Re: SRFI 182: ADBMAL, ALET, and ALET*
Joo ChurlSoo 10 Mar 2020 05:12 UTC
* From: Jim Rees <xxxxxx@gmail.com>
* Date: Mon, 9 Mar 2020 12:42:56 -0400
* Subj: Re: SRFI 182: ADBMAL, ALET, and ALET*
| The proceed adbmal* seems like an interesting alternative to values for some situations.
| But the syntactic versions don't add anything except disadvantages -- they delay evaluation
| (possibly to a different dynamic extent), and they do not memoize their results, so multiple calls
| could produce different values and could produce multiple side effects. Consider the following
| to remove these issues.
(adbmal expr ...) ==> (let ((tmp expr) ...) (lambda (f) (f tmp ...)))
| (where (tmp ...) are generated temporary ids).
| The advantage this has over adbmal* is that it avoids cons'ing up arguments into a list and
| needing to call apply on f.
For example:
(define x 1)
(define y 2)
(define a (adbmal x y))
(define a* (adbmal* x y))
(define v (values x y)) error:racket
(define v* (lambda () (values x y)))
(define listxy (lambda (x y) (list x y)))
(a listxy) = (1 2)
(a* listxy) = (1 2)
(call-with-values v listxy) error
(call-with-values v* listxy) = (1 2)
(receive (x y) v (list x y)) error or (1 2):gambit
(receive (x y) v* (list x y)) error
(receive (x y) (v*) (list x y)) = (1 2)
(set! x 10)
(set! y 20)
(a listxy) = (10 20)
(a* listxy) = (1 2)
(call-with-values v* listxy) = (10 20)
(receive (x y) (v*) (list x y)) = (10 20)
(receive (x y) v (list x y)) error or (1 2):gambit
I don't know anything more than this.
| alet is interesting -- I see it having potential to be CL's destructuring-bind with added support
| for multi-valued expressions. Did you consider arbitrary recursion to the bindings?
(alet (((a (values b ((adbmal c . d) . e))) expr)) ...)
No.
| How about destructuring vector expressions too?
I'm not interested in that yet.
| Semantic consistency issues I have with alet:
| Rules 1 and 2-1 mean that:
(foo 'bar) ==> simple binding
(foo bar '(1 2)) ==> de-structuring ???
> (alet ((foo 'bar)) foo)
'bar
> (alet ((foo bar '(1 2))) (list foo bar))
'(1 2)
| 3-1/5-1:
((foo bar) (iota 2)) ==> destructuring
((foo bar) (iota 3)) ==> destructuring, runtime error -- too many values
((foo) (iota 2)) ==> single-variable binding, no destructuring, not an error! ???
> (alet ((foo bar) (iota 2)) (list foo iota))
; bar: undefined;
> (let ((bar 'bar))
(alet ((foo bar) (iota 2)) (list foo iota)))
'(bar 2)
> (alet (((foo) (iota 2))) foo)
'(0 1)
> (alet ((foo (iota 2))) foo)
'(0 1)
> (alet ((foo) (iota 2)) (list foo iota))
'(#<continuation> 2)
See example 5.
| 4-1/5-2:
((foo . bar) (iota 2)) ==> destructuring
((foo . bar) (iota 2) "hello") ==> foo bound to (0 1) , bar bound to ("hello") ???
> (alet ((foo . bar) (iota 2)) (list foo bar iota))
'(#<procedure:t> #<procedure:t> 2)
See example 4.
> (alet ((foo . bar) (iota 2) "hello") (list foo bar iota))
lambda: not an identifier at: "hello"
| These examples are non-intuitive. The 2-1 rule should just go away, in my opinion. The
| second two can be easily remedied by changing 5-1/5-2 to instead be specializations on
| 3-1/4-1:
| * 5-1. ((<var1> <var2> ...) (list <expr1> <expr2> ...))
((lambda (<var1> <var2> ...) body) <expr1> <expr2> ...)
5-2. ((<var1> <var2> ... . <varn>) (list <expr1> <expr2> <expr3> ...))
| ==> ((lambda (<var1> <var2> ... <varn>) body) <expr1> <expr2> ... (list <exprn> ...))
| So, we require the caller to use the list keyword on the right hand size, but lose no performance
| with an unnecessary call to list. 3-1 needs to be changed to permit as few as one variable
| also.
| For completeness, rule 3-1 could be changed to permit zero variables. That may seem useless
| by a user, but if alet calls are generated by other macros, it may be convenient to permit the
| most general situations.
| On Sat, Feb 22, 2020 at 7:16 PM Arthur A. Gleckler <xxxxxx@speechcode.com> wrote:
What's wrong? I don't know.
Thanks.
--
Joo ChurlSoo