More generally, syntactic sugar matters a lot. E.g. Python's list comprehensions are merely syntactic sugar for filter + map, but they make functional code so much more readable.
More generally, syntactic sugar matters a lot. E.g. Python's list comprehensions are merely syntactic sugar for filter + map, but they make functional code so much more readable.
That is to say Clojure/lisp programmers are likely more familiar working with deeply nested lists of data.
You could write a very similar library in Python if you wanted using lists, I'm just doubtful anyone would use it because it's not "Pythonic".
user> (require '[rum.core :as rum]
'[hiccup.core :as hiccup])
nil
user> (rum/render-static-markup [:p "<script>alert('you have been pwned')</script>"])
"<p><script>alert('you have been pwned')</script></p>"
user> (hiccup/html [:p "<script>alert('you have been pwned')</script>"])
"<p><script>alert('you have been pwned')</script></p>"
(Note that Rum is also a React wrapper, but you don't have to use that part of it; you can simply use it for static rendering of HTML.)More readable than filter/map/reduce _in Python_, because Guido dislikes them and wanted them out of the language (and succeeded in moving reduce to functools). Python's excuse for lambdas makes this so much worse.
Compared to functional languages, though? I'll take filter/map/fold/reduce from Haskell or Clojure versus list comprehensions any day.
Imagine if JSX produced a standard data structure that could then be
- Rendered by React or another framework
- Serialized to a string
- Deeply inspected/compared
etc. And framework integration only happened when you make the actual framework call, not globally at build-time
Your custom jsx function can return data in reusable format, that is passed to different functions for difference use case.
ts-liveview is using this approach to use jsx for both server-side rendering and compact over-the-wire updates
Compared to what? Languages with actual filter & map generics seem far more legible to me than list comprehensions...
I was doing imperative programming for years, and more functional now.
You've got for loops, list comprehensions, newer dict comprehensions, map/filter, generators, etc. in Python.
Python programmers tend to prefer for loops and comprehensions. List comprehensions, especially, dict comprehensions being much newer.
Living mostly in the pre-Java 8 Java world, I used for loops as much as the next guy, like the rest of the Java world. But I really liked list comprehensions. And then Java got streams and map and filter, etc., and wow, I loved it. Even most Java programmers started embracing the new "functional" paradigms.
Now that I've been both (and its more powerful cousins in Clojure), I'd say map/filter are "more readable". It depends on the implementation too: try merging two dictionaries in Python, ugh [1] [2]. Awkward any way you slice it. Watch out what version of Python 3.x you have! Watch the order of arguments, and some variations modify in-place! You're also never sure if your result will be a list or a dict.
Try map'ing a dict in Python: don't, it's not worth it [3]. These things are actually pretty easy, even in Java, let alone Clojure.
For the record, Clojure has map/filter and list comprehensions (called for comprehensions, and they're even more powerful than Python because they can terminate early [0]).
So, yes, in Python, map/filter can often be a pain. They were afterthoughts, and less readable than the alternatives. For languages with powerful map/filter and friends, these functional equivalents are much more flexible and readable. And it appears that most people that are familiar with both prefer the functional variety.
[0]: https://clojuredocs.org/clojure.core/for
[1]: https://stackoverflow.com/questions/38987/how-do-i-merge-two...
[2]: https://gist.github.com/SZanlongo/bc4baa90d3795db7c6ed7e8d41...
[3]: https://stackoverflow.com/questions/23862406/filter-items-in...
> No one has structured HTML creation that's as easy as string templates.
Well, maybe it's about the "easy" part, maybe the author considers JSX string templates. I assume the former, because the latter would be absurd.
The advantages of so-called frontend "frameworks" such as React et al is 50% this point. Also a reason for Lit's subjectively slow adoption.
Can't say I agree. Maybe it's because I worked with simple functional programming primitives like filter and map before I ever really worked with Python, but I find Python list comprehensions weirder and harder to read than things like Clojure's thread macros, Ruby blocks, or even just chaining functional method calls together using the normal dot syntax in Java or Scala.
They do look better than the equivalents shown in the official Python documentation¹:
squares = list(map(lambda x: x**2, range(10)))
but that is exceptionally hideous and not what I'd consider a normal way to write functional code for dealing with collections or streams.Seems like a Python workaround for a Python problem to me. ¯ \ _ ( ツ ) _ / ¯
--
[x^2 | x <- [1..10]]
which looks about as legible as the Python version.for example, imagine if your example could be written as:
range(10).map(lambda x: x*2).list()
but as a list comprehension it's slightly shorter, but autocomplete isn't as good:
[x*2 for x in range(10)]
Also some historical context, Python's list comprehension are based on Haskell's
I do also find the comprehensions more readable when one is actually using all of their components, i.e., when the function in the map behind the sugar would not be the identity function. But occasionally, when all the author really wanted to do is filter, you'll see stuff like
[x for x in ... if ...]
and that always strikes me as a bit weird and unfortunate.> Also some historical context, Python's list comprehension are based on Haskell's
I didn't know that! I do kinda like Python's preference for English keywords over arrows here, even though the Haskell syntax is more concise or whatever.