[HN Gopher] How functional programming shaped and twisted front ...
___________________________________________________________________
How functional programming shaped and twisted front end development
Author : jicea
Score : 114 points
Date : 2025-10-04 13:04 UTC (9 hours ago)
(HTM) web link (alfy.blog)
(TXT) w3m dump (alfy.blog)
| davedx wrote:
| Think some of that (the dialog and friends) is the wrong way
| around: we wouldn't have gotten all those nice DOM native
| components if libraries and frameworks hadn't popularised them
| and driven adoption into the standards.
|
| I am not sure I agree "the state of front end development" is due
| to "functional purism" either. React just provided a good
| abstraction that worked well for many people. It's a meritocracy.
| If the abstraction that worked best (however we measure that) had
| been something more OOP then that would have been adopted.
| paulryanrogers wrote:
| It's funny because React has both class-based components and
| more functional components.
| madeofpalk wrote:
| Not sure I agree with the tone of the article, but I do find that
| Javascript developers have a weird relationship with "functional
| programming". I see _so much_ convoluted code with arr.reduce()
| or many chained arr.map().filter().filter().map(), that would
| just be so much simpler and easier to read if it was a classic
| for-loop. I suggest this to people and they scoff at the thought
| of using a for-loop in Javascript.
|
| > _Consider the humble modal dialog. The web has <dialog>, a
| native element with built-in functionality. [...] Now observe
| what gets taught in tutorials, bootcamps, and popular React
| courses: build a modal with <div> elements_
|
| The dialog element is new! Only broadly supported since 2022. I
| find it hard to fault existing material not using it. Things like
| dialog, or a better select, are notable because they were lacking
| for so long.
| madeofpalk wrote:
| On the other hand, from my experience, large development teams
| cannot write CSS at scale. "Writing clean CSS code" doesn't
| seem to be a skill that most (frontend) developers seem to
| value, so abstractions like CSS Modules (which is barely an
| abstraction - it's just compile-time BEM) and CSS-in-JS came up
| to manage complexity of both a large codebase and large team.
| hombre_fatal wrote:
| On the _other_ hand, scaling CSS is fundamentally hard
| especially in a large team where it 's more of an
| organizational problem.
|
| It takes eternal vigilance to maintain it. Refactoring it is
| a huge feat. And when you want to modify or add a single
| component, it doesn't make sense to re-cred in the whole CSS
| apparatus, and it's not necessarily trivial to figure out
| where to make the CSS change, so CSS files tend to become
| append-only.
|
| It's like how learning how to "write clean code" doesn't
| really change much about how hard it is to change large
| software systems over time in a large team.
| Terretta wrote:
| These difficulties with CSS are how you know an org can't
| "design system".
|
| You will see similar issues with their Word and PowerPoint,
| setting properties on elements instead of styles.
| pverheggen wrote:
| Yeah, most orgs use Figma as the source of truth, so if
| your designers don't "design system", it finds its way
| into the codebase.
|
| Even if they do follow a design system, it tends to
| evolve over time, and it can be a bumpy road to reach a
| mature one.
| madeofpalk wrote:
| Yeah, this is exactly my point. It's hard to do, doubly so
| when most folks don't value it.
| nucleogenesis wrote:
| I'm fond of chained array methods, especially if the callbacks
| I pass are named functions - it can make for code that I find
| way more legible than for loops. But even with anonymous
| callbacks I'd rather do that ~90% of the time than use a for
| loop anyway.
| dapperdrake wrote:
| Series (by Richard C. Waters) are a pipelining compiler for
| map/reduce.
| ninetyninenine wrote:
| The benefit of FP has nothing to do with it being easier to
| read. FP is HARDER to read. The benefit of FP is modularity.
| Take your example:
| arr.map().filter().filter().map()
|
| Every step on that is a modular operation.
| const x = arr.map() const y = x.filter() const z
| = y.filter() const d = z.map()
|
| now I can easily do this: const x = (arr) =>
| arr.map() const y = (arr) => arr.filter() const z
| = (arr) => arr.filter() const d = (arr) => arr.map()
| o = d(z(y(x(arr))))
|
| This is the main reason why functional programming is elegant.
| It makes every corner of your program modular and solves the
| fundamental program of program organization and modularity.
|
| with a for loop it is easier to read initially but if that
| filter chain grows the functional approach will begin to be
| better.
|
| Take an example of a for loop doing the same thing:
| const acc = [] for (const x in arr) { y =
| map1(x) if(filter(y) { continue
| } z = y if(filter(z)) {
| continue } d = map2(z)
| acc.push(d) }
|
| Yes more readable but imagine if the logic gets even more
| complex. Then at scale functional will become more readable AND
| more modular. Modularity, however, is the main problem here.
| You cannot split or modularize that for loop.
|
| But I agree with you. Initially and not at scale, functional
| programming loses readability. Functional programming is harder
| to read because people think procedurally over functionally. We
| like numbered instructions or a todo list, not a series of
| composed function calls and thus from a general view point
| functional programming is harder to read than procedural
| programming. But this has never been the benefit of functional.
|
| Functional programming is supposed to solve the modularity
| problem with how you organize programs to be reusable.
| Functional programming objectively does this while it is only
| subjectively considered less readable by the majority of
| people.
| madeofpalk wrote:
| I don't actually have all that much of a problem with
| chaining fp-style functions, but I note that I see a fair bit
| of anonymous functions and excessive chaining where none of
| the benefits you point out are realised.
|
| My _actual_ problem is with bad reduce functions that try to
| shoehorn multiple things into one function and often break
| the core concept of functional programming by mutating the
| input arguments. It 's that code that would just be better
| written as a normal loop.
| whilenot-dev wrote:
| > It's that code that would just be better written as a
| normal loop.
|
| Have to disagree with your conclusion here. It's that code
| that should be rewritten, so it doesn't mutate the input
| arguments at all.
| edoceo wrote:
| When I'm doing FP, rather than making a long chain, I assign
| at each step, then call the next one. As you've shown above.
| Sometimes I even comment on why the code is doing stuff.
|
| Making it read as a list of steps, helps me understand what
| it's doing a little easier than that long chain.
| monkpit wrote:
| Same. Chaining all of those together does nothing useful,
| is arguably less readable, and the JIT will optimize out
| the intermediate assignments. So there's not really any
| reason to do that big chain (unless you're talking about
| HoC/composable functions, which this example is not).
| derefr wrote:
| > I see so much convoluted code with arr.reduce() or many
| chained arr.map().filter().filter().map(), that would just be
| so much simpler and easier to read if it was a classic for-
| loop.
|
| It's interesting; when I'm writing JS in an actual .js file, I
| _do_ tend to use for loops. But when I 'm writing JS at the
| (CLI or browser-dev-console) REPL, I'll always reach for
| arr.map().filter().filter().map().
|
| When you're at a REPL, with its single-line/statement,
| expression-oriented evaluation, it's always easier / more
| intuitive to "build up" an expression by taking the last
| expression from history, adding one more transformation, and
| then evaluating the result again to see what it looks like now.
| And you don't really want side-effects, because you want to be
| able to keep testing the same original line vis-a-vis those
| modifications without "corrupting" any of the variables it's
| referencing. So REPL coding leads naturally to building up
| expressions as sequences pure-FP transforms.
|
| Whereas, when you're iteratively modifying and running a
| script, with everything getting re-evaluated from the start
| each time, it's not only more intuitive to assign intermediate
| results to variables, but also "free" to have side-effect-y
| code that updates those variables. It's that context where for
| loops become more natural.
|
| I bet that a lot of the chained-expression JS code you see out
| there was originally built up at a REPL, and then pasted into a
| file, without then "rephrasing" it to be more
| readable/maintainable in the context of a code file.
|
| ...though there's also just FP programmers who write JS (or
| more often TS) as if it were a pure-FP language -- either
| literally making every variable const / using Object.freeze /
| using Readonly<T>, or just writing all their code _as if_ they
| had done that -- where for loops become almost irrelevant,
| because they 're only really for plain iteration (they're not
| list comprehensions), and plain iteration has few uses if
| you're not going to do anything that produces side-effects.
| yearolinuxdsktp wrote:
| I think it's a far cry on the original author's side to call
| the use of map().filter().map() an obsession with FP.
| Underscore.js simply provided super-useful functions over
| arrays and objects, which IMO makes for more legible code.
| Often times you can re-use filters with named functions. If you
| have multiple conditions for iteration exit, it's clearer to
| chain filters than it is to have nested ifs or early exits in a
| for loop -- it refactors better.
|
| The real obsession with FP is the pervasive use of immutable
| state. But in apps, state must be effectively mutated, but now
| with a copy of the original immutable object. The FP obsession
| believes that this better than directly mutating the state each
| and every time.
| madeofpalk wrote:
| Using these functions is not the problem. It's using them
| passed the point of being reasonable where I see the
| incorrectly placed obsession.
| DavidWoof wrote:
| It's hard to talk in the abstract because obviously people can
| abuse any type of code feature, but I generally find chaining
| array methods, and equivalents like c# linq, much easier to
| read and understand than their looping equivalents.
|
| The fact that you single out .reduce() here is really telling
| to me. .reduce() definitely has a learning curve to it, but
| once you're used to it the resulting code is generally much
| simpler and the immutability of it is much less error-prone. I
| personally expect JS devs to be on the far side of that
| learning curve, but there's always a debate about what it's
| reasonable to expect.
| albedoa wrote:
| > The fact that you single out .reduce() here is really
| telling to me. .reduce() definitely has a learning curve to
| it, but once you're used to it the resulting code is
| generally much simpler and the immutability of it is much
| less error-prone. I personally expect JS devs to be on the
| far side of that learning curve, but there's always a debate
| about what it's reasonable to expect.
|
| Not only that, but the words that GP uses to single out
| .reduce() start with:
|
| > I see _so much_ convoluted code with arr.reduce() or many
| chained arr.map().filter().filter().map()
|
| Which I do not doubt, but the point is diminished when one
| understands that a mapping of a filtering of a filtering of a
| mapping is itself a convoluted reduction. Just say that you
| prefer to read for-statements.
| madeofpalk wrote:
| I say _convoluted_. I prefer using the functional-style
| array methods, but there 's a time and place for
| everything, and I feel a lot of Javascript developers
| extend those methods beyond what is reasonable and into a
| convoluted mess, _especially_ with reduce.
|
| Give me a good classic `T[] => I` reduce function and I'm
| fine with it. Not the more common case of folks mutating
| the accumulator object.
| chuckadams wrote:
| The wonderful thing about .reduce() is that it can compute
| literally anything. The problem with .reduce() is that it can
| compute literally anything. As for the rest of the morphism
| menagerie, I like being able to break up functions and pass
| intermediate results around. It's literally cut and paste
| with map/filter, with a loop it's rewriting. Yay
| composability.
|
| That said, it's easy to get carried away, and some devs
| certainly do. I used to be one of those devs, but these days
| I sometimes just suck it up and use a local variable or two
| in a loop when the intent is perfectly clear and it's not
| leaking side effects outside of a narrow scope. But I'll be
| damned if I let anyone tell me to make imperative loops my
| only style or even my primary one.
| chowells wrote:
| Reduce cannot calculate literally anything, in the sense
| you mean. It corresponds in computational power with
| primitive recursion. And quite famously, there are problems
| primitive recursion cannot solve that general recursion
| can.
|
| On the other hand, I don't think I've ever seen something
| as recursive as Ackermann's function in real life. So it
| can probably solve any problem you actually mean to solve.
| zelphirkalt wrote:
| Unfortunately, since we don't have continuations, we cannot
| make reduce _stop_ computing. In such cases where that is
| needed, it might be better to use a loop that can be broken
| out of.
| michaelcampbell wrote:
| > that would just be so much simpler and easier to read if it
| was a classic for-loop.
|
| Only if that's how you were taught. For devs brought up in the
| FP manner, the for loop is as hard to grok as you find the
| chained stuff.
|
| The Blub Paradox in action.
| zbentley wrote:
| I have never, ever seen this. And I've worked next to some
| very FP-forward types and academic CS/abstract math
| background types who have vastly deeper knowledge of their
| fields than I ever will of mine.
|
| Plenty of them don't _like_ imperative loops, sure. But I've
| never seen someone assert that a simple loop is not
| intelligible to them while chaining functions are.
| chowells wrote:
| If you're replacing a chain of filters and maps with a
| nested loop, you're far past "a simple loop" and well into
| the realm of an unintelligible for loop. The chain of maps
| and filters tends to make that far easier to read by
| decomposing it into separately-comprehensible pieces.
| zbentley wrote:
| Oh totally agreed; for complex transformations, being
| able to compose and tap the intermediate states is really
| nice (though I quite like generator/yielding functions
| with captured stack state as a happy medium).
|
| But that's not the claim I was pushing back on. That
| claim was that, given a loop and some equivalent chained
| list-processing functions, primarily FP-taught people
| _could not understand the loop_ due to their background.
| That's bogus.
|
| That complex loops are hard to understand for anyone is
| inarguable. But there's not some magical "functional
| mindset" in which imperative/mutative code is
| unintelligible to the point of total obscurity and
| functional code is not. If there were, how would anything
| ever get rewritten in a functional style?
| Jcampuzano2 wrote:
| Personally I use filter and map (and others like .some, .every
| .flat and flatmap etc) all the time but I avoid reduce.
|
| filter and map immediately tell me what the purpose of the
| loops are - filter things and transform things. A for loop does
| not do this.
|
| To someone familiar with functional programming these are very
| normal and easier to read and grep than just a loop. In other
| words filter and map give additional context as to the intent
| of the loop, a bare for loop does not.
|
| Not to mention this is not abnormal in languages outside of JS,
| even non-functional ones.
|
| That said Ive seen too many convoluted uses of reduce that I
| just avoid it out of principle.
| sgarland wrote:
| I like map() and filter() in Python, but unfortunately
| they're 2nd class citizens compared to list comprehensions,
| which continue to get optimizations to further increase their
| speed.
|
| I like comprehensions as well - and their syntax is quite
| readable - but I'd like for the two to be more at parity.
| zbentley wrote:
| One of the main reasons that map() and filter() don't get
| optimizations in Python is because they're _lazy_.
|
| It's a lot easier to optimize comprehensions because you
| can make a lot more guarantees about what _doesn't_ happen
| between iterations: the outer stack doesn't move, the outer
| scope can be treated as static for purposes of GC-ing its
| locals, various interpreter-internal checks for "am I in a
| new place /should I become aware of a new scope's state?"
| can be skipped, the inner generator can use a simplified
| implementation since it never needs to work with manual
| send(), and so on.
|
| Map/filter can't take advantage of any of those
| assumptions; they have to support being passed around to
| different arbitrary places each time next() is called on
| them, and have to support infinite sequences (so do
| comprehensions technically, but the interpreter can assume
| infinite comprehensions will terminate in fairly short
| order via OOM lol).
|
| That said, there are likely optimizations that could be
| applied for the common cases of "x = list(map(...))" and
| "for x in filter(...):" (in nongenerator functions) which
| allow optimizers to make more assumptions about the outer
| context staying static.
| lblume wrote:
| list(map(f, ...)) should almost always be replaced with
| [f(x) for x in ...] though.
| Quekid5 wrote:
| Yeah, the "problem" with reduce is that it can do anything,
| and so doesn't offer much over a traditional for loop with
| mutable local variables to accumulate into. Of course, if you
| can replace a reduce() with a filter and/or map or whatever
| (which more clearly states intent), by all means do so!
|
| If you really need arbitrary computation, I'm not sure
| there's any real readability benefit to reduce() over _local_
| mutation (emphasis on local!). Sure, there 's immutability
| and possibly some benefit to that if you want to prove your
| code is correct, but that's usually pretty marginal.
| lblume wrote:
| Reduce can be very useful to signal that the state used is
| inherently limited. My rule of thumb is to use reduce when
| the state is a primitive or composed of at most two
| primitives, and a for loop otherwise. What counts as
| "primitive" depends on the language of choice and
| abstraction level of the program, of course.
| zelphirkalt wrote:
| I think the reason for JS devs having "a weird relationship
| with 'FP'" is, that JS itself, in its nature, is not a
| particularly well suited language for FP. It has essential
| elements, that by their nature are global mutable state. For
| example timers and their ids.
|
| Also weak typing plays into this. Some operations not
| immediately raising an error when the wrong type of thing is
| provided, is a recipe for bad experience when having point free
| style or semi point free style. If given the choice, at least
| one thing would be good to have, strong typing or static
| typing.
| ninetyninenine wrote:
| I believe functional is the better (and best) paradigm we have
| right now. But the problem of why FE development still feels
| overcomplicated is because of a different reason.
|
| There's a mismatch between how components are organized and how
| data flows through the front end application.
|
| HTML is hierarchical. You have elements wrapping each other
| A +- B +- C | +- C1 |
| +- C2 | | +- C2a | | +- C2b
| | +- C3 +- D +- D1 +-
| D2 | +- D2a | +- D2b
| +- D3
|
| The issue here is that you can have something like D3 changing
| the state of an element like C3. So data must be artificially
| grafted on the above hierarchy to make it work.
|
| D3 wants to send data to C3? Well then that means B must be the
| owner of the data. So data that feels like it must live on D3
| well now you got to make it live on B which has nothing to do
| really with D3.
|
| This has one primary problem.
|
| It destroys modularity and much of the benefits of functional
| programming making it sort of useless in react. If you did prop
| drilling most things that have a path from B to C3 and B to D3
| now are no longer modular and can ONLY be used in context of data
| related to D3. If you didn't use prop drilling and used some
| contextual way to pass the data the problem is still there
| because now components on that path have access to contextual
| data that's irrelevant. I mean for a time it may be safe... but
| some developer may break it and have a component access that
| context and suddenly modularity is broken... that component can
| now never be moved outside of the context.
|
| Really... how data flows through your program is actually a
| separate graph structure, and how HTML elements are organized in
| your program is another separate graph structure we try to graft
| into the first one and that creates a mess.
|
| I think the best way to do this, hasn't been done yet. But really
| side effects like clicks and button presses should NOT live on
| components. Components don't know about these things. That keeps
| the hierarchy and modularity of these html elements pure. A
| framework that's well designed needs to enforce this separation.
| I even think this can be done in a way that is STILL functional,
| but not react.
|
| HTML and jquery were sort of going in this direction, but the
| problem was HTML lacked modularization because you couldn't group
| tags into a component. You also have timing issues and complexity
| with state that jquery didn't handle.
|
| Overall I think the old style was actually better. It was a
| better overall direction that had tons of problems and I think
| those problems could have been solved if we continued in that
| direction. AND i feel we could have continued this direction with
| some sort of functional framework.
|
| Imagine something similar to jquery but this jquery can only
| directly reference components on your component hierarchy and
| pass data directly to components (aka manipulate them). Context
| and state will also live on this jquery like framework and it
| will be handled in a similar way to how react handles it. While
| components themselves can wrap other components, and parameters
| that go into components can ONLY have default values. The
| components can never dynamically "call" other components with
| data and actually have anything truly dynamic going on.... only
| the jquery like framework can do this.
| ianthehenry wrote:
| Bonsai is a frontend framework that models data as an explicit
| graph, separate from any "component hierarchy" or DOM
| structure. State can live anywhere in the application graph,
| whether or not it's associated with DOM nodes, and you
| eliminate all of the "move this state to the parent to share
| it" ceremony by just having "components" return their views and
| "outputs" at the same time (if they want).
|
| It's pretty great and hard to imagine going back to a React-
| like component hierarchy.
| ninetyninenine wrote:
| Oh nice, it's ML style, like elm.
| whstl wrote:
| IMO/IME these problems have more to do with program
| organization rather than with any individual architecture.
|
| To avoid it, funny enough, you have to take cues from
| functional programming, and you need strong, composable,
| primitives with succint interfaces (the opposite of shadcn).
| Even for visually combining and placing components, you need
| stateless layout components [1] that don't depend on anything
| and just render children a certain way. This way it's possible
| to have a very flat component hierarchy. The entire state-logic
| at the top-level doesn't hurt much anymore. Also, just
| props+events are enough, no need for Context, Redux or other
| tricks.
|
| But if you go the "Clean Code" route and the main reason to
| have components is so so they're not too big, then you get deep
| hierarchies, prop-drilling becomes a big problem, and you need
| Context or state libraries specifically for inter-component
| communication.
|
| This is a problem that I've seen come up time and time again
| not only in Frontend but also in desktop apps and in video
| games. And backends often have the luxury of having the entire
| state in the database, so it doesn't happen as often.
|
| Of course the side effect of this is that you will end up with
| bigger components, and you need _better_ abstractions, but IMO
| this is a small price to pay for having code that is easier to
| work with and doesn 't need special ways for handling the data.
| Also this method tends to work better in bigger apps and people
| complain it's wasteful in smaller apps, so there's that too.
|
| [1] In the design world this is often called Templates.
| https://atomicdesign.bradfrost.com/chapter-2/#templates It's
| interesting how this didn't catch among frontend devs. I
| remember "layouts" being a big part of WPF for example.
| ninetyninenine wrote:
| hard disagree.
|
| With prop drilling how do you get the setter methods into C3?
| You have to prop drill all the way down.
|
| Let's say I add a new component under C3 that has a side
| effect in some sister hierarchy under B. Then now suddenly in
| between and B and C3 and the other component I have to modify
| EVERYTHING to take that new change into account and these
| components now all have an extra prop that they don't
| intrinsically need but they keep in order to account for C3.
|
| Because data is so intrinsically linked with components Every
| component between B and C3 now needs to be modified to prop
| drill when previously it wasn't needed.
| em-bee wrote:
| that's because you are using react where every html element
| that does something dynamic is its own component.
|
| when i use aurelia, then the whole page is one component and
| dynamic functionality in elements is achieved through bindings
| and functions that all share the data in the component. you can
| include other components, but you only do that where needed,
| and then passing data becomes a lot easier.
| myguysi wrote:
| > Really... how data flows through your program is actually a
| separate graph structure, and how HTML elements are organized
| in your program is another separate graph structure we try to
| graft into the first one and that creates a mess.
|
| My team migrated away from Redux and for over a year I've been
| unable to pinpoint why I've been longing for it again. This has
| hit the nail on the head for me. Redux (and other "global"
| state management solutions) allowed me to decouple the data
| graph from the UI graph. When a UI event is triggered, an
| action is dispatched and then the data graph takes over. This
| makes the UI graph extremely simple - render UI and dispatch
| actions - but these days we're mixing state with business
| logic, event handling, API calls, rendering UI, styling, etc.
| This is very much a problem of our own making that could be
| solved by a different architecture, but yeah... thanks for
| clarifying this feeling for me.
| gedy wrote:
| I don't disagree with the idea that people can be a little kooky
| about FP, but the idea that webapps are perfectly fine without
| modern front end approaches is a bit exaggerated. Managing UI
| state is much easier in the client - sure, if you don't have a
| stateful UI to begin with don't go build some JS SPA. But I've
| have been there done that with teams and companies that dislike
| JS then try to fake UI state back and forth from server to
| client, and it really sucks, overcomplicates stuff that should be
| simple.
| AstroBen wrote:
| A lot of these are implementation details and not necessary for
| the abstraction to work. Preact doesn't use a synthetic event
| system for example
| paulryanrogers wrote:
| Is that true even when you want to use Preact without class
| based components?
| ludicrousdispla wrote:
| Something about web development really does seem to break a
| person's ability to design/architect a proper event-driven, data-
| oriented UI.
| marginalia_nu wrote:
| I suspect there's a class of problems, front end development is
| one, ORM is another; where the problem itself is constrained in
| such a way that only shitty solutions exist.
|
| ORM keeps sucking because RDBMSes simply don't operate on
| objects. You can either impose ill conceived object models on
| the database, or try and fail to capture the database's
| affordances in objects.
|
| I don't have a theory on what's gone wrong with front-end
| development to cause its chronic disease, but it may simply be
| that HTML is a document markup language, and makes a
| questionable base for a user interface.
| taffer wrote:
| > HTML is a document markup language
|
| No it is a _hypertext_ [1] markup language and it doesn 't
| suck if you actually use it as such.
|
| The problem is that we decided that <a> and <form> tags
| should be the only hypercontrols, only triggered by clicking
| on them. However, libraries like HTMX and Unpoly enhance HTML
| so that every element can act as a hypercontrol, responding
| to all kinds of events. This allows you to implement
| interactive features such as autocompletion, form validation
| and infinite scrolling without writing a single line of
| JavaScript.
|
| > ORM keeps sucking because RDBMSes simply don't operate on
| objects
|
| Have you read [2]? Modern SQL can return nested JSON. No ORM
| needed.
|
| [1] https://htmx.org/essays/how-did-rest-come-to-mean-the-
| opposi...
|
| [2] https://www.scattered-thoughts.net/writing/sql-needed-
| struct...
| marcosdumay wrote:
| The name for those is "wicked problem". They usually appear
| when your problem statement is itself incoherent.
|
| The entire thing about users interacting with data through
| computers is one of them. There are several inconsistent
| goals, like consistency is at odds with flexibility, and
| accessibility is at odds with security.
|
| We have those tools that push the incoherence around, but
| they are always prone to collide somewhere.
| knallfrosch wrote:
| UI would be easy if its data wasn't just a cache.
| morcus wrote:
| This article started out interesting and then there were a series
| of baffling claims that... didn't quite make sense to me and
| feels like they are just trying to set up a straw man.
|
| 1. The author complains that React devs don't understand
| addEventListener when it is used and required reasonably often as
| far as I have seen?
|
| Also, "Again: the web had this. The browser's event system is
| fast, flexible, and well-understood. But it wasn't controlled
| enough for the FP ideal of a closed system."
|
| The stated purpose of the synthetic event system was to normalize
| differences in browser behavior back when React was created. It's
| not as necessary these days because browsers have gotten better,
| but saying it's about "FP Idealism" seems off.
|
| 2. The author complains about re-inventing the <dialog> element.
| This is valid, and new code should obviously use it. That said,
| it only became available across all major browsers in March of
| 2022, and still isn't supported by some minor browsers.
|
| All of the popular component libraries were made before that, and
| thus ought to keep their JS implementation for backwards compat.
|
| As far as tutorials, when I search "React dialog tutorial" the
| first result regrettably does show how to build your own, but the
| next two focus on using the built in element.
|
| 3. Then the author turns to customized select, and complains that
| JS frameworks don't support them. This would be valid but the
| very MDN article they link literally starts with:
|
| > This article explains how to create fully-customized <select>
| elements using *experimental browser features*
|
| (emphasis mine)
| reactordev wrote:
| I can see from a new developer point of view, their
| frustration. Why aren't things standard? Why not use builtin
| tags? Why this or that?
|
| Valid questions we should all be asking. Sometimes, just
| because "that's the way it was" doesn't mean that's the way it
| should be. Often times I find myself _deleting_ code that is
| now more readily available as either part of the platform I'm
| on or part of the framework I'm using.
|
| Your points are valid too, that they don't know about the
| history that got us here and why it is the way it is but
| nevertheless we should all be asking ourselves daily, "do we
| still need this?" and trim the fat.
| totallykvothe wrote:
| That's not what the article was about though. It wasn't only
| a complaint about not using built in niceties of the
| platform. It was an assertion that the reason we aren't is
| because of some kind of functional bro boogeyman.
| fleebee wrote:
| > That said, it only because available across all major
| browsers in March of 2022, and still isn't supported by some
| minor browsers.
|
| `<dialog>` only got full compatibility with Firefox about two
| months ago with Firefox 141. Safari still doesn't support
| `closedby`.
|
| Given that, I still regard `<dialog>` as experimental, and
| that'll remain the case as long as the "Baseline Widely
| available" label comes with an asterisk.
| hungryhobbit wrote:
| It only became obvious at the end that the whole (WAY too long)
| article was just a giant troll to promote the author's personal
| pet technology (HTMLX). But it was a highly disingenuous one,
| because (as the poster above noted) it was giant straw man, not
| a legit critique.
|
| I felt cheated just by having read the article: I'm all for a
| long and winding article that has something to say, but this
| one was telling a bad joke for WAY, WAY too many paragraphs.
| rs186 wrote:
| The article does not go into the disadvantages of server-side
| rendering (or more specifically, fetching html from server).
| I am sure the author is well aware of the choice between
| client- and server-side rendering but skipped it and seems to
| present technology like htmlx as "solutions" to all the
| problems the article mentioned which is quite a stretch.
| librasteve wrote:
| I spent the whole time thinking "yeah, we need HTMX" - took a
| long time to get there eventually.
| troupo wrote:
| > That said, it only became available across all major browsers
| in March of 2022, and still isn't supported by some minor
| browsers.
|
| And the only reason it suddenly reappeared in 2022 was because
| browsers want to get rid of alert/prompt dialogs.
|
| The spec was (and probably still is) so riddled with issues
| that it never went anywhere for 10 or so years, and Chrome at
| one point argued it should be removed.
|
| > This would be valid but the very MDN article they link
| literally starts with
|
| People involved with HTMX play really fast and lose with
| anything that doesn't fit their conclusions hoping no one will
| call them out.
| didibus wrote:
| What I'm curious is why the platforms don't adapt to how the
| developers have found works best?
|
| The developers look for ergonomics in maintaining the code base,
| that can scale to larger team and websites.
|
| This requires a lot of customers JS framework code to offer, but
| in a sense, it's because the platform doesn't natively support it
| no.
|
| Would there be ways to evolve the web platform to better align
| with the React style for example?
| edoceo wrote:
| WebComponents?
| troupo wrote:
| Web Components are not anywhere near to any requirements
| people had, have, or will have.
|
| That's why they went from "you won't need React" to "good for
| leaf components maybe" to "maybe use HTML web components
| maybe?"
| aardvark179 wrote:
| There are often a couple of barriers to this.
|
| Firstly, you can't break what is already there, so any
| evolution of the general platform often has to make wider
| guarantees than a single framework.
|
| Adopting ideas from any single framework too quickly may put
| you in a worse position. A framework can evolve and choose when
| to break compatibility, a language or platform standard has a
| tougher job in that regard.
|
| Some things that front end frameworks have settled on are now
| being looked at for standardisation, but I'm personally still
| wary about changing something like the ecmascript for. It would
| be an easier call if there were a standard library which simply
| needed an implementation, but we aren't quite there yet.
| jt2190 wrote:
| > What I'm curious is why the platforms don't adapt to how the
| developers have found works best?
|
| Here's my take:
|
| - The web was visualized as a way to publish academic documents
| in a hyperlinked document system. Librarians and academics live
| in this world. We hear the word "semantic" from them a lot.
|
| - The _visual_ web was visualized as a way to publish documents
| that had a precise look. Graphic designers live in this world.
| They don 't care about semantics. They do care about pixel
| perfect layouts and cool effects.
|
| - The web app was visualized as a way to deliver software to
| users with lazy, "click link to install"-like behavior. What
| this crowd cares about is providing server functionality to
| users, and other concerns like semantics or pixel perfect are
| often secondary.
|
| - The single page web app is also visualized as as a way to
| deliver software to users with lazy, "click link to
| install"-like behavior. They differ from the web app group in
| that they try to have more server functionality right in the
| client. Again semantics and pixel perfect are secondary. App
| complexity is a big problem that this group contends with, and
| this is what the article discusses.
|
| Given these different ways of visualizing the web (and I'm sure
| I've left a few out), it's no wonder that we're stuck with the
| mess that is today's web development. The right solution is a
| sensible runtime for app development, that doesn't force you to
| render UI through the DOM and doesn't make it hard for you to
| get access to basic things like the local file system. We've
| known this forever (anyone remember Flash?).
|
| WASM _feels_ like it might finally allow app developers to do
| all of the software things that native platform developers get
| to do easily, and with the added bonus of strong sandboxing. It
| 's early days yet, I think the "Ruby on Rails"-moment has not
| yet arrived there yet, i.e. a very popular, easy way for devs
| to create whatever app-de-jour everyone's excited about.
| w10-1 wrote:
| > WASM feels like it might finally ...
|
| But WASM is weirdly allergic to the DOM and to javascript.
| The core, fundamental interfaces are terrible and highly
| disputed, so it will be restricted to mainly-WASM apps for
| some time.
| jt2190 wrote:
| That's only a problem if your goal is to keep on doing the
| same old web apps the same old way, just delegating part of
| the program logic to WASM which, I agree, will be more
| complicated. But if you're going to use WASM why limit
| yourself to using the DOM and JavaScript? Why not use a
| programming environment that lets you use more
| sophisticated tools?
| troupo wrote:
| > What I'm curious is why the platforms don't adapt to how the
| developers have found works best?
|
| Because standards committees are also made out of people. They
| have their own agendas, experiences, biases, company loyalties
| etc.
|
| And in the past ten or more years _all_ standards have been
| taken over by a very small number of _very_ prolific people
| from Google. Prolific as in: writing dozens and hundreds of
| specs and having their fingers in all standards.
| chrisallick wrote:
| more like ruined it
| joduplessis wrote:
| No offense intended to the author, but this is the most bizarre
| list of points.
|
| I also realise how weird it must be writing a personal blog
| article and then have random internet-folk dissecting it. Hope
| this doesn't dissuade any future articles.
| prinny_ wrote:
| I am a FE developer and I believe that we collectively have a
| loser's mentality when dealing with CSS.
|
| In my mind, SCSS + CSS modules + maybe a processor tool is an
| rock solid and modern set of tech that produces excellent results
| and most importantly moves styling off the main thread. It makes
| sense to use it, but we don't. FE interviews even for senior+
| roles are JS/React/system design questions. Nothing about CSS and
| I get it. Why interview for something you don't use internally?
|
| I recently read something that stuck with me, which was about
| micro front ends but I think applies in more cases than this: "it
| doesn't solve a technical problem but an organizational one".
|
| There was an excellent reddit discussion on the pros and cons of
| tailwind and it boiled down to "it's really hard to enforce CSS
| guidelines for teams of multiple people". Tech leads didn't want
| to monitor how 10 or 20 or 50+ different FE developers wrote CSS
| and opted for tailwind so that everyone wrote the same, even if
| that meant multiple inline classes pasted on each element. I find
| this reluctance to enforcing guidelines weird, considering at
| $WORK we have multiple confluence pages and internal documents
| about React and Javascript guidelines and I have seen similar
| documents in previous work places. Would it be really different
| to apply the same mental paradigm for CSS?
|
| Of course, all this is under the hindsight knowledge that HTML
| and CSS have evolved in recent years to be truly powerful and
| versatile. I get the technical decision to go all in on JSS and
| React 5 years ago. I don't now.
| Tade0 wrote:
| I share this sentiment.
|
| CSS modules are really enough - there's no need to overthink it
| any further.
|
| I'm currently in a project where my first task, spanning
| several months, was to clean up after the previous guy. The
| main issues in styling were misguided attempts at sharing
| styles implemented via breaking encapsulation.
| zelphirkalt wrote:
| It seems to me, that many FE devs don't even know CSS these
| days. Rather just tack on some "ready" made component found on
| NPM or some component library. When it actually comes to using
| CSS to fix something about part of a page or part of a
| component, I often see non-responsive ways of doing that, badly
| tested across browsers, breaking at some width of the viewport,
| etc.
|
| In my view CSS is essential. Not knowing CSS at least somewhat
| well is a huge obstacle in producing high quality frontend
| work. It's like being a carpenter, but simply not knowing one
| important aspect of wood, or not being able to use a specific
| tool to work with wood, lets say a tool to smooth surfaces. CSS
| is part of the medium you work with as a FE engineer. It is
| unfathomable to me, how a FE engineer can not know this stuff
| well. If some FE engineer is reading this, and feels some
| impostor syndrome: Yes, if you don't know your medium and tools
| as least in the basics, then you should feel like an impostor.
|
| I see broken responsiveness very often. Of course in almost all
| websites, that rely on JS to display what is essentially a
| bunch of static texts.
|
| If I was interviewing for a FE position, and really had to go
| through the circus of asking interviewees code questions, I
| would definitely include a minimum of CSS knowledge there.
| Basic things like how they would scope their CSS to specific
| elements or classes of elements and how they would prevent
| their styling to bleed into other stuff. Or how they would set
| up a theme with just CSS. Not questions expecting them to write
| CSS on a whiteboard, of course. Just testing their basic
| understanding.
| marcosdumay wrote:
| > I find this reluctance to enforcing guidelines weird
|
| It's worse than that. All the hype in design has been about
| creating a global design language, and enforcing it over all
| your teams for more than a decade now. All the hype has been on
| centralizing the design team, moving it away from the
| developers for some years. All the hype has been on tools that
| claim to enable reusing and distributing that work...
|
| And yet everything is done in a way that developers have to do
| everything themselves and don't get to coordinate with each
| other.
|
| (Honestly, I'm settling on the opinion that non-developing
| application design is a scam all around.)
| troupo wrote:
| > In my mind, SCSS + CSS modules + maybe a processor tool is an
| rock solid and modern set of tech
|
| "my set of non-standard tools and preprocessors is superior to
| these guys' non-standard tools and preprocessors" is not a good
| argument.
|
| > I find this reluctance to enforcing guidelines weird
|
| Because CSS doesn't lend itself to any enforcement. All the
| tools that appear around it _includng those you like_ like SASS
| and "some processing" don't appear because people don't
| understand something or can't enforce something.
|
| > Of course, all this is under the hindsight knowledge that
| HTML and CSS have evolved in recent years to be truly powerful
| and versatile.
|
| Indeed. And many of these features have been made available
| across all major browsers only in the past two or so years.
|
| No one is going to rewrite everything from SASS or CSS-in-JS
| just because some features now exist in vanilla CSS.
| gjgtcbkj wrote:
| Are there seriously devs that think FE code quality actually
| matters? It's become so standardized and cookie cutter setting up
| this frameworks to actually work in development and production
| environments is ten times more difficult then recreating Facebook
| or Twitter. Who would build there career on this at this point?
| vinceguidry wrote:
| Great article. I got off the webdev train just as Redux was
| coming out and never looked back. When my team lead decided to
| unilaterally replatform the app we maintained from Rails to
| NodeJS my professional life went from heaven to hell. Gone were
| the days of finishing our tasks for the week in two days and
| playing ping pong every day. Insult was added to injury when that
| team lead left halfway through.
|
| The web had a golden age where it was _understandable_. The
| browsers ' inconsistencies were mostly ironed out and you had
| references for what worked where. Flexbox was magic and you had
| shims to get it working where it wasn't yet supported. Web
| development was actually fun. When you solved problems, you were
| actually learning something, not just throwing stuff at the wall.
|
| These web platforms gradually threw all that out. If you're a new
| engineer, realize that platform knowledge isn't real knowledge.
| Knowing React really well isn't a thing you can build a lasting
| career on. Your job is your job, but your education is your
| responsibility. If you don't want to be locked into an ecosystem,
| make sure you are constantly learning fundamentals.
| toastal wrote:
| These are things to be critical of after post-React in the
| explosion of complexity, but I don't think this is FP's fault. I
| did a lot of FP front-end in the actual FP languages--not
| languages cosplying FP with JS or TS--& these communities (Elm,
| PureScript, followed js_of_ocaml, Reason, & the things Haskell
| was trying at the time) were not jumping on these same bandwagons
| of complexity but hoping to wrangle in some of it, usually
| focused on how the view should be a declarative representation of
| the state while pushing side-effects to the edges. There wasn't
| talks of making CSS too complex, hydration, et. al. That JS/TS
| crowd however...
| breadwinner wrote:
| > Combined with React Hooks (which replaced stateful classes with
| functional composition), the ecosystem shifted decisively toward
| FP.
|
| React is the farthest thing from functional, see here:
| https://mckoder.medium.com/why-react-is-not-functional-b1ed1...
|
| Composition in React Hooks is closer to multiple inheritance in
| C++ (because it combines state and behavior from multiple
| components) than functional programming.
| smrtinsert wrote:
| This is a very incorrect conclusion. Nothing about jquery
| prevented functional purity. If that's what you wanted, use it as
| such. Jquery just made browser differences much less of an issue
| and wrapped it in a nice way. The modern react stack is exactly
| what all the fp snobs raged against and they weren't wrong about
| it. Its been said before, there was jsf before react. Both are
| bad ideas. React has terrible performance is extremely
| heavyweight and ridiculous for what its used for. There's a
| reason there's a revolt nearly daily.
|
| To me the major failing here was people over investing in faang
| thought leadership. Still haven't ever used react angular etc in
| a major project and gone wow this is great. JQuery got a lot
| closer. There were many other ideas coming forward around the
| time those frameworks came up, it was a fertileperiod for
| frontend. Sounds like we should cycle back.
| w10-1 wrote:
| Other commenters are criticizing details, but I really appreciate
| the OP trying to see the entire landscape. I agree with other
| commenters that ownership over code is a primary driver (at least
| for CSS style vs. javascript interaction).
|
| Leaving aside details, it seems clear the javascript frameworks
| were ahead of the platform and had the perverse incentive of
| staying that way, which also took the pressure off browser
| developers (already slowed by inter/standards politics),
| resulting in a long historical period of dissonance.
|
| By comparison, Java bytecode gave Scala and Kotlin instant access
| to the enterprise, and the JDK team responded with faster cycles
| and steady but measured incorporation of features, because they
| realized they needed something to get enterprise off Java 1.8 and
| into licensable VM's. Progress is slower in the enterprise, but
| the dissonance seems minimal.
| nielsbot wrote:
| FTA
|
| > CSS cascades globally by design. Styles defined in one place
| affect elements everywhere, creating emergent patterns through
| specificity and inheritance.
|
| I can't be the only person who finds that this makes complex
| sites a nightmare to design? (Raise your hand if you've had to
| use `!important`)
| zelphirkalt wrote:
| You are surely not the only one thinking that, but CSS also
| provides easy solutions to this problem, namely selectors and
| CSS classes. Rarely have I had an issue with CSS I wrote
| accidentally doing things I didn't want. Maybe sometimes here
| and there I needed to make a selector more specific, but that's
| not too bad.
| Animats wrote:
| Towards the end of the posting, it turns out this is a plug for
| HTMX.[1]
|
| So, is HTMX any good? Do people use it?
|
| The primary mechanism of HTMX seems to be that you click on
| something, which causes the server to return HTML which is then
| shoved into the current HTML at the selected point. Is that a
| good primitive?
|
| [1] https://htmx.org/
| austin-cheney wrote:
| I get the impression from the article the author may have meant
| declarative instead of functional programming. FP can be fully
| imperative. I often see developers interchange these terms
| improperly because there is some implicit narrow context that's
| out of scope to the broader nature of the terms.
| zelphirkalt wrote:
| Can you give an example for imperative yet functional? Do you
| mean something like within a function using lots of assignment
| and such, but keeping the function pure to the outside?
___________________________________________________________________
(page generated 2025-10-04 23:01 UTC)