7 ms·
I find that both are equally (un)readable. However, for expressions that are that long, I'm inclined to write: (setv result (-> (+ 1 3 88)
by mthomas 9y ago
I find that both are equally (un)readable.
However, for expressions that are that long, I'm inclined to write:
(setv result (-> (+ 1 3 88)
(/ 2)
(- 8)))
- deleted 9y ago[deleted]
- jamescostian 9y agoI am not a lisper, but that looks pretty cool. The non-lisp ways of writing that would either require adding parens like GP or writing things like "result /= 2", but that means repeating "result" or whatever variable many times.
- cle 9y agoThis is even better than in-fix notation.
- lliamander 9y agoIndeed, I like that better than either typical prefix or infix nested expressions. What do you advise in the case the expression tree is a little bit more complex? For example: (setv result (- (/ (+ 1 3 88) 2) (* 8 (+ 3 2)))
- mthomas 9y agoI don't see any clever way to make that more readable. I would have to break it into two subexpressions and then take the difference. i.e. (setv e0 (-> (+ 1 3 88) (/ 2))) (setv e1 (-> (+ 3 2) (* 8))) (setv result (- e0 e1))
- kazinator 9y agoBTW doesn't setv support multiple pairs? (setv e0 (-> (+ 1 3 88) (/ 2))) e1 (-> (+ 3 2) (* 8)) result (- e0 e1)) like setq and setf in CL.
- jlarocco 9y agoBecause the operators all take a list of values it's sometimes convenient to format them like any other long list, with each nested sub-expression on its own line to form a tree: (setv result (- (/ (+ 1 3 88) 2) (* 8 (+ 3 2))) Another possibility is to use a (let ...) to give nested values temporary names, like: (setv result (let ((first (/ (+ 1 3 88) 2)) (second (* 8 (+ 3 2)))) (- first second))) It helps if "first" and "second" have meaningful names like "velocity" or "force" that can describe what they are.
- lliamander 9y agoAlso, I've seen lisps that obviate the need for the outermost parentheses (I think by using significant whitespace). In that case, the above example would have as many parens as the python example (for those who are keeping count).
- btschaegg 9y agoStill being an absolute beginner at lispy syntax, I'll have to ask you the same question though. While I see the awesomeness in threading macros, I'm usually left pondering a while on where the result actually goes in the next s-expression. How long did it take you to get used to that? Would you prefer someting like `as->` for readability?
- klibertp 9y agoI thought it's a simple mnemonic: -> means inserting the form just after the beginning of the next one, while ->> inserts at the end of it. You most certainly can have explicit variable to thread through expressions, like this: (it-> (form1 it) (form2 3 it 4) ...) where it means "previous expression". I think there's a Clojure library which already implements this. You can use that if you want.
- serpix 9y agoin Clojure this is achieved with `as->`
- baldfat 9y agoIn Racket we actually have a threading macro with ~> This: (- (bytes-ref (string->bytes/utf-8 (symbol->string 'abc)) 1) 2) Becomes this: (~> 'abc symbol->string string->bytes/utf-8 (bytes-ref 1) (- 2)) https://docs.racket-lang.org/threading/index.html https://docs.racket-lang.org/threading/index.html
- peatmoss 9y agoI believe the use of "~>" rather than "->" in Racket was set in #lang rackjure which adds in some of the Clojure syntax to Racket. Also amusing is their explanation: > For example the threading macros are ~> and ~>> (using ~ instead of -) because Racket already uses -> for contracts. Plus as Danny Yoo pointed out to me, ~ is more "thready". http://docs.racket-lang.org/rackjure/index.html#%28part._.Background_philosophy%29 http://docs.racket-lang.org/rackjure/index.html#%28part._.Ba... More thready indeed :-p