5 ms·
He is probably talking about namespaces. In common lisp, for example, (a a) calls a function 'a' on a variable 'a'. Lisp knows this because the first thing
by medo-bear 3y ago
He is probably talking about namespaces. In common lisp, for example,
(a a)
calls a function 'a' on a variable 'a'. Lisp knows this because the first thing that comes after the left paren is a function
- convolvatron 3y agomore importantly there are functions (using scheme as an example) like set! and set-cdr! that mutate existing values and totally break referential transparency. this isn't just user facing - for example let* kind of depends on creating bindings up front so they work across clauses, and then mutating them afterwards
- amake 3y agoWhy does `let*` need to have mutation? It can be nested `let`s.
- convolvatron 3y agolet* permits expressions on the right refer to arbitrary other symbols bound by the let*. in particular it allows for construction of recursive lambdas that may not be linearlizable.
- amake 3y ago> let* permits expressions on the right refer to arbitrary other symbols bound by the let* In what language? I just checked Elisp, SBCL, and Guile, and they all error out if you refer to a variable not previously defined by a left-to-right traversal of the varlist: (let* ((a (+ b 1)) (b 1)) a) Edit: This doesn't work either: (let* ((a (lambda () (+ b 1))) (b 1)) (funcall a)) ; (funcall a) -> (a) for Schemes
- amake 3y agoAnyway, as far as I'm seeing it's perfectly possible to implement let* consistent with the above behavior as a macro without mutation as such: (define-macro (let* bindings &rest body) (if (null? bindings) `(progn ,@body) `(let (,(car bindings)) (let* ,(cdr bindings) ,@body))))
- tonyg 3y agoYou're thinking of letrec.
- amake 3y agoAh, that does look to be the case. I didn't know about that one. Signature (letrec BINDERS &rest BODY) Documentation Bind variables according to BINDERS then eval BODY. The value of the last form in BODY is returned. Each element of BINDERS is a list (SYMBOL VALUEFORM) that binds SYMBOL to the value of VALUEFORM. The main difference between this macro and let/let* is that all symbols are bound before any of the VALUEFORMs are evalled.
- medo-bear 3y agoLisp allows you to mutate, you can certainly write non-mutating code in lisp. Why do you think you need to use mutation with let*? let* is just a sequential let https://www.lispworks.com/documentation/lw70/CLHS/Body/s_let_l.htm https://www.lispworks.com/documentation/lw70/CLHS/Body/s_let...