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
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
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; tim@rowledge.org; 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
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" renggli@gmail.com Reply-To: The general-purpose Squeak developers listsqueak-dev@lists.squeakfoundation.org To: "The general-purpose Squeak developers list"squeak-dev@lists.squeakfoundation.org 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=...
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" azreal1977@hotmail.com Reply-To: The general-purpose Squeak developers listsqueak-dev@lists.squeakfoundation.org To: squeak-dev@lists.squeakfoundation.org 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" renggli@gmail.com Reply-To: The general-purpose Squeak developers listsqueak-dev@lists.squeakfoundation.org To: "The general-purpose Squeak developers list"squeak-dev@lists.squeakfoundation.org 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=...
_________________________________________________________________ Get a FREE Web site, company branded e-mail and more from Microsoft Office Live! http://clk.atdmt.com/MRT/go/mcrssaub0050001411mrt/direct/01/
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" renggli@gmail.com Reply-To: The general-purpose Squeak developers listsqueak-dev@lists.squeakfoundation.org To: "The general-purpose Squeak developers list"squeak-dev@lists.squeakfoundation.org 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=...
From: nicolas cellier ncellier@ifrance.com Reply-To: The general-purpose Squeak developers listsqueak-dev@lists.squeakfoundation.org To: squeak-dev@lists.squeakfoundation.org 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=EMAILFOOTE...
2007/4/29, J J azreal1977@hotmail.com:
From: nicolas cellier ncellier@ifrance.com Reply-To: The general-purpose Squeak developers listsqueak-dev@lists.squeakfoundation.org To: squeak-dev@lists.squeakfoundation.org 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=EMAILFOOTE...
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 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
From: "Lukas Renggli" renggli@gmail.com Reply-To: The general-purpose Squeak developers listsqueak-dev@lists.squeakfoundation.org To: "The general-purpose Squeak developers list"squeak-dev@lists.squeakfoundation.org Subject: Re: default args (was Re: Any reason for assigning block parameterin inject:into:) Date: Sun, 29 Apr 2007 17:39:54 +0200
My example was a bit JavaScript biased, but wh about something like that?
aString := aString asUppercase. aNumber := aNumber asInteger. ...
Yea, ok, that does make more sense. I guess I just get nervous when someone appears to me to suggest that we need something that other languages have to have due to design issues.
Not that I have anything against JavaScript, I hear it is quite flexible in many areas. It just sounds like default argument situations is not one of those areas.
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 ]
I usually see (and use) this for doing lazy initialization of ivars, I haven't seen it for defaulting method arguments.
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.
Selector prefixes? You mean the technique of providing shorter methods which call the main method with default arguments? It is just a pattern, no pattern makes sense in every possible situation. A few default-able arguments is very manageable. More then that and one would probably want some other pattern, not default arguments at all.
_________________________________________________________________ MSN is giving away a trip to Vegas to see Elton John. Enter to win today. http://msnconcertcontest.com?icid-nceltontagline
From: "Philippe Marschall" philippe.marschall@gmail.com Reply-To: The general-purpose Squeak developers listsqueak-dev@lists.squeakfoundation.org To: "The general-purpose Squeak developers list"squeak-dev@lists.squeakfoundation.org Subject: Re: default args (was Re: Any reason for assigning block parameterin inject:into:) Date: Sun, 29 Apr 2007 15:14:24 +0000
Nicolas is right, this gets real messy, real fast. See Seaside: Canvas <-> HtmlBuilder
Cheers Philippe
Well it is certainly true that the default argument pattern doesn't fit everything. Doesn't canvas use a pattern of having an object with default ivars that one can modify with mutator functions (i.e. a totally different pattern then what was mentioned before)?
_________________________________________________________________ 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=...
2007/4/30, J J azreal1977@hotmail.com:
From: "Philippe Marschall" philippe.marschall@gmail.com Reply-To: The general-purpose Squeak developers listsqueak-dev@lists.squeakfoundation.org To: "The general-purpose Squeak developers list"squeak-dev@lists.squeakfoundation.org Subject: Re: default args (was Re: Any reason for assigning block parameterin inject:into:) Date: Sun, 29 Apr 2007 15:14:24 +0000
Nicolas is right, this gets real messy, real fast. See Seaside: Canvas <-> HtmlBuilder
Cheers Philippe
Well it is certainly true that the default argument pattern doesn't fit everything. Doesn't canvas use a pattern of having an object with default ivars that one can modify with mutator functions (i.e. a totally different pattern then what was mentioned before)?
Yeah, more or less. It does the traditional Smalltalk thingie: makes an object of if.
Cheers Philippe
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=...
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 ncellier@ifrance.com Reply-To: The general-purpose Squeak developers listsqueak-dev@lists.squeakfoundation.org To: squeak-dev@lists.squeakfoundation.org 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=EMAILFOOTE...
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; tim@rowledge.org; http://www.rowledge.org/tim "Bo***x" said Pooh when Piglet kneed him in the groin.
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.
I am not confused, and that is saying something!
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; tim@rowledge.org; 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
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
Well in 3.8 that method reads like this:
String>>asPacked "Convert to a longinteger that describes the string"
^ self inject: 0 into: [ :pack :next | pack := pack * 256 + next asInteger ].
And the assignment is meaningless, perhaps the author did not fully understand #inject:into:. It should certainly be removed.
- Bert -
On Apr 29, 2007, at 14:38 , nicolas cellier wrote:
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
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
On Apr 29, 2007, at 16:09 , Colin Putney wrote:
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.
+1
I wouldn't expect assigning to a variable to affect the sending method. I think of method arguments as temps. Which they are, in Squeak at least. I actually don't see a compelling reason to disallow assigning to method args, except for stylistic ones.
I'd argue similarly for block parameters, but the current compiler does not do the Right Thing when assigning to them in some situations. It's unacceptable to get different results for these two expressions:
Array streamContents: [:s | (1 to: 5) do: [:i | s nextPut: (i := i + 1)]]
Array streamContents: [:s | 1 to: 5 do: [:i | s nextPut: (i := i + 1)]]
The optimization of #to:do: expects the block parameter to not be assigned to.
- Bert -
The difference is that both you, Bert, and Colin are quite versed in Smalltalk. Anyone looking at Smalltalk as if it were C or some other dismal bit-mangling nonsense might very well be seeing the method parameter(s) as pointers.
Whatever we think about reasons, the definition is that method parameters and and block args are not supposed to be assigned to; we should make sure the compiler enforces that properly.
tim -- tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim I asked Mom if I was a gifted child ... she said they certainly wouldn't have paid for me.
tim Rowledge writes:
The difference is that both you, Bert, and Colin are quite versed in Smalltalk. Anyone looking at Smalltalk as if it were C or some other dismal bit-mangling nonsense might very well be seeing the method parameter(s) as pointers.
C copies the arguments and allows you to change them. Just like Smalltalk would if we allowed arguments to be changed. I think Pascal didn't allow arguments to be changed. Personally I'm happy with the status quo, but could live with mutable arguments too.
Bryce
bryce@kampjes.demon.co.uk wrote:
tim Rowledge writes:
The difference is that both you, Bert, and Colin are quite versed in Smalltalk. Anyone looking at Smalltalk as if it were C or some other dismal bit-mangling nonsense might very well be seeing the method parameter(s) as pointers.
C copies the arguments and allows you to change them. Just like Smalltalk would if we allowed arguments to be changed. I think Pascal didn't allow arguments to be changed. Personally I'm happy with the status quo, but could live with mutable arguments too.
Bryce
Dont forget this is squeak, where at this language level no one agrees and nothing changes, and we are probably destined never to have namespaces either.
Actually on this issue the status quo has been something I have looked at and got annoyed with many times. Thinking - why do I have to create a method temporary with the same 'role suggesting instance variable name', when all I want to do is coerce the item into a known type, before using it.
regards
Keith
On 29-Apr-07, at 4:18 PM, Keith Hodges wrote:
all I want to do is coerce the item into a known type, before using it.
Aaaaaaaaaaaaarrrrrrrghh! <runs screaming down the hall waving arms>
tim -- tim Rowledge; tim@rowledge.org; http://www.rowledge.org/tim Fractured Idiom:- MAZEL TON - Lots of luck
I find if completely natural to expect to be able to assign to arguments, and for reasons entirely unrelated to Javascript. An argument is a binding in the environment created for evaluating the body of a lambda expression when it is applied, and as such there is no fundamental difference between it an a temporary variable. I see
| a | a := 3. a := a + 4
and
[:a | a := a + 4] value: 3
as the same thing. In this light, I see the "classic" policy of disallowing the latter as an arbitrary restriction, even when supported by emphatic hand-waving.
Oh, and the VisualWorks compiler has a configuration option to allow assignments to arguments.
--Vassili
<Vassili>I see the "classic" policy of disallowing the latter as an arbitrary restriction, even when supported by emphatic hand-waving.</Vassili>
I concur. The restriction on assignment to arguments simply creates an unnecessary semantic distinction between arguments and other variables, and so adds complexity to the denotational semantics of Smalltalk syntax. It's not as bad as Java's distinction between objects and primitive values, but it's a language design flaw of the same sort.
Bindings/assignments are not axioms, and Smalltalk is not a logic/functional programming language. Immutable bindings belong in a language where all bindings are immutable.
--Alan
From: Keith Hodges keith_hodges@yahoo.co.uk Reply-To: The general-purpose Squeak developers listsqueak-dev@lists.squeakfoundation.org To: The general-purpose Squeak developers listsqueak-dev@lists.squeakfoundation.org Subject: Re: Any reason for assigning block parameter in inject:into: Date: Mon, 30 Apr 2007 00:36:01 +0100
Aaaaaaaaaaaaarrrrrrrghh! <runs screaming down the hall waving arms>
Could you waive them in the direction to point me to the code where I can change the compiler to enable assignment to method params please.
Keith
But once you do that, any code you write can only be used by people who have your hack.
In Squeak the parameters are copies that just happen to be read-only, but is it this way in the other dialects? I would expect the parameter to be read-only, but I would expect that because I would expect at the low level the "pointer" to the original location is being passed for efficiency (since an object copy could be expensive) and therefor must be read-only.
_________________________________________________________________ Dont quit your job Take Classes Online and Earn your Degree in 1 year. Start Today! http://www.classesusa.com/clickcount.cfm?id=866146&goto=http%3A%2F%2Fwww...
Keith Hodges a écrit :
Aaaaaaaaaaaaarrrrrrrghh! <runs screaming down the hall waving arms>
Could you waive them in the direction to point me to the code where I can change the compiler to enable assignment to method params please. Keith
Easy:
TempVariableNode browse.
look at senders of isArg
Be prepared to live in your own world.
Nicolas
On Sun, 29 Apr 2007 14:52:45 -0700, bryce@kampjes.demon.co.uk wrote:
tim Rowledge writes:
The difference is that both you, Bert, and Colin are quite versed in Smalltalk. Anyone looking at Smalltalk as if it were C or some other dismal bit-mangling nonsense might very well be seeing the method parameter(s) as pointers.
C copies the arguments and allows you to change them. Just like Smalltalk would if we allowed arguments to be changed. I think Pascal didn't allow arguments to be changed. Personally I'm happy with the status quo, but could live with mutable arguments too.
Traditional Pascal had only by-value arguments, I believe.
I think Turbo Pascal 1.0 introduced by-ref arguments--well, actually UCSD Pascal probably introduced them earlier, and that was 25 years ago. (The current iteration has by-value, by-ref changeable and by-ref NOT changeable (as an optimization).
I don't really have a dog in this race but does it make sense to care what someone coming from another language might think? Shouldn't internal consistency be the primary consideration?
===Blake===
From: bryce@kampjes.demon.co.uk Reply-To: The general-purpose Squeak developers listsqueak-dev@lists.squeakfoundation.org To: The general-purpose Squeak developers listsqueak-dev@lists.squeakfoundation.org Subject: Re: Any reason for assigning block parameter in inject:into: Date: Sun, 29 Apr 2007 22:52:45 +0100
C copies the arguments and allows you to change them. Just like Smalltalk would if we allowed arguments to be changed. I think Pascal didn't allow arguments to be changed. Personally I'm happy with the status quo, but could live with mutable arguments too.
Bryce
That's true. C has only call-by-value semantics. Call-by-reference in C is purely by convention.
However, I think what he is saying is: smalltalk is using references (i.e. pointers to locations, but that I don't have to manage myself with ref/dereffing), so if I pass a reference that is automatically dereffed, and then change it, wont that change the original place? Think C++: if you see a function take a ¶m and it isn't const then you know something funny is going on (or you're looking at a bug).
_________________________________________________________________ Download Messenger. Join the im Initiative. Help make a difference today. http://im.live.com/messenger/im/home/?source=TAGHM_APR07
From: Bert Freudenberg bert@freudenbergs.de Reply-To: The general-purpose Squeak developers listsqueak-dev@lists.squeakfoundation.org To: The general-purpose Squeak developers listsqueak-dev@lists.squeakfoundation.org Subject: Re: Any reason for assigning block parameter in inject:into: Date: Sun, 29 Apr 2007 16:30:25 -0400
+1
I wouldn't expect assigning to a variable to affect the sending method. I think of method arguments as temps. Which they are, in Squeak at least. I actually don't see a compelling reason to disallow assigning to method args, except for stylistic ones.
I should probably mention that I am not stating an opinion against the ability to assign to the variables. If it makes sense and doesn't hurt anything then ok.
I'm simply against adding a feature to support some broken technique that we shouldn't be using anyway. If there are other motivations, then I have no issue with it.
_________________________________________________________________ Interest Rates NEAR 39yr LOWS! $430,000 Mortgage for $1,299/mo - Calculate new payment http://www.lowermybills.com/lre/index.jsp?sourceid=lmb-9632-19132&moid=1...
I don't think it's quite that.
Assigning simply to parameters is rarely if ever 'magical' in reaching up the call chain. (Among widespread languages, one exception is the goulash of C++ reference parameters; I can't think of others offhand.)
For the workaday C programmer, there's a very big difference between arg = 3; and (*arg) = 3. The distinction between 'what's in the local parameter' and 'what I have to do to change longer-lived state' is always front and center in low-level languages.
I don't think the real confusion that's avoided by barring assignment-to-arguments isn't that of someone writing param := foo and expecting non-local effects up the call chain.
Rather it's the confusion of sorting out what's going on in a piece of code when someone's decided variable names are too much work to invent, and reused parameter names for other quantities along the way.
When you're reading a piece of unfamiliar code, every bit of solid ground helps; knowing that the value of a parameter doesn't change in the course of the method makes it that much easier to read and debug.
- brad
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
Rather it's the confusion of sorting out what's going on in a piece of code when someone's decided variable names are too much work to invent, and reused parameter names for other quantities along the way.
When you're reading a piece of unfamiliar code, every bit of solid ground helps; knowing that the value of a parameter doesn't change in the course of the method makes it that much easier to read and debug.
The particular annoyance that I noticed was when very short methods which should have been one liners. end up as three of four because of the need to declare and assign a second variable to represent the same thing.
I dont think that debugging or readability is made easier by finding that there are not two, often similar, variable names which reference the same thing, one of which is immutable the other is not.
Keith
Hello Colin,
CP> Interesting. As far as I can tell, you're the only poster in this CP> thread that thinks assigning to a parameter name implies that the CP> parameter was passed by reference. Lukas was just complaining that CP> parameter slots are read-only, and giving examples of cases where it CP> would be nice to be able to write to them. I occasionally feel this CP> way too - making parameters different from other temps feels CP> arbitrarily inconsistent.
in LISP I do this regularly. A parameter usually being a list which in my function needs some preprocessing (e.g. removing collinear adjacent line segments) but still has the same meaning after the preprocessing.
Funny thing is I never came across this in my Squeak programming.
This makes me wonder what will happen, when I start complementing my LISP work (= bread and butter) with Squeak.
Cheers
Herbert mailto:herbertkoenig@gmx.net
On Sun, Apr 29, 2007 at 09:03:43AM -0700, tim Rowledge wrote:
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.
Can someone give me a pointer to a brief explanation of why closures were a hard problem for the original Squeak compiler? I know there is some limitation of the original implementation, and I know that this has been explained many times before, but I can't seem to find a simple explanation of the original problem. No debates please, I'm just curious about the reason for the original limitation.
Thanks a lot,
Dave
squeak-dev@lists.squeakfoundation.org