Hacker News new | ask | show | jobs
by nordsieck 1159 days ago
> 1. It's functional! OK, well, all the higher order functions exist in Python, too, but in fact you wouldn't want to use them anyway because in Python you have list comprehensions, which, it turns out, usually leads to an even more readable solution.

My experience is that this is not the case.

Sure, list comprehensions are nice for simple things. But once they start getting complicated - for example nested iteration - they start to look fugly. This is a big reason why I strongly prefer ruby over python - I get access to reduce[1] which is substantially more powerful than map and filter. And the syntax for complex expressions stays easy to understand.

I get that that may not be a path that you want to travel, but for me one of the best parts of Clojure is all of the built in functional bits.

> 2. REPL-driven development! Python also has a REPL. True, it isn't the best REPL imaginable, but as far as I can tell it has feature parity with Clojure's! Both are missing the ability to fix errors live in a breakout REPL like you would find in a true LISP REPL.

If you like using the REPL and haven't tried it, ptpython is amazing. A huge upgrade over the default REPL.

> 3. Macros! Code is data! You can easily create your own DSL! OK, maybe. But actually, in Clojure I've gathered the impression that macros are looked down upon, a feature of last resort, unlike in other LISPs. I also can't recall ever using Python and wishing I could replace its syntax with a DSL, since it is already so expressive and flexible. But admittedly that might be a limitation with my own imagination and experience.

Another way to look at macros is that they make it possible to integrate the meta-programming environment - stuff like swagger API generators - into your coding environment.

---

1. Yes, I know that python has map, filter, and reduce. But they're all gimped by the way python implements lambdas. Which is sort of necessary due to meaningful whitespace. And I could just write regular functions instead, but it's not very ergonomic at that point. And it's also un-pythonic.

1 comments

> But once they start getting complicated - for example nested iteration - they start to look fugly.

Then don't do it. Un-nest them always. Simples.

> I get access to reduce[1] which is substantially more powerful than map and filter

Reduce is orthogonal to map/filter.

> Yes, I know that python has map, filter, and reduce. But they're all gimped

No they're not: map [x*2 for x in y], [x*2 for x in y if x > 3] (Syntax not tested, am a bit rusty so may be wrong). Okay, you're not providing a function as a parameter but most of the time with map and filter, that parameter is a constant function not a variable so I still hold this is true. Reduce would be nice as a comprehension, if that's possible.

> by the way python implements lambdas. Which is sort of necessary due to meaningful whitespace

I don't believe whitespace is the problem here. They could fix that pretty easily. I'm really unhappy with python's expression-only lambdas, they do suck.

> Then don't do it. Un-nest them always. Simples.

Sure, that's an option. It's also an option to only write for loops.

I'd prefer to do neither of those. And I get my way in languages that have ergonomic support for map, reduce, and filter.

> Reduce is orthogonal to map/filter.

Reduce is a superset of map/filter.

> No they're not: map [x2 for x in y], [x2 for x in y if x > 3]

I meant the actual map, filter, and reduce functions that are part of python, not list comprehensions that are, admittedly, a fusion of map and filter.

> Sure, that's an option. It's also an option to only write for loops.

I gave you a solution that solves readability and costs you nothing in performance, and you reject it without saying why. *shrug*

> Reduce is a superset of map/filter

Edit: you're saying that reduce can be abused into a map and a filter. Yes, okay I take your point.

[deleted]

> I meant the actual map, filter, and reduce functions that are part of python

I think you meant "not part of python", I guess I'd agree on that, but then again it's irrelevant. I don't care what mechanism you use to iterate over a list and apply a function to every item, whether it be a comprehension or a map function. The end result is the same, and I'd argue that comprehensions are, or can be, a little cleaner syntactically.

Comprehensions are part of python, the language. Map/filter/reduce as you've indicated, isn't, it's clearly a library.

In addition you previously complain that python doesn't have what you want "I get access to reduce... [in Ruby]" then prove that it does have it, so I don't see what you're saying.

> Clojure is all of the built in functional bits.

Are you saying map, filter, reduce are implemented in the core language and not an add-on library?

> Comprehensions are part of python, the language. Map/filter/reduce as you've indicated, isn't, it's clearly a library.

I guess, it's true that reduce is part of an included library. But map and filter are "built-in functions". I guess you could make a distinction between those and the language proper, but that's splitting some pretty fine hairs.

> In addition you previously complain that python doesn't have what you want "I get access to reduce... [in Ruby]" then prove that it does have it, so I don't see what you're saying.

Here's what I said:

"Yes, I know that python has map, filter, and reduce. But they're all gimped by the way python implements lambdas."

> Are you saying map, filter, reduce are implemented in the core language and not an add-on library?

If you look at the clojure cheetsheet[1], you can see all of the built-ins (most are functions, some are macros) that Clojure supports (as well as some included libraries).

map, filter, and reduce are all built ins. I strongly doubt that they're supported at the syntax level, but that's kind of lisp's shtick - even stuff like "+" is a built in function, and not "part of the language".

---

1. https://clojure.org/api/cheatsheet