letn semantics for default vals and set: stable feature?

For the Compleat Fan
Post Reply
hartrock
Posts: 136
Joined: Wed Aug 07, 2013 9:37 pm

letn semantics for default vals and set: stable feature?

Post by hartrock »

It could be helpful to mention in the manual (haven't found it), that setting symbols by 'Default variable values' (http://www.newlisp.org/CodePatterns.html#toc-4) or set goes from left to right, honoring the values of symbols already set: this is letn semantics (in contrast to let 'using symbol bindings as before the let statement').
Examples:

Code: Select all

> 
(define (foo (a1 1) (a2 (+ a1 1)) (a3 (+ a2 1)))
  (println "a1: " a1 ", a2: " a2 ", a3: " a3))
(foo)

(lambda ((a1 1) (a2 (+ a1 1)) (a3 (+ a2 1))) (println "a1: " 
  a1 ", a2: " a2 ", a3: " a3))
a1: 1, a2: 2, a3: 3
3
> 
(set 'a1 1 'a2 (+ a1 1) 'a3 (+ a2 1))
(println "a1: " a1 ", a2: " a2 ", a3: " a3)

3
a1: 1, a2: 2, a3: 3
3
> 
If this is not a stable feature, this would be interesting to know, too.

Lutz
Posts: 5285
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Re: letn semantics for default vals and set: stable feature?

Post by Lutz »

Thanks Hartrock. For the define function, this is already shown in one of the examples. For set an example will be added in the future manual.

hartrock
Posts: 136
Joined: Wed Aug 07, 2013 9:37 pm

Re: letn semantics for default vals and set: stable feature?

Post by hartrock »

It's good to know for sure, that things like:

Code: Select all

(define (do str , (len (length str)))
  ...)
(set 'str "foo"
     'len (length str))
are working reliably.
For bind with evaluation it is left to right, too:

Code: Select all

> 
(define-macro (foo)
  (local (a1 a2 a3)
    (bind (args) true)
    (println "a1: " a1 ", a2: " a2 ", a3: " a3)))

(lambda-macro () 
 (local (a1 a2 a3) 
  (bind (args) true) 
  (println "a1: " a1 ", a2: " a2 ", a3: " a3)))
> (foo (a1 1) (a2 (+ a1 1)) (a3 (+ a2 1)))
a1: 1, a2: 2, a3: 3
3
>
Is it possible to say - as a rule of thumb for easy memorizing (good not only for beginners) -, that let and letex are the exception of a general left to right evaluation for setting symbols? Or is it more complicated?

Lutz
Posts: 5285
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Re: letn semantics for default vals and set: stable feature?

Post by Lutz »

define, letn, let , letex, all have to deal with two variable environments: the calling environment and the their own environment. Only define and letn will assign from the changed current own environment. let, letex will consistently refer to the calling environment:

Code: Select all

> (define (foo (a 1) (b (+ 1 a))) (list a b))
(lambda ((a 1) (b (+ 1 a))) (list a b))
> (set 'a 123)
123
> (foo)
(1 2)
> (letn (a 1  b (+ a 1)) (list a b))
(1 2)

> (let (a 1  b (+ a 1)) (list a b))
(1 124)
> (letex (a 1  b (+ a 1)) '(a b))
(1 124)
>
If you name the local and variable assigned from the same, there is no difference:

Code: Select all

> (define (foo (a a)) a)
(lambda ((a a)) a)
> (foo)
123
> (letn (a a) a)
123
> (letex (a a) a)
123
> (let (a a) a)
123


The functions set and bind only deal with one environment which gets updated incrementally.

hartrock
Posts: 136
Joined: Wed Aug 07, 2013 9:37 pm

Re: letn semantics for default vals and set: stable feature?

Post by hartrock »

Lutz wrote:

Code: Select all

> (define (foo (a a)) a)
(lambda ((a a)) a)
> (foo)
123
> (letn (a a) a)
123
> (letex (a a) a)
123
> (let (a a) a)
123
Thanks for the example, where symbol a refers to different environments: inner new environment and outer one, where it has 123 value (inner val gets outer val assigned here).

I already have known all of these semantics, but I haven't been sure for 100%, that e.g.:

Code: Select all

(set 'foo 1
     'bar (+ foo 1))
is and stays the same as:

Code: Select all

(set 'foo 1)
(set 'bar (+ foo 1))
At a first look same semantics for both variants may seem to be 'natural'.
But it had been possible to keep a door open for some kind of optimization: to only use second variant for enforcing sequential set'ing of syms, and reserving first one for allowing set'ing them in parallel by using their values before set expression (which - if used (!) - would make a difference for bar, giving it the value of foo before set'ing this to 1 incremented by 1).
This door is not open, but IMO it had been a possibility to want to keep it open.

Lutz
Posts: 5285
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Re: letn semantics for default vals and set: stable feature?

Post by Lutz »

Evaluation order in general is always depth first from left to right.

See also here: https://en.wikipedia.org/wiki/Tree_traversal

If you want to change that order you would write a fexpr using the define-macro function, which does not evaluate arguments on function entry. There also some - the more complex - built-in functions, which don't follow that order, like for and other flow control flow control functions. Lisp calls these special forms.

hartrock
Posts: 136
Joined: Wed Aug 07, 2013 9:37 pm

Re: letn semantics for default vals and set: stable feature?

Post by hartrock »

Lutz wrote:Evaluation order in general is always depth first from left to right.

See also here: https://en.wikipedia.org/wiki/Tree_traversal

If you want to change that order you would write a fexpr using the define-macro function, which does not evaluate arguments on function entry.
Thanks for clarification.
Lutz wrote: There also some - the more complex - built-in functions, which don't follow that order, like for and other flow control flow control functions. Lisp calls these special forms.
At least for Scheme set! (haven't seen 'set' without '!' there) is mentioned as special form; see e.g. http://www.cs.bham.ac.uk/research/proje ... ml#setbang (to backup my remark regarding newLISP set).

abaddon1234
Posts: 21
Joined: Mon Sep 14, 2015 3:09 am

Re: letn semantics for default vals and set: stable feature?

Post by abaddon1234 »

that let and letex are the exception of a general left to right evaluation for setting symbols? Or is it more complicated?
เล่นจีคลับผ่านเว็บ

hartrock
Posts: 136
Joined: Wed Aug 07, 2013 9:37 pm

Re: letn semantics for default vals and set: stable feature?

Post by hartrock »

abaddon1234 wrote:that let and letex are the exception of a general left to right evaluation for setting symbols? Or is it more complicated?
เล่นจีคลับผ่านเว็บ
let and letex are using the outer binding of given symbols for initialization; e.g.:

Code: Select all

sr@free:~$ newlisp
newLISP v.10.6.4 64-bit on Linux IPv4/6 UTF-8 libffi, options: newlisp -h

> (letex (x 1 y 2 z 3) '(x y z))
(1 2 3)
> ; but:
> (letex (x 1 y (+ x 1) z (+ y 1)) '(x y z))

ERR: value expected in function + : nil
> ; but:
> (set 'x 10 'y 11)
11
> (letex (x 1 y (+ x 1) z (+ y 1)) '(x y z))
(1 11 12)
> 
My point regarding set - denoted as a special form in other Lisps - has been, that it should stated somewhere in the manual, that it follows the general rule of left-to-right evaluation using formerly set bindings at the same level (there is no new level of bindings):

Code: Select all

sr@free:~$ newlisp
newLISP v.10.6.4 64-bit on Linux IPv4/6 UTF-8 libffi, options: newlisp -h

> (set 'x 1 'y (+ x 1) 'z (+ y 1)) (list x y z)
3
(1 2 3)
> 
That there are no new bindings introduced is clear, but set - as well as let - guaranteed to follow the general left-to-right evaluation rule has not been self-evident to me. Think of parallelization opportunities, if this would not been the case; on the other side parallelization could be dangerous in case of side-effects.
Possibly some thoughts along 'pure functional programming is good for parallelization, because it has no side effects' has made my thinking more complicated than needed here.

It is probably correct to say for newLISP, that the general rule of left-to-right evaluation:
  • also applies for expressions like set, let - even if denoted as special forms in other Lisps -;
  • does not apply only, if explicitely stated so.
Taking the definition of special forms from the newLISP manual (different from other Lisps):
manual wrote: Lisp functions that do not evaluate all or some of their arguments are called special forms.
; denoting something as special form there only implies, that the general rule of left-to-right evaluation does not apply to all arguments.

To make a long story short:
Lutz wrote: Evaluation order in general is always depth first from left to right.
Where
  • arguments are evaluated - like for function calls and also for expressions like let -, and
  • nothing is said about a special evaluation order,
left-to-right evaluation applies.

Note: It is possible, of course, to write some macro for changing evaluation order by rearranging to be evaluated macro arguments.

Post Reply