A question arose in Discord regarding #basicNew, to which I felt like the proper answer should be
that #basicNew is used only** from the class-side when making custom initializers. (**excepting special meta-handling like by Behaviour) This philosophy is somewhat supported by... (#basicNew senders select: [:sender | sender methodClass isMeta]) count ==> 264 but there are also counter examples... (#basicNew senders select: [:sender | sender methodClass isMeta] not) count ==> 76. like these... Example1 -- DAPackageRelationGraph>>addMessageSendDependencies: aPackage analyser := DAMessageSendAnalyzer basicNew initializeWith: aPackage; yourself. Example 2 -- FreeTypeFontProvider>>#updateFromFile: aFile face := FreeTypeFace basicNew fileContentsExternalMemory: externalMem . Example 3 -- HandMorph>>#moveToEvent: anEvent self handleEvent: (MouseMoveEvent basicNew setType: #mouseMove startPoint: self position endPoint: anEvent position trail: (Array with: self position with: anEvent position) buttons: anEvent buttons hand: self stamp: anEvent timeStamp) Should we be pushing these sort of basicNew + instance-side-method-call to the class side? Or do I have the wrong end of the stick? cheers -ben |
On Saturday 27 May 2017 01:41 PM, Ben Coman wrote:
> A question arose in Discord regarding #basicNew, to which I felt like > the proper answer should be > that #basicNew is used only** from the class-side when making custom > initializers. > (**excepting special meta-handling like by Behaviour) AFAIK, #basicNew is a low-level essential method which should *never* be overridden by application methods, while #new offers a stable facade over #basicNew for applications. Essentially, #basic* methods are calls to primitives in VM which reify basic objects of the object model like float, symbols etc. They are coupled closely with interpreter and object memory structures and functions. Application classes do not concern themselves with size and layout of such objects and use the facade methods like #new. It is like the difference between a system call and runtime C library function. A C function like malloc maintains a stable interface to the app while its makes different system calls on different OS implementations. HTH .. Subbu |
On Sat, May 27, 2017 at 5:41 PM, K K Subbu <[hidden email]> wrote:
> On Saturday 27 May 2017 01:41 PM, Ben Coman wrote: >> >> A question arose in Discord regarding #basicNew, to which I felt like >> the proper answer should be >> that #basicNew is used only** from the class-side when making custom >> initializers. >> (**excepting special meta-handling like by Behaviour) > > > AFAIK, #basicNew is a low-level essential method which should *never* be > overridden by application methods, while #new offers a stable facade over > #basicNew for applications. > > Essentially, #basic* methods are calls to primitives in VM which reify basic > objects of the object model like float, symbols etc. They are coupled > closely with interpreter and object memory structures and functions. > Application classes do not concern themselves with size and layout of such > objects and use the facade methods like #new. > > It is like the difference between a system call and runtime C library > function. A C function like malloc maintains a stable interface to the app > while its makes different system calls on different OS implementations. > > HTH .. Subbu > Thanks Subbu. That is a useful insight for me, but is about the implementation. My query was more about senders of basicNew, so is still open if you have an opinion there, or anyone else. cheers -ben |
> On 28 May 2017, at 10:39, Ben Coman <[hidden email]> wrote: > > On Sat, May 27, 2017 at 5:41 PM, K K Subbu <[hidden email]> wrote: >> On Saturday 27 May 2017 01:41 PM, Ben Coman wrote: >>> >>> A question arose in Discord regarding #basicNew, to which I felt like >>> the proper answer should be >>> that #basicNew is used only** from the class-side when making custom >>> initializers. >>> (**excepting special meta-handling like by Behaviour) >> >> >> AFAIK, #basicNew is a low-level essential method which should *never* be >> overridden by application methods, while #new offers a stable facade over >> #basicNew for applications. >> >> Essentially, #basic* methods are calls to primitives in VM which reify basic >> objects of the object model like float, symbols etc. They are coupled >> closely with interpreter and object memory structures and functions. >> Application classes do not concern themselves with size and layout of such >> objects and use the facade methods like #new. >> >> It is like the difference between a system call and runtime C library >> function. A C function like malloc maintains a stable interface to the app >> while its makes different system calls on different OS implementations. >> >> HTH .. Subbu >> > > Thanks Subbu. That is a useful insight for me, but is about the > implementation. > My query was more about senders of basicNew, so is still open if you > have an opinion there, or anyone else. > cheers -ben Normally #basicNew is an implementation detail. It is however often used to prevent #initialize from happening (#new being #basicNew followed by #initialize). If that is the case, then it is probably a design error. Sven |
In reply to this post by Ben Coman
On Sunday 28 May 2017 02:09 PM, Ben Coman wrote:
> Thanks Subbu. That is a useful insight for me, but is about the > implementation. > My query was more about senders of basicNew, so is still open if you > have an opinion there, or anyone else. It is just a private primitive for creating new instances. I don't think there is any restriction in the language that it should only be sent only from class-side methods. Only methods which are part of language implementation will send this selector and it so happens that most callers fall on the class side. You will also find instance side methods (operators) in non-trivial basic types like Colors or DateAndTime sending #basicNew. Regards .. Subbu |
On Tue, May 30, 2017 at 2:05 PM, K K Subbu <[hidden email]> wrote: On Sunday 28 May 2017 02:09 PM, Ben Coman wrote: Cool. Sounds like I was being over-eager then. cheers -ben |
Hi Ben, Just to complete Sven's answer: #new will send #initialize to the new instance. Some frameworks may not want that to avoid extra initializations or side-effects. Think for example about any kind of serializer like Fuel or Glorp: the object they serialize/deserialize already have state, there is no need to execute the #initialize method on them. Now, checking the cases you show in the first email: - Case 1: could probably call #new - Case 2: I don't know without checking the code :) - Case 3: could probably call #new I think Cases 1 and 3 are just optimizations. They avoid #new to avoid the extra (empty) call to #initialize. Sista should fix this by smartly inlining the #initialize methods thus avoiding extra overhead for these cases... That said, I'd say that - people should not use #basicNew, unless they know what they are doing and why. - corollary: if you do not know what to use, use #new That will avoid headaches like "My object is not initialized ñaañaña" :) Guille On Tue, May 30, 2017 at 8:16 AM, Ben Coman <[hidden email]> wrote:
|
Thanks for the additional perspective Guille.
Now reading back I see that I was not explicit. I was proposing the following changes might be preferred... Example1 -- DAPackageRelationGraph>> analyser := DAMessageSendAnalyzer newWith: aPackage; yourself. Example 2 -- FreeTypeFontProvider>># face := FreeTypeFace newWithFileContentsExternalMemory: externalMem . since I'm guessing the above aren't performance sensitive. Example 3, same idea, but maybe its performance critical, but as you say, sista should fix that. cheers -ben On Tue, May 30, 2017 at 2:40 PM, Guillermo Polito <[hidden email]> wrote:
|
Free forum by Nabble | Edit this page |