News for hackers. Stuff that matters.
Re:JSX in detail by viebel on Friday September 08, 2017 @03:03AM (#15198358)
In LISP based languages like ClojureScript, macros are part of the language. No need to build tools like JSX (that requires to run on webpack + IDE tooling etc...).
Re:JSX in detail by ghusbands on Friday September 08, 2017 @05:29AM (#15198920)
In Lisp, if you created something like JSX, your IDE or text editor would still be unlikely to understand it, as it'd be a very complicated reader macro. It doesn't magically solve all macro problems.

Doing it the Lispy way, though, you'd likely use sexprs directly, with maybe some normal macros, so you wouldn't have HTML-like syntax but would have something that worked nicely in your editor.

Re:JSX in detail by shakna on Friday September 08, 2017 @09:30AM (#15199985)
SXML has been around a while, and makes working with HTML in most Lisps a breeze. See this for example [0].

    '((html (head (title "My Title"))
         (body (@ (bgcolor "white"))
               (h1 "My Heading")
               (p "This is a paragraph.")
               (p "This is another paragraph."))))
[0] http://www.neilvandyke.org/racket/html-writing/
Re:JSX in detail by davexunit on Friday September 08, 2017 @09:31AM (#15199990)
Lisp comes with a built-in templating system: quasiquote. Systems such as SXML (an s-expression representation of XML documents) build on top of that. This takes care of multiple problems with JSX: 1) writing HTML/XML is annoying (remembering to put the close tag in the right place, etc.) 2) JSX is a DSL, not an embedded DSL, so you need new compiler infrastructure to work with it.

Here is a snippet of real code that produces an SXML tree. It generates atom feeds for websites that use a static generator I wrote:

    `(feed (@ (xmlns "http://www.w3.org/2005/Atom"))
           (title ,(site-title site))
           (subtitle ,subtitle)
           (updated ,(date->string* (current-date)))
           (link (@ (href ,(string-append (site-domain site)
                                          "/" file-name))
                    (rel "self")))
           (link (@ (href ,(site-domain site))))
           ,@(map (cut post->atom-entry site <>
                       #:blog-prefix blog-prefix)
                  (take-up-to max-entries (filter posts))))
By far the best templating system I've ever used.
Re:JSX in detail by bananicorn on Friday September 08, 2017 @08:34AM (#15199684)
They work something like this in LISPs, right? Like, can you define new language constructs with them?

http://www.red-lang.org/2016/12/entering-world-of-macros.htm...

(BTW, have a look at red for desktop apps, it's not even at 1.0 and already fucking amazing)

But on topic; Are Macros a well-defined "thing"? Since a macro in C, seems to be rather different from a RED or LISP Macro.

Or is it just that C macros are essentially the same, just more restricted?

Re:JSX in detail by lmkg on Friday September 08, 2017 @11:29AM (#15200945)
C macros are text substitution, implemented in a separate less-expressive language (the C pre-processor).

Lisp macros access the input program fragment as structured data, and manipulate that using the same Lisp functions and data structures that you use for regular, normal Lisp code.

I think that both forms are technically Turing-Complete, but Lisp is more expressive. In particular, it's much more common to see Lisp macros that destructure and reform their inputs, where C macros tend to see their inputs as black boxes that can't be opened. The textual-substitution model of C also has some extra perils, because code fragments can be context sensitive (such as creating identifiers that are already in scope).

In both cases, Macros are well-defined "things" in the sense that they are thoroughly defined in their respective language documents, but in both cases they are not first-class language items because they don't exist at run-time.

Re:JSX in detail by amk_ on Friday September 08, 2017 @03:58AM (#15198612)
I could be wrong, but I don't think a LISP macro can transform the structure of the code in the same way that the JSX pragma turns an XML tree "inside-out". For example here's the source for the Babel JSX transformer:

https://github.com/babel/babel/blob/master/packages/babel-pl...

Re:JSX in detail by sbergot on Friday September 08, 2017 @04:05AM (#15198636)
A lisp macro see a code block as a tree of symbols/primitives. It can do anything. This means that it is easy to write a library with a nice dsl, but hard to read other people's code.
Re:JSX in detail by masklinn on Friday September 08, 2017 @06:02AM (#15199066)
> A lisp macro see a code block as a tree of symbols/primitives. It can do anything.

No, a regular macro still needs to be syntactically sensible. To handle arbitrary non-lisp syntax you need your lisp to support arbitrary reader macros (as in Common Lisp or — I believe — Racket) and that gets significantly more complex and involved and requires extensible/pluggable parsing.

Scheme does not have that for instance, SFRI-10 reader macros need to be wrapped in `#,()`, you can't just dump JSX or XML in Scheme source and expect it to work.

Re:JSX in detail by shakna on Friday September 08, 2017 @09:46AM (#15200075)
> Scheme does not have that for instance, SFRI-10 reader macros need to be wrapped in `#,()`, you can't just dump JSX or XML in Scheme source and expect it to work.

That's not 100% true.

See SRFI-105 which gives you infix expressions without needing to wrap them, and mixing and matching is supported the moment you dive into reader macros.

    #!curly-infix
    (+ 2 {a + b + c})
You do need to enable the reader modification, either in your own read (useful if you want safe eval, and parsing in limited environments), in which case you'd just provide an argument to read, or if you want it globally it'll probably just look like:

    #!jsx
    DOM.render(
      <h1>Hello world</h1>,
      document.getElementById((string-append "hel" "lo"))
    )
Writing the reader would be considerable work, but hardly impossible for Scheme to play nicely.
Re:JSX in detail by ghusbands on Friday September 08, 2017 @05:32AM (#15198937)
The usual macros in Lisp get all of the code as data, making rearrangement of the tree fairly trivial. For syntax changes, you'd use reader macros, which essentially involve writing a parser for all the parts that aren't Lisp. Once that's done, which is non-trivial, you would again have a tree to rearrange as you saw fit.

However, you'd be very unlikely to make something as syntactically heavy as JSX in Lisp. Lisp ethos is to keep the syntax as simple as possible, so it stays out of the way.

Re:JSX in detail by masklinn on Friday September 08, 2017 @03:42AM (#15198536)
JSX could be language-integrated (witness the now-deprecated E4X for XML literals in Javascript), it just is not.

And most lisps don't have unfettered reader macros which would allow embedding macros using non-lisp syntax (aka JSX).

A macroed JSX wouldn't make much sense in Lisps really, and AFAIK isn't used with most clojurescript vdoms using either hiccup structures or regular function calls.

Re:JSX in detail by viebel on Friday September 08, 2017 @03:56AM (#15198602)
who needs JSX when you have hiccup!
Re:JSX in detail by masklinn on Friday September 08, 2017 @05:58AM (#15199042)
Possibly a more uniform treatment of components versus "literal elements", but yeah the value proposition becomes very low.

In fact I'd argue the value proposition of JSX is already relatively low when you factor in hyperscript in regular javascript (and yes there are component-compatible hyperscript helpers for React).

Re:JSX in detail by lilactown on Friday September 08, 2017 @11:09AM (#15200774)
I think that Hiccup's idea of writing the tree as a tree-like data structure is superior to writing a tree of function calls.

I tried doing something similar in JavaScript; the result looks a bit silly (I realized the elegance of not needing to delimit lists with a , in LISP right here) and has questionable performance: https://github.com/Lokeh/hux