So the correct S-exp (let's use mod for modulo rather than %):
(+ 1
(* x 2)
(- (mod 3 x)))
It's a sum of three terms, which are 1, (* x 2) and something negated (- ...),
which is (mod 3 x): remainder of 3 modulo x.
The expression (% (- (+ (* x 2) 1) 3) x) corresponds to the parse
((x * 2 + 1) - 3) % x
I would simplify that before anything by folding the + 1 - 3:
(x * 2 - 2) % x
Thus:
(% (- (* 2 x) 2) x).
Also, in Lisps, numeric constants include the sign. This is different from C and similar languages where -2 is a unary expression which negates 2: two tokens.
So you never need this: (- (+ a b) 3). You'd convert that to (+ a b -3).
Trailing onstant terms in formulas written in Lisp need extra brackets around a - function call.
The part that is confusing if you don't know Clojure is (->). This a thread macro, and it passes "x" through a list of functions.
So it basically breaks this down into a list of instructions to do to x. You will multiply it by 2, add 1 to it, take 3 from it, then do the modulus by the original value of x (the value before any of these steps).
Clojurists feel like this looks more readable than the alternative, because you have a list of transformations to read left to right, vs this
No stupid questions.. I keep getting similar feedback. I'll do a better job of explaining it.
To answer your question, it's taking a lisp-style syntax and turning it into a C-style syntax (specifically JavaScript- the output AST is actually a valid Babel AST)
(add 2 (subtract 4 2))
Into
add(2, subtract(4, 2))
Correct me if I'm wrong, but this is also attractive because it can be applied even to an "actual modulo" operator. That is, because "(x mod n + n) mod n" has the same behavior as the above, one need not even know which way a particular language's "%" operator behaves if one just always uses this filter.
In general, one solution is to just keep the original inputs around as necessary. So instead of x -> x mod 4, take the function x -> (x, x mod 4); the inverse is just (x, y) -> x.
The actual % operator in this language is defined as (x, y) -> (y, x / y, x % y), acting as a divmod. The + and - operators are defined as (x, y) -> (x + y, y) and (x, y) -> (x - y, y). And so on, making sure enough inputs are left on the stack to reconstruct the others.
:D That was my point, you can get there with other representations. It amuses me that Common Lisp lets me type that as 1/3. Such that (+ 1/3 1/3 1/3) gives the expected answer.
> &+, &-, &. They will perform additions, subtraction and multiplication with wrapping
It's definitely good that languages are adding this but it's a shame they didn't go for %+, %- and %. Some other language (I forget which) uses those and they are a lot more obvious in my opinion (because % means modulo pretty much everywhere and it is essentially a modulo operation).
There's no example the author gives that contradicts it, but it's not quite RPN. In Lisp, the + operator is variadic -- it can take any number of arguments. So in reverse-Lisp, this would be legal code:
Why should I learn this language that I've never heard of if it can't even do math in any sensible way? Not left-to-right, not order of operations, not lisp-like prefix. Who thought that was a good idea?
I think you've misunderstood. This does not take away any of those issues. With this setup, you can write (+ 1 2 3) or +(1 2 3) or (1 + 2 + 3) and they would all translate into (+ 1 2 3). You can treat any of them as a list. You can still parse, transform, do anything with it. There is no loss of functionality here. Think of it as a macro that aliases "plus" to +. There is no difference between (plus 1 2 3) and (+ 1 2 3) in a macro defined in this way. They are S-expressions under an invisibility cloak. But they're still S-expressions within.
Unfortunately our brains are broken by pemdas and need clear delineations to not get confused; this syntax also extends to multiple arguments and is amenable to nesting.
The expression (% (- (+ (* x 2) 1) 3) x) corresponds to the parse
I would simplify that before anything by folding the + 1 - 3: Thus: Also, in Lisps, numeric constants include the sign. This is different from C and similar languages where -2 is a unary expression which negates 2: two tokens.So you never need this: (- (+ a b) 3). You'd convert that to (+ a b -3).
Trailing onstant terms in formulas written in Lisp need extra brackets around a - function call.
reply