Live data from Hacker News

Writing HTML with Racket and X-Expressions (2019)

xy2.dev

11–20 of 30 posts

Re: Writing HTML with Racket and X-Expressions (2019)

#11
post #9

I don’t get why templates are such a pain? > We've lost a lot of expressiveness: what if we wanted to create a nested list again? We could make it a template macro, but we have to do extra work to call it inside itself, and suddently we have an extra language to learn. Not that I’ve used jinja aside from some Ansible, I don’t get the second language part for templates or why templates are limiting? Even React’s synta…

> Even React’s syntax really isn’t that different from a template as you need to enclose JS expressions in curly braces right?

The difference is that they're real, actual JS expressions evaluated in the current scope. Anything you can express in JavaScript you can express in JSX without needing to learn anything new.

Re: Writing HTML with Racket and X-Expressions (2019)

#12
RE first Python example:

> But this approach is a little limited. We end up manipulating strings around, instead of a proper data representation for HTML.

That applies even more to the template example. Template engines are gluing strings, and shouldn't be used for the same reason the first example shouldn't - there's a language mismatch. HTML is a tree. By treating it as a series of glued strings, it's easy to generate syntactically invalid HTML, which opens you up for XSS problems. It's the exact same problem that led to SQL injections in the past, and why people use parametrized queries now.

The X-Expressions solution, i.e. generating HTML from a tree structure, is the correct one.

Re: Writing HTML with Racket and X-Expressions (2019)

#13

RE first Python example: > But this approach is a little limited. We end up manipulating strings around, instead of a proper data representation for HTML. That applies even more to the template example. Template engines are gluing strings, and shouldn't be used for the same reason the first example shouldn't - there's a language mismatch. HTML is a tree. By treating it as a series of glued strings, it's easy to gener…

> HTML is a tree

I'm not disagreeing in general, but this is reductio ad absurdum. The original formulation of HTML as an SGML vocabulary has very specific formal rules about the kind of escaping needed in a particular context. Not to mention empty/void elements and tag omission/inference. SGML, since its beginning, has entity references which do have types informing about how they can/must be expanded in a given context. The problem is that template "engines" (except SGML proper and very few HTML-aware ones) want to use ad-hoc "${...}" syntax and treat HTML/SGML as an unstructured text string.

Re: Writing HTML with Racket and X-Expressions (2019)

#14
post #11
post #9

I don’t get why templates are such a pain? > We've lost a lot of expressiveness: what if we wanted to create a nested list again? We could make it a template macro, but we have to do extra work to call it inside itself, and suddently we have an extra language to learn. Not that I’ve used jinja aside from some Ansible, I don’t get the second language part for templates or why templates are limiting? Even React’s synta…

> Even React’s syntax really isn’t that different from a template as you need to enclose JS expressions in curly braces right? The difference is that they're real, actual JS expressions evaluated in the current scope. Anything you can express in JavaScript you can express in JSX without needing to learn anything new.

Ah, I keep forgetting Jinja expressions can't be real Python. That makes more sense. So really this article is relevant to only full template languages or non-functional languages. edit: Looks like [Selmer](https://github.com/yogthos/Selmer) is similar to EEx in the Clojure world.

Re: Writing HTML with Racket and X-Expressions (2019)

#15
post #6
post #5

Earlier quoted context omitted.

The Hiccup notation in the Clojure world (eg Reagent) works well, and it doesn't need macros. You're still left with some quoting (for text inside elements and attributes), but in practice most of these come from non-constant values in code. (defn simple-component [] [:div [:p "I am a component!"] [:p.someclass "I have " [:strong "bold"] [:span {:style {:color "red"}} " and red "] "text."]])

Not a fan. Given that in a template context the first atom will always be a symbol, all the : is just redundant. I despise visual noise.

The `:` is not visual noise, it indicates that it is a keyword. Without it, you're indicating that you're writing a symbol. Symbols are evaluated, so keywords is a better choice given that they always are what they say they are, whereas you could define `div` to mean `

`, point to a function, or any number of other things.

You could write a macro to use symbol names literally, so that `div` always means ``, but then you'd have a macro where none was needed, and you'd have no obvious way of using symbols in a non-literal/evaluated way.

Fulcro[1] lies little closer to what you're after. The above would be:

  (div 
    (p "I am a component!")
    (p :.someclass
       "I have " (strong "bold")
       (span {:style {:color "red"}} "and red") "text."))
This is since Fulcro defines the element tags as functions, which are called in order, rather than as a data structure that's interpreted (a la Hiccup).

The immediate and obvious benefit of Hiccup over the function hierarchy is that Hiccup can be trivially (and safely) seralized/deserialized.

1: https://github.com/fulcrologic/fulcro

