On 17 September 2012 12:06, Henrik Sperre Johansen <[email protected]> wrote: > On 17.09.2012 11:48, Igor Stasenko wrote: >> >> On 17 September 2012 11:19, Henrik Sperre Johansen >> <[email protected]> wrote: >>> >>> On 16.09.2012 20:42, Stéphane Ducasse wrote: >>>> >>>> On Sep 16, 2012, at 7:17 PM, Igor Stasenko wrote: >>>> >>>>> So, i'd like to hear your input, which one you like, and which ones >>>>> you prefer to have >>>>> >>>>> 1. requires creating a subclass of NBFFICallback, overriding it's >>>>> fnSpec method. Takes a block closure as a callback. >>>>> 2. first you must create a factory object by specifying a callback >>>>> signature, then you can instantiate new callbacks by passing a block >>>>> closure to that factory >>>>> 3. to create a callback you must specify it's signature in one of the >>>>> compiled methods, and specify an object which will receive a message >>>>> when callback will be called. >>>> >>>> for what it is worth I like the 3rd form. Now I'm not sure on: is the >>>> right selector. >>>> >>> +1, out of those listed #3 seems the most convenient to use. >>> >>> Being able to do something like: >>> Integer >> #+ >>> <types: #( int (int aNumber) )> >>> >>> Then specify the callback parameter as >>> self callback: 3 with: #+ >>> >>> would be really neat. >>> >>> As an added bonus, it also highlights the problems this approach would >>> have >>> with simply annotating normal methods which utilize multiple >>> return/parameter types :) >>> >> not sure i understood your sentence about problems. >> > Integer + can return LargePositiveIntegers as well as SmallIntegers. > Argument type can be anything from float, to Fraction, to.. well, any kind > of number. > > So annotating such methods with a single <types> annotation (which is to > serve all uses of it as a callback), rather than defining signature on a > per-use basis can be somewhat limiting and end up working against the > inherent polymorphism you (at least when it comes to numerics) see in usual > smalltalk code. > > When it comes to return values that's mostly fine, you simply raise an error > if unable to convert to the specified type from what the smalltalk method > actually returns. > > But for parameters, you'd have to define separate methods per signature, say > addFloat: <types: #( int (float aNumber) )> > addUnsignedInt: <types: #( int (uint aNumber) )> > > when #+ actually handles those cases correctly. > > Maybe a way to "override" the default parameter signatures when specifying > the callback would be nice? > self callback: 3 with: #+ parameterTypes: {aNumber -> float} > > Leaves the usefulness of a default signature for a method, but enables you > to change it on a per-use basis, rather than pollute the base-image with > extra methods covering parametric variances. >
Ah, yeah.. i get it. Thought the same way but asked for clarification. This is not a big deal actually, since i will introduce a 'OO-callback' which performs a message send to an object using certain selector, it will be possible, of course, to pass the signature using other way, i.e. as an extra argument: callback := 3 createCallbackFor: #+ signature: #( int (int arg) ) as well as: callback := 3 createCallbackFor: #+ the only difference between those two that upon creating a callback, in first you put signature explicitly, while in another one, NB will do a method lookup and then extract the signature from that method (or raise an error, if signature cannot be found). > Cheers, > Henry -- Best regards, Igor Stasenko.
