Hacker Read top | best | new | newcomments | leaders | about | bookmarklet login

It is gibberish. The expression means:

  (1 + (x * 2)) - (3 % x)
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.



sort by: page size:

  (-> x (* 2) (+ 1) (- 3) (% x))
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

  (% (- (+ (* x 2) 1) 3) x)
Which is the most unreadable of them all, to me.

If the language has no operator precedence then

  1+x*2-3%x
is just as easy if not easier to decipher compared to both of your other examples imo. The above is equivalent to

  (1+(x*(2-(3%x)))) 
in APL/j/k. You get used to it pretty quickly.

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))

> (x rem n + n) rem n

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.


CORRECTION: `+(a,*(b,c),1)` is NOT like LISP code. However, Julia helps you to get the head of an expression (in this case, +) and it's args.

> In math ( * ) is a binary operation.

https://en.wikipedia.org/wiki/Empty_product

I am talking about Empty Product.

In all Lisps I know ( * ) returns 1, (* n) returns n. Which makes sense.

Shen's example is confusing for me.


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.


Math expression: a(8b^2+1)+4bc(4b^2+1)

In LISP: (+ (* a (1+ (* 8 b b))) (* 4 b c (1+ (* 4 b b))))

Oh, that silly operator precedence, lets just jam our heads in a vice while we unravel the nesting.


: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.

This isn't without drawback, of course.


> &+, &-, &. 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:

  (3 4 2 +)

Properly used, it's just a short-hand for small expressions, where adding formally declared parameters adds 50% or more bulk to the code.

  {|a, b| a + b}  versus {@1 + @2}
type of thing. Note also that a and b are not more informative than @1 and @2.

Both these examples convey one message: "I'm a function that adds two arguments".

Here is a useful power: omit the smaller numbers:

  # TXR Lisp:
  5> (mapcar (aret @3) '((a n 1 10) (b m 2 20)))
  (1 2)
  6> (mapcar (aret @2) '((a n 1 10) (b m 2 20)))
  (n m)
aret: a)pply list to function, which ret)urns an expression.

Simply by using @20, we get a twenty-argument function with 19 don't-cares.


You left out the more common options:

    (1 + x * 2 - 3) % x
and

    (1 + (x * 2) - 3) % x
both are clearer than the S-expression in my opinion

On any sane ML-style language, it would be this:

    (fibonacci it) - 1 + (fibonacci it) - 2
But I guess it isn't the case here, because that code doesn't make sense.

/ Right to left precedence:

3*2+5 / yields 21

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.

> (Side note: Clojure's `>` and `<` are kind of unreadable to begin with.

I felt the same for awhile but now I just mentally put the operator between the operands, so (> 3 2) is the same as 3 > 2.


My preferred version of this:

x.*(2).+(1).-(3).%(x)

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.


That's some Lisp code; if you enter it at a REPL, it prints the result of evaluating it:

    CL-USER> (defun add (a b) (+ a b))
    ADD
next

Legal | privacy