HTML as a programming language – unifying HTML with Erlang
joearms.github.io
joearms.github.io
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/). 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.What's so different about:
<html> <head>...</head> <body> ... </body> </html>
and
(html (head ...) (body ...))
Wouldn't we've been better off with the latter anyway?
No <b><i>mismatched</b></i> closing parens. No <p>optional close tags. No difference between compulsory close tags <script></script> or <img /> self closing tags.
But without a specialized editor, SGML is nicer to write.
SGML is nice for humans. S-exprs are nice for programs.
Besides, Lisp has the tooling for collapsing deeply nested structures into flatter ones if you need to, because one can use nested defines inside a function and later just call by name if needed. It just means the stuff that would've been more deeply nested will be defined earlier than it's container. Most of the time this is usually what you want anyway, because you're going to be reusing a lot of the structure elsewhere in the document - DRY becomes a lot simpler.
HTML is nice in part because it's pretty easy and accessible for people who are not programmers by training.
It's not in a vacuum though: there are tons of tools and tutorials and colleagues and other things dealing with HTML as it is, and tons of people used to how it currently is.
This is a historical issue with HTML. It's supposed to be "markup". The original idea was that HTML documents would be mostly text with some tagging. Since it was just "markup", markers that triggered formatting operations, it wasn't considered necessary that a strict tree structure be enforced. HTML5 still tolerates and parses such constructs as "Plain <b>Bold <i>Bold italic </b>Italic </i> Plain". This may be a holdover from the way things worked in UNIX nroff/troff, an early markup language.
XHTML requires that the tags balance, which seems to put a lot of people off. I thought at one time that XHTML would replace HTML, but that didn't happen.
In retrospect, browsers were made too lenient. It probably would have been better if, after detecting an error, browsers put a red band across the page with an error message, then continued to display using default fonts and colors. Then we could have avoided years of struggling with browser incompatibilities due to non-uniform handling of errors.
(I'm currently trying to figure out why BeautifulSoup 4, the Python library, creates a broken parse tree and crashes for documents which contain "<head><head> ... </head></head>". "kroger.com" has that. You'd think that the web pages of the Fortune 100 would be better.)
The dark side of Postel's Law.
There's also kioo if you like the enlive approach better.
[: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.
I'd go so far as to say that is the correct way to do it and anybody doing anything else is doing it wrong. Anything other than "immediately parse all incoming data to internal structures" and "serialize internal structures at the last possible moment" is just crazy insane to deal with, and unfortunately, when it comes to the web, "crazy insane" immediately leads to "insecure".
I find that HTML is usually more tightly coupled with the CSS than the associated logic (which is done with more traditional data structures). for this reason I find views written in programming languages can feel like a clunky abstraction over HTML, rather than a simplification of it.
Anyhow, the solution to "repetitive HTML" is the exact same as the solution to "repetitive code", because it is repetitive code: Factor it.
Get used to this approach and honestly, the only thing that a conventional template is better at is large blocks of static HTML tags; otherwise, a "powerful, rich, awesome, wonderful" template language that everyone goes gaga over is just an inner-platform effect problem mistaken for virtue.
I'm also generally underwhelmed by the "'dumb' designer has to be able to edit it"... I'm sure someone, somewhere has that use case (I mean, don't bother replying, really, I believe you have this use case), but it seems to me an awful lot of people plan for that use case but it never actually manifests. I'm not convinced it's the common case.
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...), 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.
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.
(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.arcWhich is why I don't like the proposal: it's not unifying HTML and Erlang, it's compiling string macros into Erlang. Is there any reasons not to embed the interpolation in Erlang directly?
hello(N) ->
Name = <em><? N ?></em>,
<#>
<p>Hello <? Name ?></p>
<p>The <#></#> lets you group
multiple elements, that don't
have a parent, as a single value.</p>
</#>.
(Whether the <X></X> is doing simple string interpolation, or is HTML-smart is left for the reader to decide -- it's certainly overkill for server-side only code.)You could use XSL , i'm pretty sure you never do that.
Any solution that relies on "templating" involves logic in templates. And templating languages are there because they ALLOW separation of concern. A template is independent from the controller that called it. They just share a contract at the data level.
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.
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... <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...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://www.treebrolly.com/blog/turbo-plone-theming-with-xdv-...
http://www.uwosh.edu/ploneprojects/docs/how-tos/how-to-use-d...
(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...)).
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.
This is still neat; I just want to make sure I'm not missing anything.
Also there was a talk about Erlang where Joe Armstrong was talking about EHE, but I couldn't find it. I thought it was a joke, but apparently it wasn't.
https://github.com/happi/json-transform
As another comment suggests (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.
The sad thing is, XML, and thus XHTML, has this. And it's nowhere near as ugly as this, which is saying something, because "lol, XML".
If what a person wants is cross-referenced elements in an XML document, then that's what they should use: https://msdn.microsoft.com/en-us/library/ms950811.aspx
If what a person wants is logic in their HTML, then they're standing on a slippery slope that ends in Classic ASP, PHP, and other wailings and gnashing of teeths.
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.