Is there a recommended "intro to understanding lisp" resource out there for someone like myself to dive in to?
Is there a recommended "intro to understanding lisp" resource out there for someone like myself to dive in to?
(-> 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.Currying with OOP:
res = x
.mult(2)
.add(1)
.sub(3)
.mod(x)
Currying with assignment operators: res = x
res *= 2
res += 1
res -= 3
res %= x
Naming things instead of Currying: scale = 2
offset = 1 - 3
with_scale = x * scale
with_offset = with_scale + offset
result = with_offset % x
Or aping that in Scheme: (let* ((scale 2)
(offset (- 1 3))
(with_scale (* x scale))
(with_offset (+ with_scale offset)))
(remainder with_offset x)) '(
1. This is a list: ( ). Everything is a list. Data structures are all lists.
2. A program is a list of function calls
3. Function calls are lists of instructions and parameters. For (A B C), A is the function name, B and C are parameters.
4. If you don't want to execute a list as a function, but as data, you 'quote' it using a single quote mark '(A B C)
5. Data is code, code is data.)Practical Common Lisp - https://gigamonkeys.com/book/
Casting SPELs in Lisp - http://www.lisperati.com/casting.html
Structure and Interpretation of Computer Programs - https://mitp-content-server.mit.edu/books/content/sectbyfn/b...
One of many prior discussions here on HN: https://news.ycombinator.com/item?id=22913750
... amongst many resources for learning LISP.
https://www.braveclojure.com/clojure-for-the-brave-and-true/
(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.
(%
(-
(+ (* x 2)
1)
3)
x)
This makes the structure clearer, although it's still wasteful of space, and you still have to read it "inside-out". The thread macro version would be: (-> x
(* 2)
(+ 1)
(- 3)
(% x))
It's more compact, there's no ambiguity about order-of-operations, and we can read it in order, as a list of instructions:"take x, times it by 2, add one, subtract 3, take modulus with the original x".
It's pretty much how you'd type it into a calculator.
EDIT: care to explain the downvote?
Not only would that not be idiomatic, the operator for modulus in Common LISP is mod not %. and the brackets you and the parent used in the s-expr are around the wrong groups of symbols. So you're more likely to see:
(mod (* (+ 1 x) (- 2 3)) x)
or maybe with some limited indentation, such as:
(mod
(* (+ 1 x) (- 2 3))
x) (foo
(bar
(baz (bax x 2)
"hello")
"world")
"!")
>the brackets you and the parent used in the s-expr are around the wrong groups of symbolsNo they're not. Yours is wrong. Multiplication has higher priority than addition so the order of evaluation begins with (x * 2) not (1 + x).
OK, I shouldn't have gone that far.
FWIW, modulus has the same operator precedence as multiplication and division.
So really, it is more like:
(- (+ 1 (* x 2))
(mod 3 x))
or using the increment function:(- (1+ (* x 2))
(mod 3 x))(defn run-analysis [path]
;load data from converted arrow file
(let [data (load-data path)]
(-> data
;; Calc a Weeknumber, Ad_Channel, and filter Ad_Channel for retail
add-columns
;; Agg data by DC, Store, WeekNum, Item and sum qty and count lines
rolled-ds
;; Now Agg again, this time counting the weeks and re-sum qty and lines
roll-again)))
;;Run the whole thing(time (run-analysis arrow-path))
This code processes 27 million lines in 75 seconds (shout out to https://techascent.github.io/tech.ml.dataset/100-walkthrough... library)
(% (- (+ (* x 2)
1)
3)
x)This is the main thing I use Lisp (well, Guile Scheme) for. I used to use bc for little scratch pad calculations, now I usually jump into Scheme and do calculations. I don't recall if I thought it looked like gibberish at first but it's intuitive to me now.