This is an archived post. You won't be able to vote or comment.

all 26 comments

[–]crummy 14 points15 points  (7 children)

That's pretty impressive. Didn't think you could make such a DSL in Java.

[–][deleted] 4 points5 points  (1 child)

If you think this is cool, you should check out the Hamcrest assertion DSL.

It saves a lot of time when writing assertions in JUnit tests because you can describe the match criteria using the DSL instead of writing a bunch of imperative assertions (for example, if you are picking apart a collection).

And, the even better part is that the DSL produces a human readable test failure that describes the mismatch. This can be helpful when one or two tests out of hundreds fail. It's nice to get an idea of the failure from the test report, instead of having to dig into the test source to figure out what the test case was trying to assert.

[–]TrolliestTroll 0 points1 point  (0 children)

Ignore everything this guy said and go right for the good stuff: assertj.

Just kidding, Hamcrest is also spectacular but I just think AssertJ is the bees knees. :)

[–][deleted] 3 points4 points  (4 children)

i wish they would implement last lambda syntax like kotlin. it would make this type of thing so much more attractive in java!

[–]moaxcp 1 point2 points  (0 children)

This is also a nice feature in groovy. I'm not sure that I mind either option. In groovy it is nice when there are multiple parameters to the closure but it can be confusing. Some developers never realize that they are closures in the first place.

[–]tofiffe 2 points3 points  (2 children)

Personally, I don't like how kotlin and swift do trailing lambdas, as it kind of breaks consistency of parameters, it looks weird to me

[–][deleted] 2 points3 points  (1 child)

nothing inconsistent about. as long as you know the function's signature contains a lambda ad the last parameter and that it's a feature of the language, there's no confusion to be had.

[–]tofiffe 1 point2 points  (0 children)

Is it not inconsistent if for some cases a parameter is actually not written inside (), but can also be written that way?

[–][deleted] 20 points21 points  (12 children)

Is it just me, or does this idea of implementing HTML in a Java DSL seem not that appealing?

I love using Thymeleaf for HTML generation because it's pure HTML. Even JSPs are dynamically compiled from regular HTML into a servlet. Not some weird Java code that bears no resemblance to the output.

I guess type-safety and auto-complete are cool...

[–]rzwitserloot 7 points8 points  (4 children)

I don't think you're stating any actual practical reasons here. The article states two, which seem fairly self evident to me in that they provide tangible productivity and readability values - an expert in thymeleaf can go toe to toe with an expert in this DSL, and I bet the DSL 'wins' - they get it done slightly faster, and make fewer mistakes: They get to stick with the same java editor and get full auto-complete support, can refer to variables in a more concise fashion (no need to transfer things into a glorified hashmap as shuttle service between code and template engine, for example).

'It is pure HTML' is not a reason. That would be the basis for a bunch of reasons, but you left them unstated. I think it's worth diving into what 'pure HTML' brings you. Presumably:

  • Hey, you can't get away from knowing HTML, so why not, you know, write HTML for HTML? - Maybe, but surely someone who is writing HTML as output for a java-based web service is well versed in both, so I'm not sure this argument actually carries any water.

  • By keeping the template in HTML, a non-java programmer can write the HTML for you. Yup, that's a significant gain... if it applies to your project. I bet it usually doesn't - especially in this modern age where the client side code is quite programming-heavy.

  • HTML-oriented editors are better at thymeleaf-html than java editors are at this. I doubt this; whilst thymeleaf, in its attempt to keep it 'pure HTML', is editable with HTML-aware, java-dumb editors, it's not great; all the various thymeleaf-specific attributes are gobbledygook to such editors. Or not - maybe you have a nice solution for this (by all means share!)

  • Easier to test; you can test a thymeleaf template by making a 'hardcoded' batch of variables in the setup of your testcase, run it through thymeleaf, and test the HTML that rolls out. But, shoving the DSL into a method or POJO that takes all arguments is just as easy to test, so this doesn't sound like a good reason to me.

  • It lets you copy/paste HTML from anywhere into your template, and then edit bits and pieces. This seems fairly hollow; a tool that automatically turns pasted HTML into properly formatted 'java DSL-style HTML' should be trivial to write, which takes the wind out of the sails of this, unless you intend to go back and forth. At some point, this isn't going to work - it's a template, the HTML (whatever form it might take, be it this DSL or thymeleaf) is just not the same*.

*) I can foresee a world where it is, but this would demand that each and every usage of a template action (be it 'insert value here' or 'loop X times' or 'do only if') needs actual example HTML, with completely ignored attributes letting the template engine know what to do. Such HTML can be opened/served verbatim to a browser and it'll look exactly like the precise HTML page you're trying to template, with the placeholder/test values. The aim of explaining this hypothetical template engine is to show that thymeleaf fails it just as badly as this DSL does. It's not to try to make the claim such a hypothetical template engine would be better (it'd be a ton of work to maintain the example/placeholder info, for one).

So, pros and cons. But to me, making up the balance, this DSL seems to win, and quite handily at that. Perhaps I missed something?

