Hi
I would like to know if there are any reason (except in imageSegment) to assign to inject:into: parameter. we saw String asPacket asPacked ^ self inject: 0 into: [:t1 :t2 | t1 := t1 * 256 + t2 asInteger] The assignment is not needed since the semantics of into: is to do that exactly |
> asPacked
> ^ self > inject: 0 > into: [:t1 :t2 | t1 := t1 * 256 + t2 asInteger] > > The assignment is not needed since the semantics of into: is to do > that exactly Odd that the compiler allows you to do that. In VW this code raises a compiler error, as it does in Squeak when you try to store into a method argument. I hope the new compiler is a bit more consistent. Cheers, Lukas -- Lukas Renggli http://www.lukas-renggli.ch |
I think that for imageSegment this is normal since you do not want to
get reference via the block arg (that are represented as local of the method containing the block). For all the rest I would clean the code. On 28 avr. 07, at 10:37, Lukas Renggli wrote: >> asPacked >> ^ self >> inject: 0 >> into: [:t1 :t2 | t1 := t1 * 256 + t2 asInteger] >> >> The assignment is not needed since the semantics of into: is to do >> that exactly > > Odd that the compiler allows you to do that. In VW this code raises a > compiler error, as it does in Squeak when you try to store into a > method argument. I hope the new compiler is a bit more consistent. > > Cheers, > Lukas > > -- > Lukas Renggli > http://www.lukas-renggli.ch > > |
Yes and even we don't need it with the NewCompiler with closure since
the "block context" is destroy so the temp could be GCed Mth On Apr 28, 2007, at 9:55 PM, stephane ducasse wrote: > I think that for imageSegment this is normal since you do not want > to get reference |
In reply to this post by stephane ducasse
There's absolutely no way that assigning to a block arg should be
permitted. Blocks arg should be treated the same as method parameters by the compiler. tim -- tim Rowledge; [hidden email]; http://www.rowledge.org/tim Useful Latin Phrases:- Utinam barbari spatium proprium tuum invadant! = May barbarians invade your personal space! |
> There's absolutely no way that assigning to a block arg should be
> permitted. Blocks arg should be treated the same as method parameters > by the compiler. A question: Why shouldn't it be allowed to assign to method and block arguments, if the underlying implementation allows to do so? I wonder, because in other languages like JavaScript it is a very common pattern to assign to function arguments, for example to set default values if necessary. Personally I find this more clear and less error prone than to introduce new temporary variables for the arguments: start: function (element, speed, duration, after) { element = $(element); speed = speed || 0.4; duration = duration || 4.0; after = after || function () { return true; }; ... Cheers, Lukas -- Lukas Renggli http://www.lukas-renggli.ch |
I think JavaScript et al. need that because they don't have method
overloading or keyword arguments like Smalltalk does. The patten mentioned below simply isn't needed. Instead of doing the below you just do: start: function element: el speed: sp duration: dur after: af "..." start: function element: el ^ self start: function element: el speed: 0.4 duration: 0.4 after: (function) "etc." To me this is much more elegant and clean then the ugly, perl-esque: "var = var || default" stuff. >From: "Lukas Renggli" <[hidden email]> >Reply-To: The general-purpose Squeak developers >list<[hidden email]> >To: "The general-purpose Squeak developers >list"<[hidden email]> >Subject: Re: Any reason for assigning block parameter in inject:into: >Date: Sun, 29 Apr 2007 11:36:16 +0200 > >>There's absolutely no way that assigning to a block arg should be >>permitted. Blocks arg should be treated the same as method parameters >>by the compiler. > >A question: Why shouldn't it be allowed to assign to method and block >arguments, if the underlying implementation allows to do so? > >I wonder, because in other languages like JavaScript it is a very >common pattern to assign to function arguments, for example to set >default values if necessary. Personally I find this more clear and >less error prone than to introduce new temporary variables for the >arguments: > > start: function (element, speed, duration, after) { > element = $(element); > speed = speed || 0.4; > duration = duration || 4.0; > after = after || function () { return true; }; > ... > >Cheers, >Lukas > >-- >Lukas Renggli >http://www.lukas-renggli.ch > _________________________________________________________________ Mortgage rates near historic lows. Refinance $200,000 loan for as low as $771/month* https://www2.nextag.com/goto.jsp?product=100000035&url=%2fst.jsp&tm=y&search=mortgage_text_links_88_h27f8&disc=y&vers=689&s=4056&p=5117 |
Not to mention the interface is much nicer the Smalltalk way.
someObj start: [ "do stuff" ] element: someElement. vs. someObj start: [ "do stuff" ] element: someElement speed: nil duration: nil after: nil. "????" Personally I have not yet seen a case in a language like Smalltalk where wanting to assign to a passed parameter wasn't a sign that some refactoring was needed. >From: "J J" <[hidden email]> >Reply-To: The general-purpose Squeak developers >list<[hidden email]> >To: [hidden email] >Subject: Re: Any reason for assigning block parameter in inject:into: >Date: Sun, 29 Apr 2007 10:24:34 +0000 > >I think JavaScript et al. need that because they don't have method >overloading or keyword arguments like Smalltalk does. The patten mentioned >below simply isn't needed. Instead of doing the below you just do: > >start: function element: el speed: sp duration: dur after: af > "..." > >start: function element: el > ^ self start: function element: el speed: 0.4 duration: 0.4 after: >(function) > >"etc." > >To me this is much more elegant and clean then the ugly, perl-esque: "var = >var || default" stuff. > >>From: "Lukas Renggli" <[hidden email]> >>Reply-To: The general-purpose Squeak developers >>list<[hidden email]> >>To: "The general-purpose Squeak developers >>list"<[hidden email]> >>Subject: Re: Any reason for assigning block parameter in inject:into: >>Date: Sun, 29 Apr 2007 11:36:16 +0200 >> >>>There's absolutely no way that assigning to a block arg should be >>>permitted. Blocks arg should be treated the same as method parameters >>>by the compiler. >> >>A question: Why shouldn't it be allowed to assign to method and block >>arguments, if the underlying implementation allows to do so? >> >>I wonder, because in other languages like JavaScript it is a very >>common pattern to assign to function arguments, for example to set >>default values if necessary. Personally I find this more clear and >>less error prone than to introduce new temporary variables for the >>arguments: >> >> start: function (element, speed, duration, after) { >> element = $(element); >> speed = speed || 0.4; >> duration = duration || 4.0; >> after = after || function () { return true; }; >> ... >> >>Cheers, >>Lukas >> >>-- >>Lukas Renggli >>http://www.lukas-renggli.ch >> > >_________________________________________________________________ >Mortgage rates near historic lows. Refinance $200,000 loan for as low as >$771/month* >https://www2.nextag.com/goto.jsp?product=100000035&url=%2fst.jsp&tm=y&search=mortgage_text_links_88_h27f8&disc=y&vers=689&s=4056&p=5117 > > _________________________________________________________________ Get a FREE Web site, company branded e-mail and more from Microsoft Office Live! http://clk.atdmt.com/MRT/go/mcrssaub0050001411mrt/direct/01/ |
In reply to this post by J J-6
However, this pattern should be limited to very few optional args,
because N optional args make (2 raisedTo: N) different messages. That's a lot of code to maintain. Nicolas J J a écrit : > I think JavaScript et al. need that because they don't have method > overloading or keyword arguments like Smalltalk does. The patten > mentioned below simply isn't needed. Instead of doing the below you > just do: > > start: function element: el speed: sp duration: dur after: af > "..." > > start: function element: el > ^ self start: function element: el speed: 0.4 duration: 0.4 after: > (function) > > "etc." > > To me this is much more elegant and clean then the ugly, perl-esque: > "var = var || default" stuff. > >> From: "Lukas Renggli" <[hidden email]> >> Reply-To: The general-purpose Squeak developers >> list<[hidden email]> >> To: "The general-purpose Squeak developers >> list"<[hidden email]> >> Subject: Re: Any reason for assigning block parameter in inject:into: >> Date: Sun, 29 Apr 2007 11:36:16 +0200 >> >>> There's absolutely no way that assigning to a block arg should be >>> permitted. Blocks arg should be treated the same as method parameters >>> by the compiler. >> >> A question: Why shouldn't it be allowed to assign to method and block >> arguments, if the underlying implementation allows to do so? >> >> I wonder, because in other languages like JavaScript it is a very >> common pattern to assign to function arguments, for example to set >> default values if necessary. Personally I find this more clear and >> less error prone than to introduce new temporary variables for the >> arguments: >> >> start: function (element, speed, duration, after) { >> element = $(element); >> speed = speed || 0.4; >> duration = duration || 4.0; >> after = after || function () { return true; }; >> ... >> >> Cheers, >> Lukas >> >> -- >> Lukas Renggli >> http://www.lukas-renggli.ch >> > > _________________________________________________________________ > Mortgage rates near historic lows. Refinance $200,000 loan for as low as > $771/month* > https://www2.nextag.com/goto.jsp?product=100000035&url=%2fst.jsp&tm=y&search=mortgage_text_links_88_h27f8&disc=y&vers=689&s=4056&p=5117 > > > > |
>From: nicolas cellier <[hidden email]>
>Reply-To: The general-purpose Squeak developers >list<[hidden email]> >To: [hidden email] >Subject: Re: Any reason for assigning block parameter in inject:into: >Date: Sun, 29 Apr 2007 15:00:02 +0200 > >However, this pattern should be limited to very few optional args, because >N optional args make (2 raisedTo: N) different messages. >That's a lot of code to maintain. > >Nicolas You're over-stating this. It's simple. You provide the base method that takes all options and one method for each different interface to that method you provide. And this approach certainly scales better then setting the defaults by hand, although Python style defaulting would be less typing. Languages like Smalltalk can use keyword arguments for default arguments [1], languages like Python use special default argument syntax [2] and languages that were not designed as well (at least in this area) have to rely on 'var = var || default' nonsense. [1] IMO, this is the superior method for a dynamic language because the others require runtime checks to be done every time the function is entered, while this way it is only a compile time check. [2] This is certainly better then having to manually type out every default case, but (afaik) it is still a runtime check for a dynamic language. _________________________________________________________________ The average US Credit Score is 675. The cost to see yours: $0 by Experian. http://www.freecreditreport.com/pm/default.aspx?sc=660600&bcd=EMAILFOOTERAVERAGE |
2007/4/29, J J <[hidden email]>:
> >From: nicolas cellier <[hidden email]> > >Reply-To: The general-purpose Squeak developers > >list<[hidden email]> > >To: [hidden email] > >Subject: Re: Any reason for assigning block parameter in inject:into: > >Date: Sun, 29 Apr 2007 15:00:02 +0200 > > > >However, this pattern should be limited to very few optional args, because > >N optional args make (2 raisedTo: N) different messages. > >That's a lot of code to maintain. > > > >Nicolas > > You're over-stating this. It's simple. You provide the base method that > takes all options and one method for each different interface to that method > you provide. And this approach certainly scales better then setting the > defaults by hand, although Python style defaulting would be less typing. > > Languages like Smalltalk can use keyword arguments for default arguments > [1], languages like Python use special default argument syntax [2] and > languages that were not designed as well (at least in this area) have to > rely on 'var = var || default' nonsense. > > [1] IMO, this is the superior method for a dynamic language because the > others require runtime checks to be done every time the function is entered, > while this way it is only a compile time check. > > [2] This is certainly better then having to manually type out every default > case, but (afaik) it is still a runtime check for a dynamic language. Nicolas is right, this gets real messy, real fast. See Seaside: Canvas <-> HtmlBuilder Cheers Philippe > _________________________________________________________________ > The average US Credit Score is 675. The cost to see yours: $0 by Experian. > http://www.freecreditreport.com/pm/default.aspx?sc=660600&bcd=EMAILFOOTERAVERAGE > > > |
In reply to this post by J J-6
Yes i understand that, behaviour is in a single method, all others are
wrappers. But: - all others do hold a copy of the default values. - they are 2**N So imagine you want to change a default value, or you want to add another argument... Unless wrappers pass nil, and core method implements 'var = var || default' nonsense: realValue := argValue ifNil: [defaultValue]. Nicolas J J a écrit : >> From: nicolas cellier <[hidden email]> >> Reply-To: The general-purpose Squeak developers >> list<[hidden email]> >> To: [hidden email] >> Subject: Re: Any reason for assigning block parameter in inject:into: >> Date: Sun, 29 Apr 2007 15:00:02 +0200 >> >> However, this pattern should be limited to very few optional args, >> because N optional args make (2 raisedTo: N) different messages. >> That's a lot of code to maintain. >> >> Nicolas > > You're over-stating this. It's simple. You provide the base method > that takes all options and one method for each different interface to > that method you provide. And this approach certainly scales better then > setting the defaults by hand, although Python style defaulting would be > less typing. > > Languages like Smalltalk can use keyword arguments for default arguments > [1], languages like Python use special default argument syntax [2] and > languages that were not designed as well (at least in this area) have to > rely on 'var = var || default' nonsense. > > [1] IMO, this is the superior method for a dynamic language because the > others require runtime checks to be done every time the function is > entered, while this way it is only a compile time check. > > [2] This is certainly better then having to manually type out every > default case, but (afaik) it is still a runtime check for a dynamic > language. > > _________________________________________________________________ > The average US Credit Score is 675. The cost to see yours: $0 by > Experian. > http://www.freecreditreport.com/pm/default.aspx?sc=660600&bcd=EMAILFOOTERAVERAGE > > > > |
In reply to this post by Philippe Marschall
> I think JavaScript et al. need that because they don't have method
> overloading or keyword arguments like Smalltalk does. The patten > mentioned below simply isn't needed. My example was a bit JavaScript biased, but wh about something like that? aString := aString asUppercase. aNumber := aNumber asInteger. ... > > Languages like Smalltalk can use keyword arguments for default arguments > > [1], languages like Python use special default argument syntax [2] and > > languages that were not designed as well (at least in this area) have to > > rely on 'var = var || default' nonsense. In Smalltalk this literally translates to var := var ifNil: [ default ] This is rarely used in Smalltalk, however it is very similar to: var || (var = default); var ifNil: [ var := default ] > Nicolas is right, this gets real messy, real fast. See Seaside: > Canvas <-> HtmlBuilder Not just there, there are many other examples where framework designers had to rethink that approach because it stopped to scale. That's probably also a reason why there is the 'move method' refactoring. Selector prefixes for default arguments simply do not scale. Cheers, Lukas -- Lukas Renggli http://www.lukas-renggli.ch |
In reply to this post by Lukas Renggli
On 29-Apr-07, at 2:36 AM, Lukas Renggli wrote: >> There's absolutely no way that assigning to a block arg should be >> permitted. Blocks arg should be treated the same as method parameters >> by the compiler. > > A question: Why shouldn't it be allowed to assign to method and block > arguments, if the underlying implementation allows to do so? Method parameters cannot meaningfully be assigned to because you would not be assigning to what you might think you are assigning to. A method parameter is a slot in the method context, associated with a name for the programmer's convenience. It is*not* the named object that you pass with the message send. For example Foo > bar |obj1| obj1 := 'fred'. self fibble: obj1. ^obj1 Foo>fibble: myParam myParam := 'jim' Ok, so what happens? What is the result of sending #bar (this assumes that the compiler has a bug and lets you compile such code)? It had better be 'fred'! You see, in the fibble: method 'myParam' is imply a named slot where the OOP of the parameter is place during the message send. It is *not* a pointer to the variable obj1. We don't have pointers in Smaltalk; people do seem to forget that occasionally. So, in #bar the obj1 temporary variable slot is filled with the OOP for an instance of a String with the characters for 'fred', the OOP stored at obj1 is pushed onto the stack, the message #fibble: is sent and the OOP on the stack is copied to the new method context, the new method context starts executing the named slot 'myParam' gets filled with the OOP for a new String instance with the characters 'jim'. the #fibble method context returns the #bar method context returns with the OOP from the named slot 'obj1'. That returned object is 'fred'. If the compiler did allow assigning to method parameters it would do nothing but cause confusion and, quite possibly, the end of civilisation. A similar issue pertains for block arguments but we have the added complication that even after ELEVEN YEARS we still don't have proper closures in the default system and so the compiler can't really get it's act together to work out that block args (and indeed block temps) need to be treated appropriately. A long time ago when CS was trying to be an actual science instead of a label disguising half-hearted attempts to produce semi-trained code- monkeys for java sweatshops there used to be discussions about 'pass by value' and pass by reference'. There is an old paper from '85 (Smalltalk-80 Newsletter #5) by Kim McCall evaluating Smalltalk in this context. Finding a copy, reading it and understanding it is left as an exercise to the student. tim -- tim Rowledge; [hidden email]; http://www.rowledge.org/tim "Bo***x" said Pooh when Piglet kneed him in the groin. |
In reply to this post by Lukas Renggli
Lukas Renggli wrote:
>> I think JavaScript et al. need that because they don't have method >> overloading or keyword arguments like Smalltalk does. The patten >> mentioned below simply isn't needed. > > My example was a bit JavaScript biased, but wh about something like that? > > aString := aString asUppercase. > aNumber := aNumber asInteger. > ... +1 Keith |
In reply to this post by timrowledge
tim Rowledge wrote:
> > On 29-Apr-07, at 2:36 AM, Lukas Renggli wrote: > >>> There's absolutely no way that assigning to a block arg should be >>> permitted. Blocks arg should be treated the same as method parameters >>> by the compiler. >> >> A question: Why shouldn't it be allowed to assign to method and block >> arguments, if the underlying implementation allows to do so? > > Method parameters cannot meaningfully be assigned to because you would > not be assigning to what you might think you are assigning to. A > method parameter is a slot in the method context, associated with a > name for the programmer's convenience. It is*not* the named object > that you pass with the message send. > For example > Foo > bar > |obj1| > obj1 := 'fred'. > self fibble: obj1. > ^obj1 > > Foo>fibble: myParam > myParam := 'jim' > > Ok, so what happens? What is the result of sending #bar (this assumes > that the compiler has a bug and lets you compile such code)? > > It had better be 'fred'! You see, in the fibble: method 'myParam' is > imply a named slot where the OOP of the parameter is place during the > message send. It is *not* a pointer to the variable obj1. We don't > have pointers in Smaltalk; people do seem to forget that occasionally. > So, in #bar > the obj1 temporary variable slot is filled with the OOP for an > instance of a String with the characters for 'fred', > the OOP stored at obj1 is pushed onto the stack, > the message #fibble: is sent and the OOP on the stack is copied to the > new method context, > the new method context starts executing > the named slot 'myParam' gets filled with the OOP for a new String > instance with the characters 'jim'. > the #fibble method context returns > the #bar method context returns with the OOP from the named slot 'obj1'. > > That returned object is 'fred'. If the compiler did allow assigning > to method parameters it would do nothing but cause confusion and, > quite possibly, the end of civilisation. Personally I think its a great idea, and what you described is exactly what I would expect from smalltalk, knowing that it doesnt do pointers. What you are saying is that the named parameter that comes into the method which looks like a variable, and you use it like a variable is actually a constant within the context of that method. Its actually counter intuitive. Keith |
On 29-Apr-07, at 9:17 AM, Keith Hodges wrote: > > What you are saying is that the named parameter that comes into the > method which looks like a variable, and you use it like a variable > is actually a constant within the context of that method. Its > actually counter intuitive. Perhaps if you think of it along the lines of:- a) names in a method are just local tags for programmer convenience so that you don't have to keep it all in your head as you read/write code, b) objects passed into the method as parameters are bound to the parameter tags; it might help. Assigning some new object to the tag used for a parameter is confusing and pointless because it can have no effect outside the local context despite *looking like* it might replace the object to someone not familiar. To prevent that confusion, the compiler prevents the assignment. tim -- tim Rowledge; [hidden email]; http://www.rowledge.org/tim "Wibble" said Pooh the stress beginning to show. |
> Perhaps if you think of it along the lines of:-
> a) names in a method are just local tags for programmer convenience > so that you don't have to keep it all in your head as you read/write > code, > b) objects passed into the method as parameters are bound to the > parameter tags; > it might help. I don't understand what you mean. Temps and method and block arguments are all slots in some context object. It is only the compiler that tries to stop you in an inconsistent way from assigning to some of these slots. I initially asked because I find that an unnecessary restriction. Usually the philosophy of Smalltalk is to open the possibilities that the programmer has, not to arbitrarily restrict them. I don't say it is good style to assign to arguments. It might also confuse beginners, I agree. I don't even suggest to change the language. I only asked why this restriction was made in the first place. Luckily you can always use the debugger/inspector or thisContext tempAt:put: (there are a few methods that actually do that in the standard image) to change these values. Lukas -- Lukas Renggli http://www.lukas-renggli.ch |
Hi Lukas,
I perfectly understand your argument. duplicating args in temporaries is bad. But you reformulate Tim so well: It might also confuse beginners, that i cannot believe you did not understand him. He did not mean anything else. And I feel like the example given by stephane is exactly a case of such confusion. asPacked ^ self inject: 0 into: [:t1 :t2 | t1 := t1 * 256 + t2 asInteger] unless it is just an effect of Decompiler? Who would name block variables t1 and t2 but the Decompiler? However, stupid me, one thing I cannot understand is the reason to do so for ImageSegment. Any light on this? Nicolas Lukas Renggli a écrit : >> Perhaps if you think of it along the lines of:- >> a) names in a method are just local tags for programmer convenience >> so that you don't have to keep it all in your head as you read/write >> code, >> b) objects passed into the method as parameters are bound to the >> parameter tags; >> it might help. > > I don't understand what you mean. > > Temps and method and block arguments are all slots in some context > object. It is only the compiler that tries to stop you in an > inconsistent way from assigning to some of these slots. I initially > asked because I find that an unnecessary restriction. Usually the > philosophy of Smalltalk is to open the possibilities that the > programmer has, not to arbitrarily restrict them. > > I don't say it is good style to assign to arguments. It might also > confuse beginners, I agree. I don't even suggest to change the > language. I only asked why this restriction was made in the first > place. Luckily you can always use the debugger/inspector or > thisContext tempAt:put: (there are a few methods that actually do that > in the standard image) to change these values. > > Lukas > |
In reply to this post by timrowledge
On Apr 29, 2007, at 10:03 AM, tim Rowledge wrote: > Assigning some new object to the tag used for a parameter is > confusing and pointless because it can have no effect outside the > local context despite *looking like* it might replace the object to > someone not familiar. To prevent that confusion, the compiler > prevents the assignment. Interesting. As far as I can tell, you're the only poster in this thread that thinks assigning to a parameter name implies that the parameter was passed by reference. Lukas was just complaining that parameter slots are read-only, and giving examples of cases where it would be nice to be able to write to them. I occasionally feel this way too - making parameters different from other temps feels arbitrarily inconsistent. I wonder if this is a sign of changing times. After all, "confusion" is a mismatch between expectations and reality. Perhaps were seeing a change in expectations? Back in the days of yore, people were coming to Smalltalk from low-level languages where it was possible to pass pointers around, and returning a value through a pass-by-reference parameter was a common idiom. These days, people who are interested in Smalltalk are probably coming from other dynamic languages where that's not possible, and treating parameters as just another temp feels natural. Personally, I think it would be nice to be able to write to parameter slots, but it's not worth breaking compatibility with other Smalltalks. Colin |
Free forum by Nabble | Edit this page |