Hi,
Following Pharo Days, I brainstormed about some possible class definition syntaxes. What I have in mind: "basic mechanics, only THIS one in the image!" ClassDefinition new superclass: Object; "optional. If not specified, Object by default ;-)" name: #A; "optional and create an anonymous class if not specified" instVars: 'a b c'; traits: {TEquality}; package: 'Plop'; createClass. " this message sent might be hidden by the browser when accepting" "---------------" "Some IDEAS (but I did not find one that I really like) of scripting/shorter syntaxes that must ALWAYS end up calling the above basic mechanics at the end:" Class fromDefinition: [ :def | def name: #sub; instVars: 'w r g'; superclass: Object ]. Object subclass "<-- returns a subclass of Object but the problem is that the new class is muted each time and the class definition is not explicit" name: #A; ivs: 'a b c'; traits: { TEquality }. { #superclass -> Object. #name -> #sub. #instVars -> 'a b c' } asClass. { Object asSuperclass. #sub asClassName. 'a b c' asInstVars. 'c' asClassVar } asClass. "litteral approach" #( name A superclass Object instVars #(a b c) instVar d ) asClass #Luc |
If we can get rid off the myriad of class creation methods count me in. :) I would do something like:ClassBuilder new name: #A; superclass: Object; addInstanceVariableNamed: 'a'; addInstanceVariableNamed: 'c'; addBooleanSlotNamed: 'z'; addClassVariableNamed: 'D'; use: SomeTrait; use: SomeOtherTrait; beWeak "if you want a weak subclass"; build With all of this optional. If we can avoid to pass nil as superclass for the cases you don't have a superclass that would be good, maybe an specific method in the builder ? On Mon, May 22, 2017 at 4:25 AM, Luc Fabresse <[hidden email]> wrote:
|
Why can't instance variables/slots not be Symbols as well ...
> On 22 May 2017, at 13:27, Gabriel Cotelli <[hidden email]> wrote: > > If we can get rid off the myriad of class creation methods count me in. :) > > I would do something like: > > ClassBuilder new > name: #A; > superclass: Object; > addInstanceVariableNamed: 'a'; > addInstanceVariableNamed: 'c'; > addBooleanSlotNamed: 'z'; > addClassVariableNamed: 'D'; > use: SomeTrait; > use: SomeOtherTrait; > beWeak "if you want a weak subclass"; > build > > With all of this optional. If we can avoid to pass nil as superclass for the cases you don't have a superclass that would be good, maybe an specific method in the builder ? > > On Mon, May 22, 2017 at 4:25 AM, Luc Fabresse <[hidden email]> wrote: > Hi, > > Following Pharo Days, I brainstormed about some possible class definition syntaxes. > What I have in mind: > > "basic mechanics, only THIS one in the image!" > ClassDefinition new > superclass: Object; "optional. If not specified, Object by default ;-)" > name: #A; "optional and create an anonymous class if not specified" > instVars: 'a b c'; > traits: {TEquality}; > package: 'Plop'; > createClass. " this message sent might be hidden by the browser when accepting" > > "---------------" > "Some IDEAS (but I did not find one that I really like) of scripting/shorter syntaxes that must ALWAYS end up calling the above basic mechanics at the end:" > > Class fromDefinition: [ :def | > def name: #sub; > instVars: 'w r g'; > superclass: Object ]. > > Object subclass "<-- returns a subclass of Object but the problem is that the new class is muted each time and the class definition is not explicit" > name: #A; > ivs: 'a b c'; > traits: { TEquality }. > > { #superclass -> Object. > #name -> #sub. > #instVars -> 'a b c' } asClass. > > { Object asSuperclass. > #sub asClassName. > 'a b c' asInstVars. > 'c' asClassVar } asClass. > > "litteral approach" > #( name A > superclass Object > instVars #(a b c) > instVar d > ) asClass > > > #Luc > |
In reply to this post by gcotelli
I'd also put in the pot a more declarative, less-smalltalkish-syntax approach: Class { name: 'A', superclass: Object, a: InstVar, b: InstVar, c: InstVar } Of course this could evolve. Some people will say that this is too verbose if you have lots of instance variables. I'd say that having too many instance variables is a code smell :) Guille On Mon, May 22, 2017 at 1:27 PM, Gabriel Cotelli <[hidden email]> wrote:
|
In reply to this post by Luc Fabresse
Hi. My idea was to ask concrete metaobject for new object definition: superclass: #Object; uses: #MyTrait; vars: { #a. #b }; classVars: { #A. #B }; package: #MyPackage; tags: #(Core); layout: #MethodDictionaryLayout. for class side: Metaclass <<< #MyClass vars: { }. Or: Class classSide <<< #MyClass for trait: Trait <<< #MyTrait uses: #AnotherTrait; package: #MyPackage; tags: #(Core Traits) for trait class side: ClassTrait <<< #MyTrait uses: #AnotherClassSideTrait 2017-05-22 9:25 GMT+02:00 Luc Fabresse <[hidden email]>:
I would not call it #createClass but something like #install. Because #createClass can be also interesting message to get new class without affecting live system. And #install should be default version of #installInto: anEnvironment. |
The build / partial object syntaxes are interesting in the way they could be integrated with RB in creating RB actions (RDAddClassChange / RBAddClassVariableChange / RBAddInstanceVariableChange) that could then be played on "build".
Gives you a nice undo/redo capability and Epicea integration to boot. Also, it could be valuable to not completely build / install the class in some cases, and manipulate the abstract structure without compiling it. Regards, Thierry 2017-05-22 13:53 GMT+02:00 Denis Kudriashov <[hidden email]>:
|
In reply to this post by Denis Kudriashov
2017-05-22 13:53 GMT+02:00 Denis Kudriashov <[hidden email]>: Class <<< #MyClass I think superclass should be defined as symbol because it can not exists. |
In reply to this post by Sven Van Caekenberghe-2
2017-05-22 13:40 GMT+02:00 Sven Van Caekenberghe <[hidden email]>: Why can't instance variables/slots not be Symbols as well ... To me current slot syntax is good enough. Anybody have objections? |
In reply to this post by Luc Fabresse
>ClassDefinition new
> superclass: Object; "optional. If not specified, Object by default ;-)" > name: #A; "optional and create an anonymous class if not specified" > instVars: 'a b c'; > traits: {TEquality}; > package: 'Plop'; > createClass. " this message sent might be hidden by the browser when accepting" I would like to suggest to consider replacing instVars: 'a b c'; with instVars: #( b a c ); That is, to replace the String with names separated by whitespace, by an array of Symbols, one name per line. This would make it possible to put comments right next to variable names like this: instVars: #( b "comment about b" a "comment about a" c "comment about c" ); Which is similar to what can be done in other object oriented languages like Java or C++. This would also make for nice diffs of changes to the class definition - when put into git - when instance variables are added, removed or renamed. instVars: #( b - a + d c ); Best Regards, Milan Vavra |
In reply to this post by Luc Fabresse
>ClassDefinition new
> superclass: Object; "optional. If not specified, Object by default ;-)" > name: #A; "optional and create an anonymous class if not specified" > instVars: 'a b c'; > traits: {TEquality}; > package: 'Plop'; > createClass. " this message sent might be hidden by the browser when accepting" I would like to suggest to consider replacing instVars: 'a b c'; with instVars: #( b a c ); That is, to replace the String with names separated by whitespace, by an array of Symbols, one name per line. This would make it possible to put comments right next to variable names like this: instVars: #( b "comment about b" a "comment about a" c "comment about c" ); Which is similar to what can be done in other object oriented languages like Java or C++. This would also make for nice diffs of changes to the class definition - when put into git - when instance variables are added, removed or renamed. instVars: #( b - a + d c ); Best Regards, Milan Vavra -- View this message in context: http://forum.world.st/Class-syntax-brainstorming-tp4947801p4947858.html Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com. |
In reply to this post by Luc Fabresse
On Mon, May 22, 2017 at 3:25 PM, Luc Fabresse <[hidden email]> wrote:
(btw, I assume you mean mutated.)
What about... Object subclass: [ :def | def name: 'MyClass' ; "optional and create an anonymous class if not specified" instanceVariables: 'a b c' ; classVariables: 'M N O'; classInstanceVariables: 'x y z' ; traits: {TEquality} ; package: 'Plop']. Object>>subclass: builderBlock ^ (builderBlock value: ClassDefinition new) createClass or similar to Guille's declarative proposal... Object subclass: { name: 'Myclass', a: InstVar, b: InstVar, c: InstVar } cheers -ben |
Honestly, I do not like that much having a more declarative (less Smalltalksish) definition. In fact, one of the things I was always proud of showing to Smalltalk newcomers, that when they created a class, all they were doing was a "DoIt" to tell the superclass to create the new subclass. And then showing how they could copy and paste that into a workspace and DoIt. Or Debug it. So..if it were for me, I would keep a Smalltalk syntax with a plain message send. Sure, a builder kind of API is better to me, like Luc proposes. Also, I do prefer too the #createAndInstall kind of message so that we can have a flavour of #createClass that only creates the class but doesn't install it into the system. Cheers, On Mon, May 22, 2017 at 10:48 AM, Ben Coman <[hidden email]> wrote:
|
In reply to this post by Luc Fabresse
I like very much the idea!
Creating a class can be done in many different ways. The Factory design pattern should be applied here I think. Something like ClassFactory Alexandre -- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;. > On May 22, 2017, at 3:25 AM, Luc Fabresse <[hidden email]> wrote: > > Hi, > > Following Pharo Days, I brainstormed about some possible class definition syntaxes. > What I have in mind: > > "basic mechanics, only THIS one in the image!" > ClassDefinition new > superclass: Object; "optional. If not specified, Object by default ;-)" > name: #A; "optional and create an anonymous class if not specified" > instVars: 'a b c'; > traits: {TEquality}; > package: 'Plop'; > createClass. " this message sent might be hidden by the browser when accepting" > > "---------------" > "Some IDEAS (but I did not find one that I really like) of scripting/shorter syntaxes that must ALWAYS end up calling the above basic mechanics at the end:" > > Class fromDefinition: [ :def | > def name: #sub; > instVars: 'w r g'; > superclass: Object ]. > > Object subclass "<-- returns a subclass of Object but the problem is that the new class is muted each time and the class definition is not explicit" > name: #A; > ivs: 'a b c'; > traits: { TEquality }. > > { #superclass -> Object. > #name -> #sub. > #instVars -> 'a b c' } asClass. > > { Object asSuperclass. > #sub asClassName. > 'a b c' asInstVars. > 'c' asClassVar } asClass. > > "litteral approach" > #( name A > superclass Object > instVars #(a b c) > instVar d > ) asClass > > > #Luc |
In reply to this post by Luc Fabresse
Nice. We will have troubles with slots because that will mix model and real instances (and slot definitions can contain any Smalltalk code) -- Pavel 2017-05-22 9:25 GMT+02:00 Luc Fabresse <[hidden email]>:
|
...do not forget on method tags -- Pavel 2017-05-22 16:44 GMT+02:00 Pavel Krivanek <[hidden email]>:
|
In reply to this post by gcotelli
Yes this is the idea. We should the combinatorial explosion :) On Mon, May 22, 2017 at 1:27 PM, Gabriel Cotelli <[hidden email]> wrote:
|
In reply to this post by Luc Fabresse
On 05/22/2017 12:25 AM, Luc Fabresse wrote:
> Hi, > > Following Pharo Days, I brainstormed about some possible class > definition syntaxes. There is a class definition syntax defined in ANSI Smalltalk. It's a syntax, purely declarative. I seem to recall seeing at least one implementation of this, though I don't know how widely it was used. Regards, -Martin |
In reply to this post by Denis Kudriashov
On Monday 22 May 2017 05:32 PM, Denis Kudriashov wrote:
> package: #MyPackage; > tags: #(Core); > layout: #MethodDictionaryLayout. How about: properties: { #package->"My Package", ... } A property dictionary would be a better option than named variables as it will not impose a burden on every class instance. It would also be easy to add new features to existing classes without breaking backward compatibility. Regards .. Subbu |
In reply to this post by Pharo Smalltalk Developers mailing list
2017-05-22 15:06 GMT+02:00 Milan Vavra via Pharo-dev <[hidden email]>:
+1 !
|
In reply to this post by Mariano Martinez Peck
2017-05-22 16:26 GMT+02:00 Mariano Martinez Peck <[hidden email]>:
good point!
|
Free forum by Nabble | Edit this page |