constants and local clash

Started by nigelbrown, March 11, 2004, 10:59:33 PM

Previous topic - Next topic

nigelbrown

Consider:

CRADLE> (constant 'zz 10)

10

CRADLE> (define (tst n , zz) (begin (setq zz (+ n n)) zz))

(lambda (n , zz)

 (begin

  (setq zz (+ n n)) zz))

CRADLE> (tst 2)



symbol is protected : zz

called from user defined function tst

>



Without thinking too hard about it I expected a local zz not

to conflict with a constant zz

HPW

#1
You have created the constant in the namespace.


Quote
> (constant 'zz 10)



10

> (context 'Test)

Test

Test> (define (tst n , zz) (begin (setq zz (+ n n)) zz))

(lambda (n , zz)

 (begin

  (setq zz (+ n n)) zz))

Test> (tst 2)

4

Test> (context 'MAIN)

MAIN

> (tst 2)



invalid function : (tst 2)



> (Test:tst 2)

4

> zz

10

>
Hans-Peter

nigelbrown

#2
Hi Hans-Peter,

The example I used was a little confusing in that I wasn't referring to context local variables (I just happened to be in a context when I thought of the example).



What I was referring to was the variable bindings within a lamba. The manual says:

"When binding parameter symbols in lambda expressions to their new contents, the old bindings (environment) of these symbols are saved on a stack. newLISP automatically restores the environment (the original variable bindings) when leaving the lambda function."  I assumed that the constant setting for the old binding would also be saved on

the stack and the newly bound symbols would be modifiable - when the lambda expression is exited and the old bindings restored the symbol would then again be the original constant with its original value.



If not then problems occur due to conflicts between constant names and dummy symbols for a function e.g.

> (constant 'str "my string")

"my string"

> str

"my string"

> (define (showme str) (print str))

(lambda (str) (print str))

> (showme "this string")



symbol is protected : str

called from user defined function showme



>



Someone will want both a constant x and x as a lambda parameter.



One way around this is to have a naming convention for constants eg surround with stars viz *x* e.g.

> (constant '*x*  2)

2

> *x*

2

>

(by the way I couldn't see an explicit rule for what are acceptable characters in an identifier symbol in the manual? - I could have missed it)



Maybe Lutz could say what the intent was regarding constant and lambda dummy symbols.

Lutz

#3
A constant variable cannot be used as a parameter variable in the same conetxt. But when using the same variable name in a context (see HPW example): the variable MAIN:zz and Test:zz are lexically different variables, there are two places for this in memory and two different places for it in the symbol table: MAIN:zz is a child of MAIN and Test:zz is a child of Test which is a child of MAIN. Both are lexically seperated.



When using a constant variable as parameter in a function we are talking about the same variable, this time dynamicaly scoped and retaining it's 'constant' character. The decision not to change/restore the constant behaviour of a dynamic variable was made deliberately for the following reasons:



- it makes its 'constant' character stronger and doesn't allow it to

be shadowed by the dynamics of dynamic scoping



- a big groups of constants are primitives, which should never be shadowed (primitives are also globals)



About variable naming conventions: a variablename can start with any character except a number digit or dot semicolon ; or pound sign #. If the first charcater is a + or - no digit can follow it.



After that any character can follow except for ( ) , : " ' space # ; which will end the variable.



I will put somehting in the manual for this.



Lutz

Lutz

#4
When writing a paragraph for the manual and going through the parser code, I realized I forgot something about variable/symbol names:



A symbol starting with [ and ending with ] can have any characters inside, i.e.:



[1 &*$()}]



is a legal variable symbol.



Lutz

nigelbrown

#5
Hi Lutz,

Thanks for the explaination re constants - I can see now that pi etc should not be used as parameters.



Nigel

nigelbrown

#6
Lutz,

I also noticed that making something a constant in a lambda expression means the previos symbol will then be a constant viz



newLISP v7.5.8 Copyright (c) 2004 Lutz Mueller. All rights reserved.

 

> (setq z 8)

8

> (define (trick ,z) (constant 'z 3))

(lambda (, z) (constant 'z 3))

> z

8

> (trick)

3

> z

8

> (setq z 5)

 

symbol is protected in function setq : z

 

>

Is that a side effect that should be avoided?

Lutz

#7
In 7.5.9 'z' is only constant in the dynamic scope of the function trick:





(define (trick z) (constant 'z 999))



(trick) => 999



(set 'z 123) => 123



(trick) => 999



z => 123



Lutz