[HN Gopher] Declarative Enhancement for HTML
       ___________________________________________________________________
        
       Declarative Enhancement for HTML
        
       Author : revskill
       Score  : 112 points
       Date   : 2023-07-06 08:57 UTC (14 hours ago)
        
 (HTM) web link (twinspark.js.org)
 (TXT) w3m dump (twinspark.js.org)
        
       | nsonha wrote:
       | When do people understand "declarative" is a style not a property
       | of some language? As the language, "declarative" xml and by
       | extension, html has failed in every single platform (the web,
       | android, iOS), which is why in all of those platforms people have
       | been trying for years to write UI in code, but in a more
       | declarative style (React, Swift UI, Jetpack Compose). This is
       | backward.
        
         | chrisco255 wrote:
         | Declarative markup always evolves into a badly conceived
         | programming language.
        
           | [deleted]
        
           | Drakim wrote:
           | That's also been my experience, yet I've also gotten a
           | spaghetti of a mess assembling the UI in regular code with
           | loops and whatnots. Are there any other interesting options I
           | could explore?
        
             | nsonha wrote:
             | an imperative language that is DSL-friendly, such as kotlin
             | and jetpack compose, or just functional languages, like
             | ClojureScript's Reagent.
             | 
             | JSX is fine too. It's gotten a lot a bad rap because of
             | React, but looping and conditions have never bothered me,
             | despite people's complains about them.
        
             | wongarsu wrote:
             | Declarative Code for initial state, with modifications done
             | in regular code. Ideally data bindings for lists etc. (so
             | the declarative part can state "this is a scrollable list
             | view, each item looks like this, the content of these items
             | is stored in variable Y", and any update to Y updates the
             | list)
        
           | maweki wrote:
           | I think in one direction, i.e. templating, it works fine.
           | Have data, have declarative syntax on how to iterate over
           | data and generate fresh code from that.
           | 
           | The bidirectional case is already difficult where your
           | changes in the generated source should backtranslate into
           | changes in the supplied data.
           | 
           | But now also declaring interactions in the general case? This
           | endeavour must surely fail, as there are so many possible
           | interactions and so little design space without running into
           | either the _inner platform effect_ , where you're just
           | replicating the host programming language (but with bugs), or
           | _Greenspun 's tenth rule of programming_, where you're
           | accidentally building "an ad hoc, informally-specified, bug-
           | ridden, slow implementation of half of Common Lisp".
           | 
           | As an aside: I think a sweet spot is providing some UI
           | elements and a framework for composing them, and then having
           | a kind of DSL to low-code-connect them up in the DOM. You can
           | abstract a lot of stuff away from the end user using, you
           | know, code. And then the DSL can be nice for the
           | interactions.
           | 
           | But we all know that interactivity is hard and complex and no
           | way of writing it down, be that imperative, declarative, or
           | whatnot, will take that away.
           | 
           | Edit: Beware of the Turing tar-pit in which everything is
           | possible but nothing of interest is easy.
        
         | dwb wrote:
         | Strictly speaking I agree with your first sentence, but clearly
         | some languages/environments lend themselves more to the
         | declarative style than others, and may or may not let you reap
         | more of the benefits. (I also disagree that HTML has "failed"
         | in almost any sense, but I don't think that's as interesting a
         | discussion.)
        
           | nsonha wrote:
           | Sorry you said not interested but I have to comment on this
           | 
           | > disagree that HTML has "failed" in almost any sense
           | 
           | The web was born in html, at some point web development skill
           | shifted from it to mostly js. Why do you think that's the
           | case if not html itself failing to accommodate for modern web
           | development requirements?
           | 
           | It's not a joke that html isn't a real programming language.
           | You can only go so far with it and it definitely offers zero
           | help in modeling the problem's domain or any high level
           | thinking process that programming encompasses.
        
             | ziftface wrote:
             | Even so, web developers always had the option of sticking
             | with an imperative approach to UI, like using
             | element.innerHTML = '...', but overwhelmingly they
             | preferred more declarative solutions like React. You could
             | just as easily make the argument that the shortcomings of
             | HTML had nothing to do with its "declarativeness", since
             | that part was retained. I think a more likely explanation
             | is that HTML couldn't be used to express the more
             | complicated SPAs that people wanted to build, and
             | regardless of what you think about those, JS-based
             | solutions had to fill that need.
        
               | bobthepanda wrote:
               | Yeah, HTML _is_ declarative but the issue is that it's
               | such in an extremely simple way.
               | 
               | Loops, conditions, and variables/transclusions are table
               | stakes, and without them pure HTML is just tedious data
               | entry with extra tags.
        
             | Semaphor wrote:
             | > at some point web development skills shifted from it to
             | mostly js.
             | 
             | [citation needed]
             | 
             | I mean, it looks like this if you look at HN (the comments,
             | not the code) and similar places, but imo less in the wild.
        
         | austin-cheney wrote:
         | Even more to that point we only need HTML (in any flavor)
         | because the browser says we do. The compile target is the DOM.
         | The DOM is the goal, not HTML. If the environment were treated
         | more like WASM where any language could compile to the target
         | then it wouldn't matter what the source language is.
        
           | dgb23 wrote:
           | Having a standardized data representation is a good thing.
        
             | nsonha wrote:
             | html is not a DATA representation, it's not designed that
             | way and it would actually be way more noisy if attemps to
             | represent all the hidden states of the DOM.
        
             | austin-cheney wrote:
             | Does it really matter? The data representation could be
             | markdown, yaml, JSON, SVG, or just about anything else and
             | be equally effective. The browser already supports XML and
             | HTML5 as wildly differing grammars that still compile to
             | the same target.
        
         | tannhaeuser wrote:
         | I wouldn't go so far as to be bitter about it like you appear
         | to be (based on past negative experience?) but yeah: the real
         | question is why should one stick to markup when you're
         | developing an app anyway?
         | 
         | Markup is for documents, and the "declarative" aspect of it is
         | that it guarantees certain safety conditions (termination,
         | injection safety, maintainability) without sending the author
         | into a full Turing-complete programming environment and
         | everything that goes with it, requiring experience, testing,
         | choice over implementation alternatives, maintenance,
         | debugging, and more laborious/expensive hosting with
         | monitoring, etc. Markup is for ambitious tech-savvy end
         | users/non-developers, and the high end of a non-Turing markup
         | language operating purely at the level of syntactic
         | manipulation, unlike htmx and TwinSpark, IMHO would be SGML,
         | containing a finite state mechanism for context dependent
         | styling or other processing and natural injection-free
         | templating/macro expansion.
         | 
         | Now the web has pushed the limits of what can conceivably be
         | called "documents" eg blogs with threaded comments, table of
         | contents and other navigational idioms, etc. For these kind of
         | "content apps" (supported by SGML still), there has always been
         | a struggle between full Turing complete environments and
         | increasingly idiosyncratic markup techniques.
         | 
         | That struggle is even more noticeable when looking at CSS. IMO,
         | CSS has aggregated such an enormous complexity while most
         | advanced use cases fall straight into "app" territory. That is,
         | there is no justification for most recent CSS features when
         | those features can only realistically be applied in the
         | presence of JavaScript anyway, and thus should actually be
         | implemented using JavaScript rather than bloating CSS. Case in
         | point: the has() selector which doesn't materially enhance what
         | you can do with HTML/CSS but clearly is introduced in support
         | of components and modularity; ie requiring JS anyway, and with
         | JS allowing much better modularity already anyway, is hence
         | just redundant. Clearly, also calc() and custom properties are
         | doubling what's already available.
        
           | ziftface wrote:
           | I think my experiences are just very different from yours,
           | but I found that declarative markup was the only sane way to
           | represent visual UI elements. The classic example is using an
           | imperative JS API like element.innerHTML = '...' vs
           | React/Vue/etc, but the same could be said for newer UI APIs,
           | like SwiftUI. I wouldn't call a mobile app's UI layout a
           | document, but I still think the declarative nature of that
           | API is a better fit than its imperative predecessor, UIKit.
           | 
           | Both of those examples have an "escape hatch", where you can
           | drop into an imperative API if you need to, so I can see the
           | argument for them not being a perfect abstraction of the
           | underlying primitives, but that doesn't mean they're not
           | useful and a good fit for the problems they're solving.
        
           | xigoi wrote:
           | The has() selector definitely enhances what you can do with
           | CSS. You can style elements differently based on what they
           | contain.
        
             | nsonha wrote:
             | which is the wrong way to do it. The source of truth for a
             | state, that determines the style, should be... well a
             | state, most likely in memory. It should not be a visual
             | representation of that state (what element is rendered in
             | side). When you change the latter, your conditional css
             | will become broken unknowingly.
        
       | imbnwa wrote:
       | Would be interesting to see the HTML spec find a way to pull from
       | the SCXML[0] spec for declaratively modeling nested, parallel
       | state machines, maybe adding pseudo-selectors to CSS for querying
       | it.
       | 
       | [0]https://www.w3.org/TR/scxml/
        
       | m3h wrote:
       | It would be great to have some examples right on the main page as
       | many devs would be interested in how this library compares to the
       | React/Vue/Angular/etc. Currently, the code samples are hidden two
       | levels deep and behind a view source button.
        
         | piranha wrote:
         | Thanks for that message, it was just hard for me to decide on
         | what to put in there :)
         | 
         | But your comment forced me to, so I've put something in there,
         | even if it's not really thought through. :)
        
           | revskill wrote:
           | Could be a todo example with a static json as API ?
        
             | piranha wrote:
             | There is no way to render JSON as HTML right now, it
             | expects server to return HTML.
             | 
             | OTOH that's an interesting thought and it feels like just
             | an addition of one command to whatever there are in actions
             | ( https://twinspark.js.org/api/ts-action/ ) right now... I
             | need to think about it a bit. :)
        
               | murkt wrote:
               | An action that renders HTML from JSON will either:
               | 
               | -- Require additional client-side templates and then it's
               | back straight to hell;
               | 
               | -- Require really specific JSON structure, basically
               | HTML-in-JSON, which will be ugly as hell and totally
               | meaningless. Meaningless, because then it means I need to
               | adapt my API to this format, and then I can just make it
               | return HTML.
        
               | piranha wrote:
               | Yeah it's only the first way, since the second is
               | effectively the same as rendering html on the server.
               | 
               | As for the first - it could give a way to use legacy apis
               | and static data. Not sure if I want this in the core,
               | but... how hard can it be?
        
               | murkt wrote:
               | Sure, if it's only one additional five-liner action
               | that's not even in core, then whoever wants to bring the
               | hell back - it's only their own doing
        
       | cyberproblem wrote:
       | How does this differ from Alpine? It looks like an AlpineJs 2.
        
         | piranha wrote:
         | It's more like an alternative implementation of htmx. Alpine is
         | more about "let's do components in HTML", and this one is more
         | of an idea "how do not go there, but still have practical
         | results". :)
        
       | replwoacause wrote:
       | Looks awesome, can't wait to try it out!
        
       | culopatin wrote:
       | Is the name in any way associated with the two spark plug Alfa
       | Romeo engines?
        
         | piranha wrote:
         | Yeah, that was the inspiration. If you know, htmx predecessor
         | was called intercooler.js, so I just continued the automotive
         | theme. :)
         | 
         | I had a reference on main page for a long time...
        
       | evrimoztamur wrote:
       | How does it compare to HTMX? Anybody have experience with both?
        
         | andybak wrote:
         | That was the first thig I wondered too.
         | 
         | In case you didn't spot this part:
         | 
         | > Some reasons why TwinSpark exists despite HTMx and Unpoly
         | (those are similar in approach):
         | 
         | >
         | 
         | > It's really small (8KB .min.gz).
         | 
         | > There is no attribute inheritance -- keeps surprises away.
         | 
         | > Batching - very useful if you want to use HTTP caching
         | effectively, while maintaining some personalisation for your
         | users.
         | 
         | > Bundled - a lot of practical stuff packed in, like actions,
         | or non-traditional event triggers, or morphing.
         | 
         | > Extensibility - you can easily register new directives the
         | same way those in core are registered.
        
           | rakoo wrote:
           | This doesn't answer the question "why not bring this inside
           | htmx or unpoly", and now as a developer I need to _again_
           | check if I need to port over a new framework or not
        
             | piranha wrote:
             | Two reasons really: I wrote it before htmx appeared, so it
             | already existed and a few projects were using it in
             | production. And second one - I really hate attribute
             | inheritance, and it's everywhere in htmx...
        
               | rakoo wrote:
               | The blog post hints at the first point, but I didn't know
               | about the latter, so thanks for the details !
        
             | andybak wrote:
             | > now as a developer I need to again check if I need to
             | port over a new framework or not
             | 
             | Why do you "need to"? Use what works for you. Glance over
             | new stuff and dig deeper if some aspect of it appeals to
             | you. And if the churn stresses you out then don't.
        
           | dgb23 wrote:
           | Most of these also apply to HTMX it seems.
           | 
           | I think a bigger difference is that TwinSpark seems to have
           | some integrated DOM manipulation, so it's a bit bigger in
           | scope and less opinionated?
           | 
           | HTMX on its own is great as long as you stay within its
           | philosophy of rendering things on the server.
           | 
           | But most UIs I write need - as in it's optimal for UX and
           | performance or out of necessity because it's talking to a
           | third party - at least _some_ parts to be fully client side
           | rendered.
           | 
           | I personally found that combining HTMX with something like
           | lit-html is kind of the sweet spot for a lot of projects
           | assuming full-stack development. These are very small/light
           | libs that cover a ton of ground with minimal surprises and
           | very good performance per default. The _only_ downside is
           | that you don't get isomorphic rendering code but I happily
           | pay that relatively small cost for having such a simple
           | dependency graph.
        
             | piranha wrote:
             | Why do you feel the need to use lit-html? Just interested
             | in the use-case.
        
               | megaman821 wrote:
               | I am not the original poster, but I use lit-html to make
               | the interactive elements on the page like tabs and
               | modals. Then I use HTMX to load the contents of those
               | elements when the tab or trigger is clicked.
        
               | piranha wrote:
               | That's one of the reasons TwinSpark got actions, you
               | still need little bits of client-side interactivity.
        
               | megaman821 wrote:
               | I find things like actions is great for conditionally
               | showing and hiding form fields or small things like that,
               | but if you want to have accessible tabs and modals it is
               | best to bundle it up in a component. Here is an example
               | of a lit components I use,
               | https://codepen.io/megaman821/pen/GRXmzZb and
               | https://codepen.io/megaman821/pen/dydvxBE
        
       | zsoltkacsandi wrote:
       | I have been thinking for a while to create a new
       | library/framework that composes the features of Tailwind/DaisyUI
       | and HTMX/Unpoly/Hotwire into a SwiftUI like declarative template
       | language (forcing these features into HTML attributes makes HTML
       | bloated/difficult to write) that eventually generates all the
       | HTML, JS, CSS code in the background.
       | 
       | I am tired of MVC frameworks, SPAs, writing CSS, JS, dealing with
       | tooling, setting up IDEs to format the code properly, etc, I just
       | want to create nice webapps, and want my app designed nicely from
       | the first line of code I write.
        
         | azangru wrote:
         | > I am tired of ... writing CSS, JS
         | 
         | Wait till you get tired of writing html - and you will have
         | caught all the pokemon :-)
        
         | _connerc wrote:
         | have you thought about low code platforms?
        
           | zsoltkacsandi wrote:
           | Why would I? I didn't say that I don't want to write code,
           | but don't want to deal with this frontend madness. Other
           | platforms (Android, Swift, desktop, etc), has been able to
           | solve that the web hasn't been able to do in 30 years.
        
             | kristiandupont wrote:
             | I on the other hand find that "npm create vite@latest" is
             | orders of magnitude simpler than working with any of the
             | Android or iOS developer environments. I can't speak to
             | "desktop" as I haven't done anything like that in 10 years,
             | but I have a feeling that it would be similar.
             | 
             | Could it perhaps be that you are confusing familiarity with
             | simplicity?
        
               | zsoltkacsandi wrote:
               | Please show me how Vite helps you to work in one language
               | instead of three.
        
               | Rumudiez wrote:
               | CSS is a feature, not a bug
        
       | cassepipe wrote:
       | It reminds me of hyperscript: https://hyperscript.org/
       | 
       | I am fine with writing a little js has long as it's colocated
       | with the (augmented) html and css. I think the svelte approach
       | scales better and seems more easily debuggable because it
       | enforces a structure and is more readable. There is enough stuff
       | in my html tags already.
        
       ___________________________________________________________________
       (page generated 2023-07-06 23:02 UTC)