Cannot assign a parameter

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Cannot assign a parameter

laurent laffont
Hi,

I can't write

foo: n 
  ^[:i| s := s+i. ]

but 

foo: n
  |s|
  s := n.
  ^[:i| s := s+i. ]


Why ?


Cheers, 

Laurent Laffont

Pharo Smalltalk Screencasts: http://www.pharocasts.com/
Blog: http://magaloma.blogspot.com/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Cannot assign a parameter

Max Leske
In the first example you didn't declare 's':

foo:n
^ [ :i || s | s:= s+i ]

Or did I misunderstand the question?

Cheers,
Max


On 28.11.2010, at 10:30, laurent laffont wrote:

Hi,

I can't write

foo: n 
  ^[:i| s := s+i. ]

but 

foo: n
  |s|
  s := n.
  ^[:i| s := s+i. ]


Why ?


Cheers, 

Laurent Laffont

Pharo Smalltalk Screencasts: http://www.pharocasts.com/
Blog: http://magaloma.blogspot.com/

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Cannot assign a parameter

laurent laffont
Sorry

foo: n 
  ^[:i| n := n+i. ]

vs

foo: n 
  |s| 
  s := n. 
  ^[:i| s := s+i. ]


Laurent

On Sun, Nov 28, 2010 at 10:51 AM, Max Leske <[hidden email]> wrote:
In the first example you didn't declare 's':

foo:n
^ [ :i || s | s:= s+i ]

Or did I misunderstand the question?

Cheers,
Max


On 28.11.2010, at 10:30, laurent laffont wrote:

Hi,

I can't write

foo: n 
  ^[:i| s := s+i. ]

but 

foo: n
  |s|
  s := n.
  ^[:i| s := s+i. ]


Why ?


Cheers, 

Laurent Laffont

Pharo Smalltalk Screencasts: http://www.pharocasts.com/
Blog: http://magaloma.blogspot.com/


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Cannot assign a parameter

Max Leske
Yeah, that's true, I've noticed that too. I guess it's on purpose but I have no idea. AFAIK you can't assign a new value to a parameter anywhere in the method not only when using blocks. Maybe it's not possible because there is not really a 'variable' but only a reference. So assigning a new value to the parameter would effectively override the reference. But don't trust me on this....

Cheers,
Max


On 28.11.2010, at 10:54, laurent laffont wrote:

Sorry

foo: n 
  ^[:i| n := n+i. ]

vs

foo: n 
  |s| 
  s := n. 
  ^[:i| s := s+i. ]


Laurent

On Sun, Nov 28, 2010 at 10:51 AM, Max Leske <[hidden email]> wrote:
In the first example you didn't declare 's':

foo:n
^ [ :i || s | s:= s+i ]

Or did I misunderstand the question?

Cheers,
Max


On 28.11.2010, at 10:30, laurent laffont wrote:

Hi,

I can't write

foo: n 
  ^[:i| s := s+i. ]

but 

foo: n
  |s|
  s := n.
  ^[:i| s := s+i. ]


Why ?


Cheers, 

Laurent Laffont

Pharo Smalltalk Screencasts: http://www.pharocasts.com/
Blog: http://magaloma.blogspot.com/



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Cannot assign a parameter

laurent laffont
I would like to know whether it's a design choice or a technical obstacle.

I've seen:

Parser>>assignment: varNode
" var ':=' expression => AssignmentNode."
| loc start |
(loc := varNode assignmentCheck: encoder at: prevMark + requestorOffset) >= 0
ifTrue: [^self notify: 'Cannot store into' at: loc].
        .....


TempVariableNode>>assignmentCheck: encoder at: location
^((self isBlockArg and: [Parser allowBlockArgumentAssignment not])
   or: [self isMethodArg])                                                                  "<-- not allowed !"
ifTrue: [location]
ifFalse: [-1]

