6 ms·
It's why JSX is such a god-send in React (and very rarely do people use string templates to produce HTML in React). String templates are much easier to read and
by ummonk 3y ago
It's why JSX is such a god-send in React (and very rarely do people use string templates to produce HTML in React). String templates are much easier to read and understand than nested function calls. If a language incorporates a safe readable HTML-generation feature akin to JSX, people will be much more enthusiastic about it.
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.
- MBlume 3y agoClojure's great for this too, I've never seen a Clojure programmer generating HTML with string templates and that's not because Clojure programmers are more disciplined, it's because Clojure's syntax is flexible/simple enough to make generating HTML in a structured way the natural solution. https://github.com/weavejester/hiccup https://github.com/weavejester/hiccup
- everforward 3y agoI think it's more that the syntax is fairly similar to HTML already. HTML is basically deeply nested lists with some attributes attached to the nodes, and lisp code is deeply nested lists with keywords replacing attributes. 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".
- alex-robbins 3y agoIn the context of this article, it's worth pointing out that hiccup doesn't escape strings automatically. Rum does, and I've been using it as a drop-in replacement: 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.) https://github.com/tonsky/rum https://github.com/tonsky/rum
- nawgz 3y ago> Python's list comprehensions are merely syntactic sugar for filter + map, but they make functional code so much more readable. Compared to what? Languages with actual filter & map generics seem far more legible to me than list comprehensions...
- the-alchemist 3y agoIt's a matter of comfort. 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 https://clojuredocs.org/clojure.core/for [1]: https://stackoverflow.com/questions/38987/how-do-i-merge-two-dictionaries-in-a-single-expression-in-python https://stackoverflow.com/questions/38987/how-do-i-merge-two... [2]: https://gist.github.com/SZanlongo/bc4baa90d3795db7c6ed7e8d4150f1de https://gist.github.com/SZanlongo/bc4baa90d3795db7c6ed7e8d41... [3]: https://stackoverflow.com/questions/23862406/filter-items-in-a-python-dictionary-where-keys-contain-a-specific-string https://stackoverflow.com/questions/23862406/filter-items-in...
- brundolf 3y agoWhat makes me upset about JSX is how it's build-time-dependent on whichever specific library you've configured it to translate to (and can't be used otherwise) 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
- eyelidlessness 3y agoIt certainly could be done for many use cases, it would probably be ~a superset of the various transformers’ ASTs. But that could add a fair bit of overhead to runtimes, particularly for transforms which deviate significantly from React’s tree structure (eg Solid’s underlying dom-expressions).
- aabbcc1241 3y agoYou can write custom jsx function and let typescript call your function instead of react's. 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
- brundolf 3y agoWhat I'd like is for it to have been a standard language feature, that can be used with or without a framework and without any build involvement
- wellanyway 3y ago[flagged]
- moritzwarhier 3y agoExactly. You made my comment unnecessary, but if I'm not wrong, JSX has proved this wrong 10 years ago: > 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.
- pxc 3y ago> E.g. Python's list comprehensions are merely syntactic sugar for filter + map, but they make functional code so much more readable. 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. ¯ \ _ ( ツ ) _ / ¯ -- 1: https://docs.python.org/3/tutorial/datastructures.html https://docs.python.org/3/tutorial/datastructures.html
- ummonk 3y agoI guess preferences vary but to me [x**2 for x in range(10)] is a lot easier to read at a glance than range(10).map(x -> x**2).
- stjohnswarts 3y agoHaskell always seemed like it was meant for the really mathematical subset of compsci that loves notation and that's why some of those who really love compsci love it.
- nequo 3y agoIncidentally, Haskell has list comprehensions so you could write [x^2 | x <- [1..10]] which looks about as legible as the Python version.
- emptysea 3y agoYeah I think having some a few more methods on some types would be nicer than having global functions like `map` 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
- maleldil 3y ago> Python's list comprehensions are merely syntactic sugar for filter + map, but they make functional code so much more readable. 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.