
HTML as a programming language – unifying HTML with Erlang - rubiquity
http://joearms.github.io/2015/03/16/HTML-As-A-Programming-Language.html
======
escherize
I personally prefer using data structures as html as long as I can, then
rendering the html to a string at the last moment. This has the advantage of
being able to use the entire programming language on the html-y data.

In Clojure there are a bunch of tools for doing this. One is hiccup, it's for
server side html rendering. You can define a function that returns a Clojure
datastructure like so:

    
    
        (defn greeting [person] 
            [:h2 (str "Hey, " person)])
    

Then:

    
    
        (greeting "Paul")
        ;=> [:h2 "Hey, Paul"]
    

and:

    
    
        (hiccup/html (greeting "Paul"))
        ;=> "<h2>Hey Paul</h2>"
    

There are also tools for doing this in clojurescript. My favorite here is
called Reagent ([http://reagent-project.github.io/](http://reagent-
project.github.io/)). It's a minimal wrapper for react.js that appeals to me
because I can focus on my code since there's less to know compared to Om.

~~~
elliotec
Do you use hiccup as well as Reagent? Or must you commit to one or the other?
Which do you prefer?

~~~
escherize
People use 'hiccup syntax' to mean the [:h2 "okay"] style of datastructures.
Hiccup is actually the name of the (first?) clojure library that parses

    
    
        [:p.tall "hi"] 

into:

    
    
        <p class="tall">hi</p>

.

Reagent is a clojurescript library that lets one write a Single Page App as
clojure datastructures. Most of what reagent does is take a function that
returns 'hiccup syntax' and turns it into a react.js component. One can also
create components using Reagent by hooking into the :component-did-mount
events.

------
jasim
_Any sufficiently complicated templating language contains an ad hoc,
informally-specified, bug-ridden implementation of a turing complete
programming language._

Segregating views from code was reasonable when most of our sites were mostly
content. The occasional need for logic can be satisfied by string
interpolation to run a programmable expression. Which is exactly what the old
crop of templating languages have been doing.

