That's an interesting point about infix and postfix calculators but no prefix calculators. Though I wouldn't go so far to say there aren't any, I feel pretty sure I've seen one before--though don't care enough to go looking--they do seem pretty rare. I wonder what lisp/scheme/whatever-I-need-to-say-to-get-you-to-stop-being-pedantic would look like with post-fix evaluation.
I think it would be not that much better than prefix.
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.
Your argument amounts to "I know Python better than Lisp." And it may be true that because most languages and especially most popular languages are like Python that you have a head start. But it doesn't mean that Lisp is insensible or harder to read. It just means you have less experience reading it.
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.
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.)
I know it's not real code but I honestly find the second example way easier to read. It's indeed very common to use a 'let' like that and I don't see what's wrong with a "two spaces" indent (between your 'let' and the next 'if'). If you're talking about the indent after the 'let*' then, if anything, I think it makes the scope just so much more obvious.