letn semantics for default vals and set: stable feature?

For the Compleat Fan

letn semantics for default vals and set: stable feature?

Postby hartrock » Sat Sep 26, 2015 11:55 am

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.
hartrock
 
Posts: 136
Joined: Wed Aug 07, 2013 9:37 pm

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

Postby Lutz » Sat Sep 26, 2015 2:09 pm

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.
Lutz
 
Posts: 5258
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California

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

Postby hartrock » Sat Sep 26, 2015 5:09 pm

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?
hartrock
 
Posts: 136
Joined: Wed Aug 07, 2013 9:37 pm

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

Postby Lutz » Sun Sep 27, 2015 2:32 pm

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.
Lutz
 
Posts: 5258
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California

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

Postby hartrock » Mon Sep 28, 2015 8:31 am

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.
hartrock
 
Posts: 136
Joined: Wed Aug 07, 2013 9:37 pm

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

Postby Lutz » Mon Sep 28, 2015 2:04 pm

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.
Lutz
 
Posts: 5258
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California

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

Postby hartrock » Mon Sep 28, 2015 6:45 pm

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/projects/poplog/paradigms_lectures/lecture11.html#setbang (to backup my remark regarding newLISP set).
hartrock
 
Posts: 136
Joined: Wed Aug 07, 2013 9:37 pm

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

Postby abaddon1234 » Wed Oct 21, 2015 9:15 am

that let and letex are the exception of a general left to right evaluation for setting symbols? Or is it more complicated?
เล่นจีคลับผ่านเว็บ
abaddon1234
 
Posts: 21
Joined: Mon Sep 14, 2015 3:09 am

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

Postby hartrock » Tue Oct 27, 2015 6:50 am

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.
hartrock
 
Posts: 136
Joined: Wed Aug 07, 2013 9:37 pm


Return to Anything else we might add?

Who is online

Users browsing this forum: No registered users and 3 guests

cron