Hi all,
In playing with Environments today, I found myself building a subclass of Environment with the following method in it: doesNotUnderstand: aMessage aMessage numArgs = 0 ifFalse: [^ super doesNotUnderstand: aMessage]. ^ self valueOf: aMessage selector ifAbsent: [ ^ super doesNotUnderstand: aMessage] Then, having constructed and set up some environment `e`, using the Browser to create classes X and Y in it, I can install it as a global: Smalltalk at: #E put: e and from then on I can say x := E X new. y := E Y new. etc. I can also do this recursively (and in fact cyclically, I think?). What's missing from this picture is tool support. In particular, Monticello support. I'd love to be able to have classes in my spliced-into-the-globals environment scanned by MC just like those in the toplevel. I've always found the MC codebase intimidating, however. Would it be reasonable to hope to be able to implement support for something like this in Monticello? Regards, Tony PS. squeak : unix :: Smalltalk globals : /, and it's just that Smalltalk globals, being a flat namespace, is equivalent to a DOS 1.0 root directory without subdirectory support. I guess I'm proposing adding subdirectories, bringing Squeak's file-system-analogue into the mid-80s DOS 2.0 era?? |
On Wed, Mar 24, 2021 at 1:14 PM Tony Garnock-Jones <[hidden email]> wrote: What's missing from this picture is tool support. In particular, MC relies on PackageInfo to gather information about which definitions are in a package. Packages can provide their own PackageInfo subclass, and override the default behavior. See e.g. http://squeaksource.com/OMeta.html - Vanessa - |
On 3/24/21 9:29 PM, Vanessa Freudenberg wrote:
> MC relies on PackageInfo to gather information about which definitions > are in a package. > > Packages can provide their own PackageInfo subclass, and override the > default behavior. Thanks, Vanessa! That's helpful. I think, to my chagrin :-) , that I'm already well outside what the core MC model can offer... but if I'm wrong about that, that would be great! Tony |
On Thu, Mar 25, 2021 at 5:59 AM Tony Garnock-Jones <[hidden email]> wrote: On 3/24/21 9:29 PM, Vanessa Freudenberg wrote: Your PI subclass just needs to answer what classes and methods are considered to be in your package. What else do you need? - Vanessa - |
On 3/25/21 6:20 PM, Vanessa Freudenberg wrote:
> Your PI subclass just needs to answer what classes and methods are > considered to be in your package. What else do you need? They need to be attached to the correct Environment on load, too. So the package needs to know something about Environments other than Environment current. |
HI
> On 25. Mar 2021, at 19:09, Tony Garnock-Jones <[hidden email]> wrote: > > On 3/25/21 6:20 PM, Vanessa Freudenberg wrote: >> Your PI subclass just needs to answer what classes and methods are considered to be in your package. What else do you need? > > They need to be attached to the correct Environment on load, too. So the package needs to know something about Environments other than Environment current. I think Jakob had a bit more tooling, no? BEst -Tobias |
In reply to this post by Tony Garnock-Jones-5
Hi, I had sprinkled menu items
around some tools (like the MCSnapshotBrowser) that were labelled something like "Load into other environment...", which would prompt you for the environment, then make it the "Environment current" during the loading. I have lost track though how many of these I have submitted to the Inbox or how many have been merged in Trunk and which were not. One of these menu items is "change environment..." on a package in the Monticello Browser. It would change the environment of an MCWorkingCopy for future snapshots and loads. Also all my modifications kept Environments out of the package definitions. In terms of Tony's experiment: you would need your special environment with doesNotUnderstand: already set up, then make it the "Environment current" while you load the package in order to get it back as Tony had intended it to be. For example, create the (empty) package in the Monticello browser, then "change environment" of it to your special environment, then load the package from a repository. If you would not do this and load as usual instead, it would load into Smalltalk globals instead, regardless of how Tony had saved it. Kind regards, Jakob Am Do., 25. März 2021 um 19:10 Uhr schrieb Tobias Pape <[hidden email]>: HI |
In reply to this post by Tony Garnock-Jones-5
Hi Tony,
thanks for playing around with Environments. :-) As Jakob described, there are tools already supporting #environment when looking up class names. Try browsing all implementors of #environment. As you mentioned, your initial example with "x := E X new" proposes a syntax that does not exist at the moment. Given that, for some reason, you want to put an environment into a global #E one would need to write: x := (E classNamed: #X) new. Of course, you could shorten this by adding #doesNotUnderstand: to Environment. In general, the class "Environment" organizes named environments already: x := ((Environment named: #MyProject) classNamed: #X) new. Provided that classes know their environment, there might be no need to write such code in methods. Just in workspaces for experimentation. Yet, environments are not organized in a hierarchy, which means that look up will not fall back: (Environment named: #Example) classNamed: #String. "nil" Anyway, I don't follow your comparison with the DOS 1.0 file system. At least that motivation does not work for me. :-) In a regular application, I would never want to explicate an environment name in my classes' methods. Instead, the correct environment should remain implicit. Maybe like a "working directory"? :-D Ha, maybe now I get your metaphor... Best, Marcel
|
Hi Marcel,
(I'll bundle your replies into one here.) On 3/26/21 11:31 AM, Marcel Taeumel wrote: > thanks for playing around with Environments. :-) It's fun! And also I need it, or at least I *think* I need it, for a compiler for a data-describing schema language. The use of prefixes is getting horribly horribly unwieldy, so short *relative* names make more sense to me than long *absolute*(ish) names. > Of course, you could [allow syntax like E A X new etc] by adding #doesNotUnderstand: to > Environment. This is exactly what the Namespace subclass of Environment does. Well, Namespace does three things that plain Environment doesn't, and arguably shouldn't, do: - #doesNotUnderstand: to act ergonomically, like Self modules - configuring self with a small but sensible set of initial imports, namely importSelf and import: Environment default - managing a "parent" relationship to another environment, and enforcing naming invariants wrt the entry for self in that parent's binding table. > environments are not organized in a hierarchy, > which means that look up will not fall back: Yes, and I think this is the correct behaviour. The existing import/export mechanism is I think better than a hierarchical lookup system. The hierarchy of namespaces comes in when you want to explicitly refer to something unusual, something not managed via the normal Environment import/export mechanism. The usual stuff, like Array, String etc., would be imported and so available directly in the local Environment as usual. > Anyway, I don't follow your comparison with the DOS 1.0 file system. Just that Smalltalk's globals are analogous to the root directory of a file system, and that like DOS 1.0 and unlike unix, it's a flat, structureless collection of names. > In a regular > application, I would never want to explicate an environment name in > my classes' methods. Me neither. The overwhelming majority of name usage is of *relative* identifiers. Absolute naming is, ultimately, impossible :-) but also not a very good idea. > Instead, the correct environment should remain > implicit. Maybe like a "working directory"? :-D Ha, maybe now I get > your metaphor... Heh, yes quite. So this is how Environments already work, ISTM: most name references are relative, to the active Environment. My proposal (? it's not really a proposal yet, more just an experiment) is to add hierarchical reference to Environments to allow for nonlocal reference when needed. As an example, my schema compiler, done with absolute names, generates monsters like this: PreservesSchemaCompoundPattern subclass: #'PreservesSchemaCompoundPattern_setof' "..." And that's just for the meta-schema! When it comes to real schemas, I often have multiple that "import" definitions from one another, leading to names like NovySyndicateSturdyCaveat_Rewrite referencing NovySyndicateActorRef etc. I'd very much like to be able to write PreservesSchema CompoundPattern setof instead. But classes aren't "higher-order" in the right way to have the obvious way of doing that work. So Environments was where I ended up looking. Perhaps I'm looking under the lamp, where the light is brightest? Is there some dark corner of the system where I should be directing my attention? I'd love to hear about it! On 3/26/21 11:42 AM, Marcel Taeumel wrote: > if I would implement a hierarchy of environments, I would not exploit > "globals" or "declarations" but add "outer" and/or "inner" as > instance variables. Then #classNamed: needs to be changed to also > look in outer environments. I prefer the way Environments work now, with explicit imports and exports to manage the local namespace, and with no particular hierarchy enforced. The Namespace idea/quasiproposal adds just one other thing: reachability of classes in other environments from some root environment using a path, for those situations where an import is inappropriate. I guess it also adds tooling support which would be, uh, *difficult* without some kind of hierarchy. Marcel, I'd love to hear your thoughts on the EnvironmentBrowser experiment in the inbox. I'll post again in a minute with a summary of where I'm up to with it. On 3/26/21 12:41 PM, Marcel Taeumel wrote: > Yes, indeed. :-) I just added ToolSet cass >> #browseEnvironment: > and Environment >> #browse to Trunk. Thank you for those! Much appreciated. > And I noticed that something > seems to be missing from empty environments since I cannot compile a > new class into it through the Browser. Yes, you have to import: Environment default to get the base declarations into scope. I think the "Smalltalk" and "Undeclared" entries are red herrings, but I haven't gotten into the details yet to understand them properly. > Maybe > Environment >> #initializeWithName: is not correct? I think it's correct. Once you add importSelf and import: Environment default to a new environment, things work fine in the Browser. Best Regards, and thanks again for the responses, Tony |
Free forum by Nabble | Edit this page |