The Inbox: Environments-tonyg.78.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

The Inbox: Environments-tonyg.78.mcz

commits-2
Tony Garnock-Jones uploaded a new version of Environments to project The Inbox:
http://source.squeak.org/inbox/Environments-tonyg.78.mcz

==================== Summary ====================

Name: Environments-tonyg.78
Author: tonyg
Time: 25 March 2021, 1:41:26.338334 pm
UUID: 1f57f26d-c9da-4c95-adb3-3fd76774a64d
Ancestors: Environments-dtl.77

EXPERIMENTAL. Nested `Namespace`s, by introducing subclass Namespace of Environment, and placing Namespace instances as "globals" in their parent environment. See also Tools-tonyg.1033, which includes an experimental EnvironmentBrowser class.

=============== Diff against Environments-dtl.77 ===============

Item was changed:
+ SystemOrganization addCategory: #'Environments-Help'!
  SystemOrganization addCategory: #'Environments-Core'!
  SystemOrganization addCategory: #'Environments-Loading'!
- SystemOrganization addCategory: #'Environments-Policies'!
- SystemOrganization addCategory: #'Environments-Help'!
  SystemOrganization addCategory: #'Environments-Notifications'!
+ SystemOrganization addCategory: #'Environments-Policies'!
+ SystemOrganization addCategory: #'Environments-Namespaces'!

