3 ms·
Now try to run this: and(false, console.log("This shouldn't run")) A critical part of the semantics of the kernel function, and the javascript built in &&
by qwertyuiop924 11y ago
Now try to run this:
and(false, console.log("This shouldn't run"))
A critical part of the semantics of the kernel function, and the javascript built in &&, is that they are _short circuit_, that is, they only evaluate the second value if the first value evaluates to false. This is very important if you're programming with side effects.
- Sanddancer 11y agoHis function will short circuit. It'll expand to: false ? console.log("This shouldn't run") ? console.log("This shouldn't run") : false : false The ? operator checks the left hand side, branching on whether it's true or false. So it'll only execute b if a is true. Otherwise, it jumps to the false section, which returns false, short circuiting. However, there is a problem with that code in that it'll run the b command twice if they're both true. So and(a,b)(a?(b?(true):false):false) will both short circuit, and will only evaluate each variable once. It gets to the first test, a?, and checks a's value. a is not true, so it jumps to the false section, which returns false, never executing b. Another way of rewriting it would be if (a) { if (b) { return true } return false } return false
- dsp1234 11y agoHis function will short circuit. Not in JavaScript. This is prevented by 11.2.3(3) which specifies that a function call evaluates it's arguments, and which occurs before function evaluation. Note that the actual call to the function to have it's code run doesn't occur until 11.2.3(8), so by then the full arguments list has already been evaluated. Since this is part of the specification, it is not possible for a JIT to completely elide the argument evaluation unless it can prove that there are no side effects (which may or may not be something that individual engines do). "Let argList be the result of evaluating Arguments, producing an internal list of argument values (see 11.2.4)." "Return the result of calling the [[Call]] internal method on func, providing thisValue as the this value and providing the list argList as the argument values." This is also super easy to test: > and(false, console.log("This shouldn't run")) This shouldn't run false
- Sanddancer 11y agoOkay. I was testing it in C# where it does short circuit, and functions aren't called until the conditions require them to be called. This is also how the Kernel language seems to operate. I have...misgivings about javascript's pre-evaluation of functions.
- cyphar 11y agoC does the same thing. I didn't know C# followed the functional train all the way to lazy evaluation of arguments. But given the fact that C# isn't purely functional, that seems like a bad design decision.
- tyoverby 11y agoC# does not have lazy argument evaluation. Arguments are fully evaluated for each call.
- cyphar 11y agoYeah, I thought as much. Haskell and (some?) LISPs are the only languages I can think that actually advertise this (but there's probably others). C# isn't purely functional, so lazy argument evaluation would be a very wonky feature.
- qwertyuiop924 11y agoOnly functional lisps, and those are few and far between.
- Sanddancer 11y agoI had just realized that prior to coming back here. The example given would evaluate. I could probably do the same with some operator overloading to emulate lazy evaluation, but it would be a bit more complicated.
- 11y ago
- wtbob 11y agoThis is from the SBCL source, and I think it's pretty elegant: (defmacro and (&rest forms) (cond ((endp forms) t) ((endp (rest forms)) ;; Preserve non-toplevelness of the form! `(the t ,(first forms))) (t `(if ,(first forms) (and ,@(rest forms)) nil))))
- mst 11y agoRight, what's interesting about klisp is that you can define that as something that can be called at runtime, rather than having to be implemented as compile-time macro expansion. I sort of regard operative lisps as "lisp, but even more so", as it were (and for sheer brain melting power when prototyping weird logic they're even more fun than normal lisps, at least to me)
- qwertyuiop924 11y agoI just like them because fexprs are in some ways more elegant and easier to understand than macros.