3 ms·
Somewhat OT, but I cannot infer the semantics of let from the examples given. Among other things it seems to have indefinite scope.
by aidenn0 3y ago
Somewhat OT, but I cannot infer the semantics of let from the examples given. Among other things it seems to have indefinite scope.
- lifthrasiir 3y agoI'm reasonably sure that it is modeled after JS `let`, so there should be a notion of implicit scopes defined by, for example, `fun`.
- MaxBarraclough 3y agoOther way round. They're implementing a language of the LISP family, which tend to use let this way. LISP languages originated around 1960. The use of let then caught on in other languages, including OCaml and Haskell, and eventually JavaScript. (It's possible some language other than LISP was the first to use let, but my suspicion is it was LISP.) https://en.wikipedia.org/wiki/Lisp_(programming_language) https://en.wikipedia.org/wiki/Lisp_(programming_language)
- lifthrasiir 3y agoI'm specifically saying about `let` syntax in this particular language. LISP and related languages also have `let` with substantially different semantics, but it's evident that it wouldn't make much sense given current examples.
- aidenn0 3y agoYou must be right. I actually didn't know JS had a "let" (which is different from "var" in that it is block scoped rather than function scoped). It's also quite different from the let in most Lisps, in that it does not establish a new lexical block. Playing with it, the binding is scoped to the entire block, but the assignment happens in statement order so that e.g. the following will be an error, rather than logging either "1" or "2" both of which there could be arguments for: { let x = 1; { console.log(x); let x = 2; } }
- alpaca128 3y agoThe scope is clearly defined by the parentheses, though if you're not used to Lisp syntax that can be confusing at first. (let n 12) => let n = 12; (let res (square a)) => let res = a*a; (let mod3 (eq 0 (% i 3))) => let mod3 = (0 == i % 3);
- zoren 3y agoIn other lisps a let form has a body that the binding(s) range over and they are not available outside. As in `(let n 12 (+ n n))` here n wouldn't be accessible after. You have `(def name 5)` for making definitions that are readable outsude.
- trealira 3y agoIn Lisp, "let" is only used for binding the variable, and it comes with a scope. (let ((a 1) (b 2)) (+ a b)) It's closer to the ML version of let, which works like this: let val a = 1 val b = 2 in a + b end You can sequence expressions for side effects, as well. (let ((a 1) (b 2)) (incf a) (do-it a b) (+ a b))
- nequo 3y agoThose lets in TFA seem more like Lisp’s setq rather than let. A let expression would bind values to names only within the scope of (let …) itself. The lets in TFA and in your examples have side effects. You reference the bound values outside of (let …).
- aidenn0 3y ago> The scope is clearly defined by the parentheses, though if you're not used to Lisp syntax that can be confusing at first. The scope is clearly not defined by the parentheses, and I've been programming in Common Lisp for 25 years, so I'm pretty used to Lisp syntax. A sibling comment suggests it comes from the JavaScript let (which did not exist when I learned JavaScript; it wasn't introduced until 1.7), which is scoped to the containing lexical block, rather than a block introduced by the let form itself.
- dan-robertson 3y agoI’m not sure but I assume it works similarly to define in scheme or to let bindings in languages like rust or JavaScript where the binding lasts until the end of some kind of implicit scope.