Item was added:
+ ----- Method: Environment class>>wellKnownInstances (in category 'as yet unclassified') -----
+ wellKnownInstances
+ ^ Instances values sorted: [:a :b |
+ (a info name = #Smalltalk)
+ ifTrue: [true] ifFalse: [
+ (b info name = #Smalltalk)
+ ifTrue: [false] ifFalse: [
+ a info name <= b info name]]]!

Item was added:
+ ----- Method: Environment>>isNamespace (in category 'testing') -----
+ isNamespace
+ ^ false!

Item was added:
+ ----- Method: Environment>>namespacePath (in category 'accessing') -----
+ namespacePath
+ ^ Array with: self!

Item was added:
+ ----- Method: Environment>>namespaceTreeDo: (in category 'accessing') -----
+ namespaceTreeDo: aBlock
+ aBlock value: self.
+ self namespaces do: [:ns | ns namespaceTreeDo: aBlock].!

Item was added:
+ ----- Method: Environment>>namespaces (in category 'accessing') -----
+ namespaces
+ "Answer all Environments declared here whose parent is this Environment"
+ | nss |
+ nss := self select: [:item |
+ (item value isKindOf: Environment) and: [item value parent == self]].
+ nss := nss asArray collect: [:item | item value].
+ nss sort: [:a :b | (a name compare: b name) <= 2].
+ ^ nss!

Item was added:
+ ----- Method: Environment>>parent (in category 'accessing') -----
+ parent
+ ^ nil!

Item was added:
+ ----- Method: Environment>>rename: (in category 'accessing') -----
+ rename: newName
+ | wellKnown |
+ newName = info name ifTrue: [^ self].
+ (wellKnown := Instances includes: self) ifTrue: [
+ (Instances anySatisfy: [:e | newName = e info name])
+ ifTrue: [self error: 'Name collision: well-known Environment with name ', newName, ' already exists']].
+ wellKnown ifTrue: [Instances removeKey: info name].
+ info rename: newName.
+ wellKnown ifTrue: [Instances at: newName put: self].!

Item was added:
+ ----- Method: EnvironmentInfo>>rename: (in category 'private') -----
+ rename: newName
+ name := newName!

Item was added:
+ Environment subclass: #Namespace
+ instanceVariableNames: 'parent'
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'Environments-Namespaces'!

Item was added:
+ ----- Method: Namespace>>checkName:in: (in category 'namespace hierarchy') -----
+ checkName: name in: parent
+ (parent notNil and: [(parent at: name ifAbsent: [self]) ~~ self])
+ ifTrue: [self error: 'Name collision: proposed name ', name, ' in ', parent name, ' for namespace ', self name, ' is already taken'].!

Item was added:
+ ----- Method: Namespace>>doesNotUnderstand: (in category 'dynamic lookup') -----
+ doesNotUnderstand: aMessage
+ aMessage numArgs = 0 ifFalse: [^ super doesNotUnderstand: aMessage].
+ ^ self valueOf: aMessage selector ifAbsent: [^ super doesNotUnderstand: aMessage]!

Item was added:
+ ----- Method: Namespace>>initialize (in category 'initialize-release') -----
+ initialize
+ super initialize.
+ self importSelf.
+ self import: Environment default.!

Item was added:
+ ----- Method: Namespace>>isNamespace (in category 'as yet unclassified') -----
+ isNamespace
+ ^ true!

Item was added:
+ ----- Method: Namespace>>namespacePath (in category 'namespace hierarchy') -----
+ namespacePath
+ | e |
+ e := self.
+ ^ (Array streamContents: [:w |
+ [e notNil and: [e isNamespace]] whileTrue: [
+ w nextPut: e.
+ e := e parent]]) reverseInPlace!

Item was added:
+ ----- Method: Namespace>>parent (in category 'accessing') -----
+ parent
+ ^ parent!

Item was added:
+ ----- Method: Namespace>>parent: (in category 'accessing') -----
+ parent: anEnvironment
+ | n |
+ parent == anEnvironment ifTrue: [^self].
+ n := info name asSymbol.
+ self checkName: n in: anEnvironment.
+ parent ifNotNil: [parent removeKey: n].
+ parent := anEnvironment.
+ parent ifNotNil: [parent at: n put: self].!

Item was added:
+ ----- Method: Namespace>>printOn: (in category 'printing') -----
+ printOn: aStream
+ self namespacePath do: [:n | aStream nextPutAll: n info name] separatedBy: [aStream space]!

Item was added:
+ ----- Method: Namespace>>rename: (in category 'accessing') -----
+ rename: newName
+ | p |
+ p := parent.
+ self checkName: newName in: p.
+ self parent: nil.
+ super rename: newName.
+ self parent: p.!

Item was added:
+ ----- Method: Namespace>>respondsTo: (in category 'dynamic lookup') -----
+ respondsTo: aSymbol
+ ^ (super respondsTo: aSymbol) or: [self includesKey: aSymbol]!


Reply | Threaded
Open this post in threaded view
|

EnvironmentBrowser and nested Namespaces (was Re: The Inbox: Environments-tonyg.78.mcz)

Tony Garnock-Jones-5
Hi all,

This message is about the in-inbox EXPERIMENTAL DRAFT packages

  - http://source.squeak.org/inbox/Environments-tonyg.78.mcz and
  - http://source.squeak.org/inbox/Tools-tonyg.1033.mcz

The two packages go together. Screenshot of EnvironmentBrowser in action
attached.

The idea here is a kind of Self-like "namespacing" facility, based
around placing Environment instances into another Environment's globals
table. The EnvironmentBrowser class in Tools 1033 is a sketch of UI for
the core functionality I've identified so far.

If I have the following setup of nested Environments...

   Smalltalk   -- the normal Environment default / Environment current
     - A
       - B
       - C
     - D

with class X in A, class Y in B, a *different* class Y in C, and class Z
in D, then

  - In a workspace whose environment is Smalltalk,
     `A` evaluates to the environment A.
     `A B` evaluates to the environment B.
     `A B Y` evaluates to B's Y.
     `A C Y` evaluates to C's Y.
     etc.

  - In a workspace whose environment is A,
     all of the examples from the Smalltalk paragraph above are unchanged
     `B` evaluates to the environment B,
     `B Y` yields B's Y
     `C Y` yields C's Y
     `D` is an undefined name

  - In a workspace whose environment is B,
     all of the examples from the Smalltalk paragraph above are unchanged
     `Y` is B's Y
     `C` and `D` are undefined names

The ability of Environments to import/export is unused (!) at present,
other than Namespace instances default to importing self and Smalltalk.

I'm looking at Monticello now. The major difficulty is that it hardcodes
`Environment current` and expects a single environment to apply.

I imagine the following:

  - the nested namespaces are analogous to nested folders in a Unix file
    system

  - packages are like Debian packages, and may have entries in multiple
    namespaces

  - `Environment current` at load time acts like a chroot

Given those guesses/assumptions, MC might need to learn about the idea
of classes living in a particular (or more than one!) Environment, and
the necessity of creating Namespaces as needed.

Here's an interesting method on PackageInfo I've been messing around with:

   classesAndEnvironments
     | cs |
     cs := IdentityDictionary new.
     self systemCategories do: [:cat |
       Environment current namespaceTreeDo: [:environment |
        (environment organization listAtCategoryNamed: cat)
          do: [:className | | envs |
            envs := cs at: (environment valueOf: className)
              ifAbsentPut: [Set new].
            envs add: environment]]].
     ^ cs

Does anyone have thoughts on this whole approach? On how MC's model
could profitably be altered to include a notion of namespace/environment?

Regards,
   Tony



Environment Browser on E F: NamespacedExampleClass.png (53K) Download Attachment
Workspace on environment E F.png (14K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: EnvironmentBrowser and nested Namespaces (was Re: The Inbox: Environments-tonyg.78.mcz)

marcel.taeumel
Hi Tony,

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 think that environments are already "namespaces". Thus, I would not add an extra subclass "Namespace" for it. 

The second proposal in here is that new syntax via #doesNotUnderstand:. Hmm... I do not like it. :-) Maybe a Environment class >> #fromPath: would work. Then tools can support such a path syntax. In source code I would rather not use it to not create any more "spaghetti code" than we already have. Feels like a "pandoras box" to allow an easy way for arbitrary environments in any piece of code.

Best,
Marcel

Am 25.03.2021 13:58:51 schrieb Tony Garnock-Jones <[hidden email]>:

Hi all,

This message is about the in-inbox EXPERIMENTAL DRAFT packages

- http://source.squeak.org/inbox/Environments-tonyg.78.mcz and
- http://source.squeak.org/inbox/Tools-tonyg.1033.mcz

The two packages go together. Screenshot of EnvironmentBrowser in action
attached.

The idea here is a kind of Self-like "namespacing" facility, based
around placing Environment instances into another Environment's globals
table. The EnvironmentBrowser class in Tools 1033 is a sketch of UI for
the core functionality I've identified so far.

If I have the following setup of nested Environments...

Smalltalk -- the normal Environment default / Environment current
- A
- B
- C
- D

with class X in A, class Y in B, a *different* class Y in C, and class Z
in D, then

- In a workspace whose environment is Smalltalk,
`A` evaluates to the environment A.
`A B` evaluates to the environment B.
`A B Y` evaluates to B's Y.
`A C Y` evaluates to C's Y.
etc.

- In a workspace whose environment is A,
all of the examples from the Smalltalk paragraph above are unchanged
`B` evaluates to the environment B,
`B Y` yields B's Y
`C Y` yields C's Y
`D` is an undefined name

- In a workspace whose environment is B,
all of the examples from the Smalltalk paragraph above are unchanged
`Y` is B's Y
`C` and `D` are undefined names

The ability of Environments to import/export is unused (!) at present,
other than Namespace instances default to importing self and Smalltalk.

I'm looking at Monticello now. The major difficulty is that it hardcodes
`Environment current` and expects a single environment to apply.

I imagine the following:

- the nested namespaces are analogous to nested folders in a Unix file
system

- packages are like Debian packages, and may have entries in multiple
namespaces

- `Environment current` at load time acts like a chroot

Given those guesses/assumptions, MC might need to learn about the idea
of classes living in a particular (or more than one!) Environment, and
the necessity of creating Namespaces as needed.

Here's an interesting method on PackageInfo I've been messing around with:

classesAndEnvironments
| cs |
cs := IdentityDictionary new.
self systemCategories do: [:cat |
Environment current namespaceTreeDo: [:environment |
(environment organization listAtCategoryNamed: cat)
do: [:className | | envs |
envs := cs at: (environment valueOf: className)
ifAbsentPut: [Set new].
envs add: environment]]].
^ cs

Does anyone have thoughts on this whole approach? On how MC's model
could profitably be altered to include a notion of namespace/environment?

Regards,
Tony



Reply | Threaded
Open this post in threaded view
|

Re: EnvironmentBrowser and nested Namespaces (was Re: The Inbox: Environments-tonyg.78.mcz)

Christoph Thiede

-1 on the #doesNotUnderstand: proposal. JsonObject is already questionable depending on the use case - IMHO message forwarding is easy to abuse, and using it for any kind of lookup appears kind of abusive to me. However, only my 2 cents. :-)


A big +1 for the rest of the proposed changes! :-)


Best,

Christoph


Von: Squeak-dev <[hidden email]> im Auftrag von Taeumel, Marcel
Gesendet: Freitag, 26. März 2021 11:42:24
An: squeak-dev
Betreff: Re: [squeak-dev] EnvironmentBrowser and nested Namespaces (was Re: The Inbox: Environments-tonyg.78.mcz)
 
Hi Tony,

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 think that environments are already "namespaces". Thus, I would not add an extra subclass "Namespace" for it. 

The second proposal in here is that new syntax via #doesNotUnderstand:. Hmm... I do not like it. :-) Maybe a Environment class >> #fromPath: would work. Then tools can support such a path syntax. In source code I would rather not use it to not create any more "spaghetti code" than we already have. Feels like a "pandoras box" to allow an easy way for arbitrary environments in any piece of code.

Best,
Marcel

Am 25.03.2021 13:58:51 schrieb Tony Garnock-Jones <[hidden email]>:

Hi all,

This message is about the in-inbox EXPERIMENTAL DRAFT packages

- http://source.squeak.org/inbox/Environments-tonyg.78.mcz and
- http://source.squeak.org/inbox/Tools-tonyg.1033.mcz

The two packages go together. Screenshot of EnvironmentBrowser in action
attached.

The idea here is a kind of Self-like "namespacing" facility, based
around placing Environment instances into another Environment's globals
table. The EnvironmentBrowser class in Tools 1033 is a sketch of UI for
the core functionality I've identified so far.

If I have the following setup of nested Environments...

Smalltalk -- the normal Environment default / Environment current
- A
- B
- C
- D

with class X in A, class Y in B, a *different* class Y in C, and class Z
in D, then

- In a workspace whose environment is Smalltalk,
`A` evaluates to the environment A.
`A B` evaluates to the environment B.
`A B Y` evaluates to B's Y.
`A C Y` evaluates to C's Y.
etc.

- In a workspace whose environment is A,
all of the examples from the Smalltalk paragraph above are unchanged
`B` evaluates to the environment B,
`B Y` yields B's Y
`C Y` yields C's Y
`D` is an undefined name

- In a workspace whose environment is B,
all of the examples from the Smalltalk paragraph above are unchanged
`Y` is B's Y
`C` and `D` are undefined names

The ability of Environments to import/export is unused (!) at present,
other than Namespace instances default to importing self and Smalltalk.

I'm looking at Monticello now. The major difficulty is that it hardcodes
`Environment current` and expects a single environment to apply.

I imagine the following:

- the nested namespaces are analogous to nested folders in a Unix file
system

- packages are like Debian packages, and may have entries in multiple
namespaces

- `Environment current` at load time acts like a chroot

Given those guesses/assumptions, MC might need to learn about the idea
of classes living in a particular (or more than one!) Environment, and
the necessity of creating Namespaces as needed.

Here's an interesting method on PackageInfo I've been messing around with:

classesAndEnvironments
| cs |
cs := IdentityDictionary new.
self systemCategories do: [:cat |
Environment current namespaceTreeDo: [:environment |
(environment organization listAtCategoryNamed: cat)
do: [:className | | envs |
envs := cs at: (environment valueOf: className)
ifAbsentPut: [Set new].
envs add: environment]]].
^ cs

Does anyone have thoughts on this whole approach? On how MC's model
could profitably be altered to include a notion of namespace/environment?

Regards,
Tony



Carpe Squeak!