However, this paradigm doesn't suit web-apps. A web-site can be thought of as
a programmatically _enhanced_ view, but a web-app is a programmatically
_constructed_ view. Construction calls for abstractions. We can either port
back programming abstractions in the form of helpers and directives into
templates, giving rise to innumerable templating languages with custom syntax
and innumerable quirks
([http://en.wikipedia.org/wiki/Comparison_of_web_template_engi...](http://en.wikipedia.org/wiki/Comparison_of_web_template_engines)),
or we could simply use code, the best tool for the job.

This is exactly what JSX does: it enhances code to be able to parse XML views,
which helps us write well-organized front-end code with all the abstractions
that only a programming language can provide.

~~~
pjmlp
Yes, but this stems from the fact, that people continue to bend the whole
stack for what it wasn't designed to be in first place.

~~~
zenojevski
Sorry, but this is a trite argument.

It's visible to everyone that "the stack" is being rethought in that direction
since DHTML became a thing (which was many, many years ago).

It does not matter much that it was not originally designed this way. it
_does_ work, it is still mostly backwards compatible. I could build an app in
react today that works on both Chrome 40 and Mosaic (`NCSA_Mosaic/2.0`). I
could switch set of views, add a transform in front of the virtual dom engine,
replace the vdom entirely, render to canvas and then send images + linkmaps
(so '90s), because the technology is so versatile yet simple.

The document model, in all its simplicity, with its elements and hyperlinks,
has allowed us to build an enormous, completely new market for services with
relatively few costs, that has been malleable enough to work on basically
every device, use-case, etc. We stream video with it, process payments, we
connected the whole world with it (people! not hosts).

It's like the old "if only unix weren't there". But of all the things that
were launched on the wall, only unix stuck. Like the vhs, like the linux
kernel, like tcp. It's obvious that despite not being technologically
superior, there were benefits to all these in practice.

------
malisper
Hacker News is actually written in a similar way[0]. Here is the code to
generate the lists page[1] (the code is a bit outdated):

    
    
      (newsop lists () 
        (longpage user (msec) nil "lists" "Lists" "lists"
          (sptab
            (row (link "best")         "Highest voted recent links.")
            (row (link "active")       "Most active current discussions.")
            (row (link "bestcomments") "Highest voted recent comments.")
            (row (link "noobs")        "Submissions from new accounts.")
            (when (admin user)
              (map row:link
                   '(optimes topips flagged killed badguys badlogins goodlogins)))
            (hook 'listspage user))))
    

[0]
[https://github.com/wting/hackernews/blob/master/news.arc](https://github.com/wting/hackernews/blob/master/news.arc)

[1] [https://news.ycombinator.com/lists](https://news.ycombinator.com/lists)

------
vonklaus
I have always found something really off putting about mixing html with
programming languages. Whether it be HAML or Rails or really anything. I like
the separation of concern, and modularity of building an application that has
files and folders for each feature or usecase. HTML is simple markup to
semantically explain pieces of the web page. Dynamic features should be
applied from their own folders and files and not mixed into some massive
frankenstein file. It is messy, not semantic, difficult to debug and creates
problems for other aspects of your application (DOM targeting, Styling etc.)

~~~
amelius
Totally agree. And actually, I find HTML in itself too verbose to begin with.
Why require those close tags? So that one can see what tag is being closed?
That is stupid, because in most cases, we're using just a few tags (DIV, SPAN)
anyway, so this gives very little information. I'd rather use real open and
close braces like most data-structures in modern programming languages.

~~~
talmand
Sometimes seeing the closing tag is rather useful for the very reason you
mention, to know which tag is closing. The simple fact that once it was
popular to use a comment to identify the id or class of the closed element at
the bottom of a long file suggests it's a problem to consider.

~~~
amelius
But nowadays, the behavior of an element can be completely styled by CSS. So
in most code, you will find a lot of DIVs. And imagine having 10 DIVs nested:
you can't possibly tell by looking at the closing DIVs which DIVs they are
closing... Unless perhaps you put also the classname on the closing tag (which
isn't allowed or enforced or verified). So, as you can see, the closing tag
has very little utility. It only makes the code less readable (as it takes
space). And also, but this is secondary, it requires more bandwidth.

~~~
talmand
Well, first I would say that if somebody has ten nested DIVs then they're
doing it wrong. But if the DIVs are formatted properly then it's usually not
that hard to find the matching start tag. As for the class in the closing tag,
that's what my statement about people putting comments with the closing tag is
referring to. It's been done and was quite popular at one time. I'm willing to
bet our editing tools fixed that problem simply by highlighting matching
element pairs.

But in the end, if HTML went with <div></> instead of <div></div> then I
probably wouldn't mind so much. But I can't agree that no closing tag is more
readable because it takes less space, that makes no sense. It might look
better.

I would be curious about bandwidth savings but I'm willing to bet in most
cases it would make very little difference.

------
spankalee
I'd much rather just use custom elements:

Assuming a library that makes declaring custom elements very easy[1]:

one.html:

    
    
        <template is="quick-element" name="one-lorem">
          Lorem ipsum dolor...
        </template>
    

two.html:

    
    
        <link rel="import" href="one.html">
    
        <one-lorem></one-lorem>
    

[1]: [https://github.com/Polymer/core-
focusable/blob/0.8-preview/d...](https://github.com/Polymer/core-
focusable/blob/0.8-preview/demo/quick-element.html)

~~~
e12e
I always liked some of the ideas from Zope/Plone's template language,
specifically the TAL (most basic) bit. When one adds macros/includes, some of
the benefits fades a bit away: but it's nice to be able to have templates that
can be rendered as-is in browsers, with a meaningful preview:

    
    
        <html>
        <!-- ... you'd need to include static css etc --!>
        <table>
          <tr tal:repeat="item here.cart">
            <td tal:content="repeat.item.number">1</td>
            <td tal:content="item.description">Widget</td>
            <td tal:content="item.price">$1.50</td>
          </tr>
        </table>
        </html>
    

[https://chameleon.readthedocs.org/en/latest/reference.html#b...](https://chameleon.readthedocs.org/en/latest/reference.html#basics-
tal)

With html5 one gets some of the same benefits for free -- I guess the basic
insight is to allow there to be demo/dummy content that can be rendered as/is
valid html(5) -- and have the templating system replace it gracefully.

Also of some interest is the xml/xsl-based theming support for Plone, allowing
taking standard html, add a few rules, have diazo write the xsl -- and use the
html (content and all) as a template:

[http://docs.diazo.org/en/latest/index.html](http://docs.diazo.org/en/latest/index.html)

[http://www.treebrolly.com/blog/turbo-plone-theming-with-
xdv-...](http://www.treebrolly.com/blog/turbo-plone-theming-with-xdv-diazo)

[http://www.uwosh.edu/ploneprojects/docs/how-tos/how-to-
use-d...](http://www.uwosh.edu/ploneprojects/docs/how-tos/how-to-use-diazo-to-
copy-another-sites-theme)

(Note this is actually mixing up two different types of templating, even if
both do text-substitution. One is more of the "string interpolation/macro
expansion" (aka you could just have used m4 to make the html) -- and the other
is more themeing related: twisting appearances while semantics stay the same.
They're conflated mostly because semantic html mark-up doesn't a) quite work
and b) isn't actually supported by CSS (independent of semantics, because
structure confers meaning in html, so with different structure, comes a need
to either morph the structure (diazo) or rewrite (parts of) the CSS.

The new way to side-step this issue, is to rather than standardize on
good/sensible html-markup (aka: the zen garden approach that has worked for
some 15 years now), but rather to move from html/xhtml/xml to json --
pretending that just because the tree is wrapped up in curly-braces and
semicolons rather than bracket-tags, it's no longer a tree, and order and
levels, and siblings magically cease to make a difference (aka the "lisp pipe
dream -- we're too cool for assoc, we already have cons"-approach). But as
long as we're on the web (and probably in many other places as well, such as
desktop ui, we'll have the equivalent of structured documents, where both
structure and tagging makes a difference -- and the need to go from various
trees to various documents, and to map differently structured documents to
each other. And interpolating simple plain-old-data-trees into a template for
a document is going to be a different task from translating parts of one
document to another. Even if both data and documents are represented as json
(or xml or html or xhmtl or...)).

------
rdtsc
This Erlang web framework already has something like this:

[https://github.com/5HT/n2o](https://github.com/5HT/n2o)

Excerpt:

    
    
        body() ->
        {ok,Pid} = wf:comet(fun() -> chat_loop() end),
        [ #panel{id=history}, #textbox{id=message},
          #button{id=send,body="Chat",postback=chat,Pid},source=[message]} ].
    
    
    

Also comes with bidirectional Websocket connection support.

It is based on a similar project called Nitrogen.

------
angersock
Does anyone else get the feeling of "Joe has rediscovered templating engines,
but in Erlang"?

This is still neat; I just want to make sure I'm not missing anything.

------
krapp
Congratulations, you've reinvented PHP, kind of.

~~~
andrewflnr
That's not the bad part of PHP. Rather, it's the part of PHP that let it take
over the world despite its manifold flaws.

~~~
krapp
The latter is undeniably true, even if the former is debatable. I've had to
maintain code where PHP variables were assigned from a database then echoed
directly into javascript functions and broke more than once because of
encoding issues or a lack of necessary escaping -- being able to do crazy
things like that is very flexible and fast, but it can also lead to some
horrible messes if you don't know what you're doing.

------
vezzy-fnord
This looks surprisingly similar to how the Nitrogen framework uses Erlang
records to wrap around HTML elements and jQuery actions, e.g. as in:
[http://nitrogenproject.com/demos/simplecontrols](http://nitrogenproject.com/demos/simplecontrols)

------
kyllo
All markup languages converge toward Turing completeness, just like all
programming languages converge toward Lisp. Just use a homoiconic language--a
language where code is data and data is code--and you won't have these kinds
of problems.

------
fa
Also reminds me of Pollen, for the inestimable Racket environment, which was
created by M. Butterick to typeset "Practical Typography".

[http://pollenpub.com/](http://pollenpub.com/)

------
jtwebman
I might do something like React JSX, maybe called ERX. I do think it opens up
a hole though in doing business logic the wrong place. I know in Elixir it
might be easy to do with the meta programming stuff.

~~~
lucaspiller
That should be pretty easy with parse transforms, here is an example for
embedding JSON:

[https://github.com/happi/json-transform](https://github.com/happi/json-
transform)

As another comment suggests
([https://news.ycombinator.com/item?id=9215580](https://news.ycombinator.com/item?id=9215580)),
this would allow you to keep everything as a data structure until the last
minute.

In regards to business logic, I think you just need to be strict when writing
your application with the idea of what a 'view' is. Although React may seem
like you are violating separation of concerns, in reality view logic and
templates are already tightly coupled.

------
douche
When I read that title, all I could think of was the apocryphal "Can I use
HTML with variables to make a hockey MMO" thread from GameDev.net.

~~~
tlrobinson
This? [http://www.gamedev.net/topic/280347-is-darkbasic-pro-the-
bes...](http://www.gamedev.net/topic/280347-is-darkbasic-pro-the-best-current-
software-to-create-a-hockey--video-game/)

~~~
douche
This one is even older, but I'm still not sure its the original
[http://www.gamedev.net/topic/128827-variables-vs-
html/page-3](http://www.gamedev.net/topic/128827-variables-vs-html/page-3)

------
peteretep
Moments like this I wish people still used XSLT...

------
absurdity69
This is powerful. It streamlines everything for efficiency. It might not be
the best solution at this moment in time but the idea of programming with HTML
has value. Especially as web apps get bigger and more powerful.

~~~
Svenstaro
It was nothing HTML was ever designed for and this kind of programming failed
horribly in the past, see PHP's frameworkless go-to mode of programming.

~~~
girvo
PHP's _past_ frameworkless mode of programming (though even goto's were
shunned, if I think back a decade to when I was writing that sort of PHP).

You are right though, that it can get messy very quickly. But there is a case
to be made for it in some circumstances; at least in terms of being able to
render a page server-side as well as having it available as an API. I don't
know enough about Erlang to say whether this is a good way of doing so,
however, but it can be nice to have your templates with the interpolation
points and small bits of display "logic" (if, then, etc.) all separate from
your proper API written in a proper style.

------
bhhaskin
This is neat, but a really bad idea over all.

~~~
matti3
Yea Its a cool exercise into what can be done. But ultimately not a road that
I personally would like to travel..

------
itsbits
basically another form of JSX. Looks cool but don't think I would prefer this
anyways...

