Infix is easier to read, because it is just more natural to parse. An expression like:
sin(1 + (5 + x + y) / (n + k)) is just really easy to understand
(sin (+ 1 (/ (+ 5 x y) (+ n k))) is inscrutable, at least to me.
The second thing is, intermediate variables makes code much more readable, but lisp strongly discourages this. The only way to create a lexical variable is with LET. But this causes indenting, which is pretty ugly. In fact, the use of indenting for both logical nesting and variable creation is a really nasty thing:
so this:
def qualifies_for_free_shipping(item_price, weight, shipping_factor, category):
if category is in FREE_SHIPPING_CATEGORIES:
return True
item_cost = item_price * TAX_RATE
shipping_cost = weight * shipping_factor + 2.00
total_price = item_cost + shipping_cost
if item_cost >= 80:
return True
if total_price >= 100 and category in ELECTRONICS_CATEGORIES:
return True
return False
becomes, in some lisp dialect I am making up but is like common lisp (defun qualifies-for-free-shipping (item-price weight shipping_factor category)
(if (in category FREE_SHIPPING_CATEGORIES)
t
(let* ((item-cost (* item-price TAX-RATE))
(shipping-cost (+ (* weight shipping-factor) 2))
(total-price (+ item-cost shipping-cost))
(if (>= item-cost 80)
t
(if (and (>= total-price 100) (in category ELECTRONICS-CATEGORIES))
t
nil)))))
I could have cleaned up the code and used a better conditional than nested if's or something, but this is my point. I can't just glance at the code and see what is going on, I have to parse it and keep track of where I am as I move around the s expressions. In the python version I can just jump in the middle and move around without keeping a mental bookmark, because I always know from indentation how I can get to where I am now.I say this as a decent Haskell programmer, and a very poor Lisper. There was a time I found Haskell code so unbelievably befuddling I thought it was a prank. Now I know it, so I know what to expect and I can read it as easily as Java. Lisp remains harder for me, like you, but it's a matter of practice.
So YMMV.
(sin (+ 1 (/ (+ 5 x y)
(+ n k))))
Similarly, your Lisp could be reformatted to something like: (define (qualifies-for-free-shipping item-price weight shipping-factor category)
(let* ((item-cost (* item-price TAX-RATE))
(shipping-cost (+ (* weight shipping-factor) 2))
(total-price (+ item-cost shipping-cost)))
(cond ((in category FREE-SHIPPING-CATEGORIES) #t)
((>= item-cost 80) #t)
((and (>= total-price 100) (in category ELECTRONICS-CATEGORIES)) #t)
(else #f))))
I think you’re trying to use Lisp as if it were Python, and that’s going to make things more difficult for you than they need to be.(A lot of my college classmates ran into trouble in a class where we programmed in Scheme [since renamed to Racket] because they tried to use it like Java, the standard curriculum language. If/when they grokked Scheme, they became just as proficient in it as they were in Java, but until they did they spent a lot of time effectively complaining about how Scheme wasn’t Java.)