basicNew usage pattern
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 <kksubbu.ml@gmail.com> 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 <btc@openinworld.com> wrote:
On Sat, May 27, 2017 at 5:41 PM, K K Subbu <kksubbu.ml@gmail.com> 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
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 <kksubbu.ml@gmail.com> wrote:
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
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 <btc@openinworld.com> wrote:
On Tue, May 30, 2017 at 2:05 PM, K K Subbu <kksubbu.ml@gmail.com> wrote:
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
Cool. Sounds like I was being over-eager then. cheers -ben
-- Guille Polito Research Engineer French National Center for Scientific Research - *http://www.cnrs.fr* <http://www.cnrs.fr> *Web:* *http://guillep.github.io* <http://guillep.github.io> *Phone: *+33 06 52 70 66 13
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>>addMessageSendDependencies: aPackage analyser := DAMessageSendAnalyzer newWith: aPackage; yourself. Example 2 -- FreeTypeFontProvider>>#updateFromFile: aFile 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 <guillermopolito@gmail.com
wrote:
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 <btc@openinworld.com> wrote:
On Tue, May 30, 2017 at 2:05 PM, K K Subbu <kksubbu.ml@gmail.com> wrote:
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
Cool. Sounds like I was being over-eager then. cheers -ben
--
Guille Polito
Research Engineer
French National Center for Scientific Research - *http://www.cnrs.fr* <http://www.cnrs.fr>
*Web:* *http://guillep.github.io* <http://guillep.github.io>
*Phone: *+33 06 52 70 66 13 <+33%206%2052%2070%2066%2013>
participants (4)
-
Ben Coman -
Guillermo Polito -
K K Subbu -
Sven Van Caekenberghe