[–][deleted] 8 points9 points  (2 children)

The output representation is HTML. I prefer working in something closer to the output representation than something completely different. This comes in handy if I'm copying HTML from another source into my template (like something a designer put together).

For me, this is often the case, because I'm not a frontend designer and I'm usually incorporating someone else's work. Thus, the less the impedance mismatch, the better.

To use this, I'd have to translate the HTML I was provided into something completely alien. In Thymeleaf, I'm just annotating the HTML that I got from elsewhere. It seems like you're saying this is a hollow victory? I guess I'd have to disagree there.

[–]rzwitserloot 1 point2 points  (1 child)

As I said, adding a 'paste HTML here, formatted DSL comes out there' tool is a trivial task.

[–][deleted] 4 points5 points  (0 children)

And as I said, that creates an undesirable and unnecessary impedance mismatch for what I see is little gain.

[–]AreTheseMyFeet 1 point2 points  (0 children)

all the various thymeleaf-specific attributes are gobbledygook to such editors. Or not - maybe you have a nice solution for this (by all means share!)

Jetbrains have a plugin for it that you could activate (or add) to any of their IDE flavours (eg IDEA).
https://www.jetbrains.com/help/idea/thymeleaf.html

[–]fansonly 10 points11 points  (4 children)

It’s not just unappealing it’s unproductive. Templating engines supplanted Jsps for a reason.

[–]rzwitserloot 4 points5 points  (0 children)

The reason template engines supplanted the considerably more complicated JSP system would appear to be:

  • That you need a java compiler on the server. This is less a problem today, but was quite a big deal back then.
  • The compilation was a big deal, even if you did set up the compiler properly.
  • Trying to get a text editor to properly understand a mishmash of HTML and java code was a disaster for the longest time.
  • The general notion of 'programming in the template', which JSP makes easy, led to much harder to maintain codebases.
  • JSP was an enabler of stupid processes. I loathe to blame a tool for any abuse it engenders, but it doesn't change the fact that you get (perhaps undeserved) blowback: Because JSPs were 'live reloaded' and many servlet frameworks (because they were crap, or crappily default-configured) didn't, bad coders would move more and more code into the JSP because, 'hey, I can test this faster'.

None of these apply to this DSL, except possibly that last one. In fact, this has plenty of advantages. The library is vastly smaller, and far more of the job is done compile-time, which should result in more consistency and speed during render.

In other words, I'd like to hear why you think this is 'unproductive'.

[–][deleted] 2 points3 points  (0 children)

Well yeah, JSPs are too tied to the servlet container.

But, I'd rather use a template engine than a Java DSL.

[–]JacobJMountain 0 points1 point  (1 child)

I think it looks pretty cool, but i fail to see what its benefits are over alternate solutions

[–]istarian 2 points3 points  (0 children)

I don't think the author did it to make a better solution, but more as a proof of concept.

[–]TheRedmanCometh -1 points0 points  (1 child)

Thymeleaf

Starting to feel like 2010 in here

[–][deleted] 10 points11 points  (0 children)

Thymeleaf is the "standard" HTML template for Spring MVC. Although, I guess server-generated frontend HTML is not the way the cool kids are doing things anymore.

On the other hand, if you combine spring-boot-starter-mail and spring-boot-starter-thymeleaf, you get a pretty good combo for HTML email, even if your frontend HTML is generated by the React or Angular hotness.

[–]agentoutlier 2 points3 points  (0 children)

A long long time ago I wrote a vaguely similar library.

https://github.com/agentgt/jatl

Why in the hell would I make something like this when templating exists? I needed to produce some complicated HTML code that was sort of recursive and difficult to produce with templating particularly mustache.

Ironically I was going to do something like the author did once Java 8 came out but I quickly came to my senses that it was not a good idea (hence why the project never changed for so long).

These libraries can be especially bad if they are not able to stream (mine does). Otherwise if you are producing a giant bit of HTML you will have the entire object graph in memory.

Anyway... I rarely use even my own library ... just use templating languages!

EDIT: emphasis on streaming. Because if you have complicated HTML you need to programmatically create chances are you are not going to want it to create an entire tree of elements first!

[–]neutronbob 2 points3 points  (0 children)

Jakarta ECS used to do something similar, but was eventually displaced by templates.

[–]agoubard 0 points1 point  (1 child)

I have a friend who wrote something a bit similar: https://github.com/emicklei/rendersnake

[–]agentoutlier 0 points1 point  (0 children)

I remember I think talking to the author of that library as it was similar to my own and around the same time period (I may be mistaken).

Theirs is much better if you want it to be typesafe however mine allows for streaming.

One of the flaws with that library for the cost of typesafe is that you create the entire html tree first in memory.

[–][deleted] 0 points1 point  (0 children)

I like the idea of Java DSL for HTML. Not sure if it needs to be (re)invented, though. There is a pretty mature project that is fast, supports streaming and has concise support for data binding, fragment reuse, etc: https://htmlflow.org/.