Re: Writing HTML with Racket and X-Expressions (2019)

#16

RE first Python example: > But this approach is a little limited. We end up manipulating strings around, instead of a proper data representation for HTML. That applies even more to the template example. Template engines are gluing strings, and shouldn't be used for the same reason the first example shouldn't - there's a language mismatch. HTML is a tree. By treating it as a series of glued strings, it's easy to gener…

> HTML is a tree I'm not disagreeing in general, but this is reductio ad absurdum . The original formulation of HTML as an SGML vocabulary has very specific formal rules about the kind of escaping needed in a particular context. Not to mention empty/void elements and tag omission/inference. SGML, since its beginning, has entity references which do have types informing about how they can/must be expanded in a given co…

So with entity references, I guess it's a DAG then, with extra idiosyncratic grammar. That doesn't change my main point: it's a structured language. Expressions in a structured language should be built up through an API that reflects that structure, and thus maintains the structural correctness of constructed expression at all times. Not by gluing arbitrary strings together.

Re: Writing HTML with Racket and X-Expressions (2019)

#17

Earlier quoted context omitted.

> HTML is a tree I'm not disagreeing in general, but this is reductio ad absurdum . The original formulation of HTML as an SGML vocabulary has very specific formal rules about the kind of escaping needed in a particular context. Not to mention empty/void elements and tag omission/inference. SGML, since its beginning, has entity references which do have types informing about how they can/must be expanded in a given co…

So with entity references, I guess it's a DAG then, with extra idiosyncratic grammar. That doesn't change my main point: it's a structured language. Expressions in a structured language should be built up through an API that reflects that structure, and thus maintains the structural correctness of constructed expression at all times. Not by gluing arbitrary strings together.

Except that HTML/SGML is a format invented for authoring and delivering semistructured text. At the risk of sounding arrogant, the idea is to have domain experts (rather than programmers) create stand-alone documents that can then be rendered and type-checked, can be refined by web developers using text macros, page boilerplate, transformations/stylesheets, and script, and that can (but don't have to be) used for rendering dynamic content from markup or other sources such as services and/or databases, while remaining self-standing, autonomous, type-checkable documents in a larger workflow.

Re: Writing HTML with Racket and X-Expressions (2019)

#18
I think the power of X-expressions would have been better demonstrated with a function that manipulates an HTML tree after creation, which is something you don't really want to do if your HTML tree is represented by a big string rather than an actual tree.

Re: Writing HTML with Racket and X-Expressions (2019)

#19
post #5
post #2

The idea is right, but all the 'quoting and explicit list calls make this super awkward. If you're going to do it, do it right... use macros. Of course, then you'd end up something that looks a lot like Haml ( http://haml.info/ ) with parens everywhere.

The Hiccup notation in the Clojure world (eg Reagent) works well, and it doesn't need macros. You're still left with some quoting (for text inside elements and attributes), but in practice most of these come from non-constant values in code. (defn simple-component [] [:div [:p "I am a component!"] [:p.someclass "I have " [:strong "bold"] [:span {:style {:color "red"}} " and red "] "text."]])

This is probably one of the major things that Clojure gets right (ignoring EAVT databases) that no one copies

You don't need a CSS preprocessor if you can manipulate your CSS using the standard data manipulators in your given language, this applies to so many DSL languages like HTML, CSS, SQL, Clojure has Hiccup, Gardern and HoneySQL respectively

Here's a PHP SQL port I've been working on https://github.com/slifin/moonlight (keywords removed for ergonomics but it did lose power when I did that)

If a third party gives you a stringy language to work with you gain power back by creating a data representation, operating on that then converting it back to string at the execution point

In the case of PHP we took the Java route and put everything into objects: https://github.com/zendframework/zend-db, the amount of code required to do that is almost comical when compared, Zend DB also suffers from a lot of bugs/lack of features compared to honeySQL which is about 5 files of data orientated code: https://github.com/jkk/honeysql

I should mention Zend DB is not an outlier here for bulky code have a look at other PHP query builders they're all impenetrable

Re: Writing HTML with Racket and X-Expressions (2019)

#20
post #2

The idea is right, but all the 'quoting and explicit list calls make this super awkward. If you're going to do it, do it right... use macros. Of course, then you'd end up something that looks a lot like Haml ( http://haml.info/ ) with parens everywhere.

You can avoid parens and have some fun building up HTML with combinators.

  > numbers n = docTypeHtml $ do
  >     H.head $ do
  >         H.title "Natural numbers"
  >     body $ do
  >         p "A list of natural numbers:"
  >         ul $ forM_ [1 .. n] (li . toHtml)
https://jaspervdj.be/blaze/tutorial.html
Post reply on HN