But no explanation :(


Laurent



On Sun, Nov 28, 2010 at 10:59 AM, Max Leske <[hidden email]> wrote:
Yeah, that's true, I've noticed that too. I guess it's on purpose but I have no idea. AFAIK you can't assign a new value to a parameter anywhere in the method not only when using blocks. Maybe it's not possible because there is not really a 'variable' but only a reference. So assigning a new value to the parameter would effectively override the reference. But don't trust me on this....

Cheers,
Max


On 28.11.2010, at 10:54, laurent laffont wrote:

Sorry

foo: n 
  ^[:i| n := n+i. ]

vs

foo: n 
  |s| 
  s := n. 
  ^[:i| s := s+i. ]


Laurent

On Sun, Nov 28, 2010 at 10:51 AM, Max Leske <[hidden email]> wrote:
In the first example you didn't declare 's':

foo:n
^ [ :i || s | s:= s+i ]

Or did I misunderstand the question?

Cheers,
Max


On 28.11.2010, at 10:30, laurent laffont wrote:

Hi,

I can't write

foo: n 
  ^[:i| s := s+i. ]

but 

foo: n
  |s|
  s := n.
  ^[:i| s := s+i. ]


Why ?


Cheers, 

Laurent Laffont

Pharo Smalltalk Screencasts: http://www.pharocasts.com/
Blog: http://magaloma.blogspot.com/




Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Cannot assign a parameter

Max Leske
+1


On 28.11.2010, at 11:26, laurent laffont wrote:

I would like to know whether it's a design choice or a technical obstacle.

I've seen:

Parser>>assignment: varNode
" var ':=' expression => AssignmentNode."
| loc start |
(loc := varNode assignmentCheck: encoder at: prevMark + requestorOffset) >= 0
ifTrue: [^self notify: 'Cannot store into' at: loc].
        .....


TempVariableNode>>assignmentCheck: encoder at: location
^((self isBlockArg and: [Parser allowBlockArgumentAssignment not])
   or: [self isMethodArg])                                                                  "<-- not allowed !"
ifTrue: [location]
ifFalse: [-1]

But no explanation :(


Laurent



On Sun, Nov 28, 2010 at 10:59 AM, Max Leske <[hidden email]> wrote:
Yeah, that's true, I've noticed that too. I guess it's on purpose but I have no idea. AFAIK you can't assign a new value to a parameter anywhere in the method not only when using blocks. Maybe it's not possible because there is not really a 'variable' but only a reference. So assigning a new value to the parameter would effectively override the reference. But don't trust me on this....

Cheers,
Max


On 28.11.2010, at 10:54, laurent laffont wrote:

Sorry

foo: n 
  ^[:i| n := n+i. ]

vs

foo: n 
  |s| 
  s := n. 
  ^[:i| s := s+i. ]


Laurent

On Sun, Nov 28, 2010 at 10:51 AM, Max Leske <[hidden email]> wrote:
In the first example you didn't declare 's':

foo:n
^ [ :i || s | s:= s+i ]

Or did I misunderstand the question?

Cheers,
Max


On 28.11.2010, at 10:30, laurent laffont wrote:

Hi,

I can't write

foo: n 
  ^[:i| s := s+i. ]

but 

foo: n
  |s|
  s := n.
  ^[:i| s := s+i. ]


Why ?


Cheers, 

Laurent Laffont

Pharo Smalltalk Screencasts: http://www.pharocasts.com/
Blog: http://magaloma.blogspot.com/





Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Cannot assign a parameter

laurent laffont
Indeed if I rewrite
TempVariableNode>>assignmentCheck: encoder at: location
^(self isBlockArg and: [Parser allowBlockArgumentAssignment not])
ifTrue: [location]
ifFalse: [-1]

then

foo: n 
  ^[:i| n := n+i. ]

works. But I don't know the impact....

Laurent



On Sun, Nov 28, 2010 at 11:41 AM, Max Leske <[hidden email]> wrote:
+1


On 28.11.2010, at 11:26, laurent laffont wrote:

I would like to know whether it's a design choice or a technical obstacle.

I've seen:

Parser>>assignment: varNode
" var ':=' expression => AssignmentNode."
| loc start |
(loc := varNode assignmentCheck: encoder at: prevMark + requestorOffset) >= 0
ifTrue: [^self notify: 'Cannot store into' at: loc].
        .....


TempVariableNode>>assignmentCheck: encoder at: location
^((self isBlockArg and: [Parser allowBlockArgumentAssignment not])
   or: [self isMethodArg])                                                                  "<-- not allowed !"
ifTrue: [location]
ifFalse: [-1]

But no explanation :(


Laurent



On Sun, Nov 28, 2010 at 10:59 AM, Max Leske <[hidden email]> wrote:
Yeah, that's true, I've noticed that too. I guess it's on purpose but I have no idea. AFAIK you can't assign a new value to a parameter anywhere in the method not only when using blocks. Maybe it's not possible because there is not really a 'variable' but only a reference. So assigning a new value to the parameter would effectively override the reference. But don't trust me on this....

Cheers,
Max


On 28.11.2010, at 10:54, laurent laffont wrote:

Sorry

foo: n 
  ^[:i| n := n+i. ]

vs

foo: n 
  |s| 
  s := n. 
  ^[:i| s := s+i. ]


Laurent

On Sun, Nov 28, 2010 at 10:51 AM, Max Leske <[hidden email]> wrote:
In the first example you didn't declare 's':

foo:n
^ [ :i || s | s:= s+i ]

Or did I misunderstand the question?

Cheers,
Max


On 28.11.2010, at 10:30, laurent laffont wrote:

Hi,

I can't write

foo: n 
  ^[:i| s := s+i. ]

but 

foo: n
  |s|
  s := n.
  ^[:i| s := s+i. ]


Why ?


Cheers, 

Laurent Laffont

Pharo Smalltalk Screencasts: http://www.pharocasts.com/
Blog: http://magaloma.blogspot.com/






Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Cannot assign a parameter

Nicolas Cellier
In reply to this post by laurent laffont
2010/11/28 laurent laffont <[hidden email]>:
> I would like to know whether it's a design choice or a technical obstacle.
>

Clearly a design choice as you discovered.
One good reason is to ease debugging : it is easier to accept/restart
if the method context has not changed.

Nicolas

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Cannot assign a parameter

Adrian Lienhard
In reply to this post by Max Leske
Its an artificial restriction. Method arguments are just like temps, i.e., the interpreter does not distinguish between the two; its only the compiler that restricts assignments to arguments (I'm not 100% sure, but I assume that this still holds with Eliot's new closure compiler).

I think it would be nice to be able to assign to arguments. In some cases they make for concise and better readable code (I got used to this for instance in Python and JavaScript). For example, consider a method that uses an argument in multiple places and you figure that you need to handle the case in which the argument is nil. You just add a line like: arg := arg ifNil: [ 0 ]. Without argument assignment you would need to create a temp var with a different name and change all usage of the old arg variable.

Block args had been writable until the new closure compiler was introduced, which by default disallows arg assignments. I don't remember what the rationale for this change was (?).

On the flip side, one has to consider code portability. For projects like Seaside this probably is a no go. But for projects that don't need to be ported I think it would be a worthwhile change. Projects that need to avoid portability troubles with other dialects should use Lint rules (stuff like this is better checked by Lint than the compiler...).

I'll also note that this topic was discussed before and some people argued that argument assignments can lead to bad code quality...

Cheers,
Adrian
 
On Nov 28, 2010, at 11:41 , Max Leske wrote:

> +1
>
>
> On 28.11.2010, at 11:26, laurent laffont wrote:
>
>> I would like to know whether it's a design choice or a technical obstacle.
>>
>> I've seen:
>>
>> Parser>>assignment: varNode
>> " var ':=' expression => AssignmentNode."
>> | loc start |
>> (loc := varNode assignmentCheck: encoder at: prevMark + requestorOffset) >= 0
>> ifTrue: [^self notify: 'Cannot store into' at: loc].
>>        .....
>>
>>
>> TempVariableNode>>assignmentCheck: encoder at: location
>> ^((self isBlockArg and: [Parser allowBlockArgumentAssignment not])
>>    or: [self isMethodArg])                                                                  "<-- not allowed !"
>> ifTrue: [location]
>> ifFalse: [-1]
>>
>> But no explanation :(
>>
>>
>> Laurent
>>
>>
>>
>> On Sun, Nov 28, 2010 at 10:59 AM, Max Leske <[hidden email]> wrote:
>> Yeah, that's true, I've noticed that too. I guess it's on purpose but I have no idea. AFAIK you can't assign a new value to a parameter anywhere in the method not only when using blocks. Maybe it's not possible because there is not really a 'variable' but only a reference. So assigning a new value to the parameter would effectively override the reference. But don't trust me on this....
>>
>> Cheers,
>> Max
>>
>>
>> On 28.11.2010, at 10:54, laurent laffont wrote:
>>
>>> Sorry
>>>
>>> foo: n
>>>  ^[:i| n := n+i. ]
>>>
>>> vs
>>>
>>> foo: n
>>>  |s|
>>>  s := n.
>>>  ^[:i| s := s+i. ]
>>>
>>>
>>> Laurent
>>>
>>> On Sun, Nov 28, 2010 at 10:51 AM, Max Leske <[hidden email]> wrote:
>>> In the first example you didn't declare 's':
>>>
>>> foo:n
>>> ^ [ :i || s | s:= s+i ]
>>>
>>> Or did I misunderstand the question?
>>>
>>> Cheers,
>>> Max
>>>
>>>
>>> On 28.11.2010, at 10:30, laurent laffont wrote:
>>>
>>>> Hi,
>>>>
>>>> I can't write
>>>>
>>>> foo: n
>>>>  ^[:i| s := s+i. ]
>>>>
>>>> but
>>>>
>>>> foo: n
>>>>  |s|
>>>>  s := n.
>>>>  ^[:i| s := s+i. ]
>>>>
>>>>
>>>> Why ?
>>>>
>>>>
>>>> Cheers,
>>>>
>>>> Laurent Laffont
>>>>
>>>> Pharo Smalltalk Screencasts: http://www.pharocasts.com/
>>>> Blog: http://magaloma.blogspot.com/
>>>
>>>
>>
>>
>


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Cannot assign a parameter

laurent laffont
OK thank you.


Laurent.

On Sun, Nov 28, 2010 at 3:36 PM, Adrian Lienhard <[hidden email]> wrote:
Its an artificial restriction. Method arguments are just like temps, i.e., the interpreter does not distinguish between the two; its only the compiler that restricts assignments to arguments (I'm not 100% sure, but I assume that this still holds with Eliot's new closure compiler).

I think it would be nice to be able to assign to arguments. In some cases they make for concise and better readable code (I got used to this for instance in Python and JavaScript). For example, consider a method that uses an argument in multiple places and you figure that you need to handle the case in which the argument is nil. You just add a line like: arg := arg ifNil: [ 0 ]. Without argument assignment you would need to create a temp var with a different name and change all usage of the old arg variable.

Block args had been writable until the new closure compiler was introduced, which by default disallows arg assignments. I don't remember what the rationale for this change was (?).

On the flip side, one has to consider code portability. For projects like Seaside this probably is a no go. But for projects that don't need to be ported I think it would be a worthwhile change. Projects that need to avoid portability troubles with other dialects should use Lint rules (stuff like this is better checked by Lint than the compiler...).

I'll also note that this topic was discussed before and some people argued that argument assignments can lead to bad code quality...

Cheers,
Adrian

On Nov 28, 2010, at 11:41 , Max Leske wrote:

> +1
>
>
> On 28.11.2010, at 11:26, laurent laffont wrote:
>
>> I would like to know whether it's a design choice or a technical obstacle.
>>
>> I've seen:
>>
>> Parser>>assignment: varNode
>>      " var ':=' expression => AssignmentNode."
>>      | loc start |
>>      (loc := varNode assignmentCheck: encoder at: prevMark + requestorOffset) >= 0
>>              ifTrue: [^self notify: 'Cannot store into' at: loc].
>>        .....
>>
>>
>> TempVariableNode>>assignmentCheck: encoder at: location
>>      ^((self isBlockArg and: [Parser allowBlockArgumentAssignment not])
>>          or: [self isMethodArg])                                                                  "<-- not allowed !"
>>                      ifTrue: [location]
>>                      ifFalse: [-1]
>>
>> But no explanation :(
>>
>>
>> Laurent
>>
>>
>>
>> On Sun, Nov 28, 2010 at 10:59 AM, Max Leske <[hidden email]> wrote:
>> Yeah, that's true, I've noticed that too. I guess it's on purpose but I have no idea. AFAIK you can't assign a new value to a parameter anywhere in the method not only when using blocks. Maybe it's not possible because there is not really a 'variable' but only a reference. So assigning a new value to the parameter would effectively override the reference. But don't trust me on this....
>>
>> Cheers,
>> Max
>>
>>
>> On 28.11.2010, at 10:54, laurent laffont wrote:
>>
>>> Sorry
>>>
>>> foo: n
>>>  ^[:i| n := n+i. ]
>>>
>>> vs
>>>
>>> foo: n
>>>  |s|
>>>  s := n.
>>>  ^[:i| s := s+i. ]
>>>
>>>
>>> Laurent
>>>
>>> On Sun, Nov 28, 2010 at 10:51 AM, Max Leske <[hidden email]> wrote:
>>> In the first example you didn't declare 's':
>>>
>>> foo:n
>>> ^ [ :i || s | s:= s+i ]
>>>
>>> Or did I misunderstand the question?
>>>
>>> Cheers,
>>> Max
>>>
>>>
>>> On 28.11.2010, at 10:30, laurent laffont wrote:
>>>
>>>> Hi,
>>>>
>>>> I can't write
>>>>
>>>> foo: n
>>>>  ^[:i| s := s+i. ]
>>>>
>>>> but
>>>>
>>>> foo: n
>>>>  |s|
>>>>  s := n.
>>>>  ^[:i| s := s+i. ]
>>>>
>>>>
>>>> Why ?
>>>>
>>>>
>>>> Cheers,
>>>>
>>>> Laurent Laffont
>>>>
>>>> Pharo Smalltalk Screencasts: http://www.pharocasts.com/
>>>> Blog: http://magaloma.blogspot.com/
>>>
>>>
>>
>>
>



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Cannot assign a parameter

Henrik Sperre Johansen
In reply to this post by Adrian Lienhard
On 28.11.2010 15:36, Adrian Lienhard wrote:
> I'll also note that this topic was discussed before and some people argued that argument assignments can lead to bad code quality...
+1 to that, your example of allowing nil to a method expecting something
else as a prime example.
Good luck debugging THAT (and figuring out it is indeed the cause) if
nil is passed erroneously :)

Cheers,
Henry

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Cannot assign a parameter

Andres Valloud-4
In reply to this post by Adrian Lienhard
Wouldn't debugging be harder if arguments could be assigned to?  Where
would you keep the original argument?  If you did that, wouldn't it be
more costly to run methods?

On 11/28/10 6:36 , Adrian Lienhard wrote:

> Its an artificial restriction. Method arguments are just like temps, i.e., the interpreter does not distinguish between the two; its only the compiler that restricts assignments to arguments (I'm not 100% sure, but I assume that this still holds with Eliot's new closure compiler).
>
> I think it would be nice to be able to assign to arguments. In some cases they make for concise and better readable code (I got used to this for instance in Python and JavaScript). For example, consider a method that uses an argument in multiple places and you figure that you need to handle the case in which the argument is nil. You just add a line like: arg := arg ifNil: [ 0 ]. Without argument assignment you would need to create a temp var with a different name and change all usage of the old arg variable.
>
> Block args had been writable until the new closure compiler was introduced, which by default disallows arg assignments. I don't remember what the rationale for this change was (?).
>
> On the flip side, one has to consider code portability. For projects like Seaside this probably is a no go. But for projects that don't need to be ported I think it would be a worthwhile change. Projects that need to avoid portability troubles with other dialects should use Lint rules (stuff like this is better checked by Lint than the compiler...).
>
> I'll also note that this topic was discussed before and some people argued that argument assignments can lead to bad code quality...
>
> Cheers,
> Adrian
>
> On Nov 28, 2010, at 11:41 , Max Leske wrote:
>
>> +1
>>
>>
>> On 28.11.2010, at 11:26, laurent laffont wrote:
>>
>>> I would like to know whether it's a design choice or a technical obstacle.
>>>
>>> I've seen:
>>>
>>> Parser>>assignment: varNode
>>> " var ':=' expression =>  AssignmentNode."
>>> | loc start |
>>> (loc := varNode assignmentCheck: encoder at: prevMark + requestorOffset)>= 0
>>> ifTrue: [^self notify: 'Cannot store into' at: loc].
>>>         .....
>>>
>>>
>>> TempVariableNode>>assignmentCheck: encoder at: location
>>> ^((self isBlockArg and: [Parser allowBlockArgumentAssignment not])
>>>    or: [self isMethodArg])                                                                  "<-- not allowed !"
>>> ifTrue: [location]
>>> ifFalse: [-1]
>>>
>>> But no explanation :(
>>>
>>>
>>> Laurent
>>>
>>>
>>>
>>> On Sun, Nov 28, 2010 at 10:59 AM, Max Leske<[hidden email]>  wrote:
>>> Yeah, that's true, I've noticed that too. I guess it's on purpose but I have no idea. AFAIK you can't assign a new value to a parameter anywhere in the method not only when using blocks. Maybe it's not possible because there is not really a 'variable' but only a reference. So assigning a new value to the parameter would effectively override the reference. But don't trust me on this....
>>>
>>> Cheers,
>>> Max
>>>
>>>
>>> On 28.11.2010, at 10:54, laurent laffont wrote:
>>>
>>>> Sorry
>>>>
>>>> foo: n
>>>>   ^[:i| n := n+i. ]
>>>>
>>>> vs
>>>>
>>>> foo: n
>>>>   |s|
>>>>   s := n.
>>>>   ^[:i| s := s+i. ]
>>>>
>>>>
>>>> Laurent
>>>>
>>>> On Sun, Nov 28, 2010 at 10:51 AM, Max Leske<[hidden email]>  wrote:
>>>> In the first example you didn't declare 's':
>>>>
>>>> foo:n
>>>> ^ [ :i || s | s:= s+i ]
>>>>
>>>> Or did I misunderstand the question?
>>>>
>>>> Cheers,
>>>> Max
>>>>
>>>>
>>>> On 28.11.2010, at 10:30, laurent laffont wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> I can't write
>>>>>
>>>>> foo: n
>>>>>   ^[:i| s := s+i. ]
>>>>>
>>>>> but
>>>>>
>>>>> foo: n
>>>>>   |s|
>>>>>   s := n.
>>>>>   ^[:i| s := s+i. ]
>>>>>
>>>>>
>>>>> Why ?
>>>>>
>>>>>
>>>>> Cheers,
>>>>>
>>>>> Laurent Laffont
>>>>>
>>>>> Pharo Smalltalk Screencasts: http://www.pharocasts.com/
>>>>> Blog: http://magaloma.blogspot.com/
>>>>
>>>>
>>>
>>>
>>
>
>
> .
>

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

SqueakSource is down

David T. Lewis
In reply to this post by Nicolas Cellier
Can someone please wake it up? Thanks.


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: SqueakSource is down

Stéphane Ducasse
In reply to this post by Nicolas Cellier
+1

I probably killed it with some heavy changes. :(

David I'm really chasing inria to create a secure webdav to host a new squeak-source (but there are security problem is some of their infrastructure and they told
me that they should fix that first).
We got the hudson server up and running with slaves.


> Can someone please wake it up? Thanks.
>
>


Loading...