Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

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.



Clojure'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


In 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>&lt;script&gt;alert(&#x27;you have been pwned&#x27;)&lt;/script&gt;</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


I 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".


> 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.


What 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


It 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).


You 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


What 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


> 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...


It'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

[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...


Exactly. 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.


> 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


Yeah 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


For whatever reason, having just the global functions feels more natural to me in Lisps, but weirder where function names precede the opening parentheses.

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.


I 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).


Haskell 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.


Incidentally, Haskell has list comprehensions so you could write

  [x^2 | x <- [1..10]]
which looks about as legible as the Python version.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: