Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

No. Doing UI in JavaScript shouldn't make any noticeable difference. I say that as someone who hates JavaScript and doesn't think it should be used for anything, really.

But, UI apps are long-running, and interactive. There's no real "throughput" or anything like that to be concerned with.

The problem is precisely with the crowd that believes that ALL optimization is premature--or rather that code styles that I would consider pessimization is good. For example, in JavaScript, it's considered hip and "functional" to have a local variable that's an array, and instead of mutating it, programmers will string together five calls to `map`, `filter`, etc, making a bunch of temporary copies and iterating the data five times instead of once.

Writing JavaScript with what I've heard called "mechanical sympathy" does not have to be slow at all.



Chained folds (map, filter, etc.) immediately within the same expression really should be easy to optimize, but even if the compiler doesn't do that, if the library provides those methods as operations on iterators, then an unoptimized version should only cause redundant loop counters and a single extra array allocation whenever you materialize it. So the array temporaries are a bad implementation/design choice.

Scala has functional web frameworks that have no problem doing 100k+ requests per second on older mid tier desktop hardware, and while that's slow compared to a good mutable, imperative C implementation, it's fast enough that obviously functional programming per se is not the reason for perceived UI slowness.


"Chained folds (map, filter, etc.) immediately within the same expression really should be easy to optimize"

In a pure functional language they are.

In a non-functional language with mutation it is much more challenging. Map functions are unconstrained in Javascript which means they can do anything they like with regards to breaking optimization.

This is generally why I'm down on the whole "chain maps and filters" style of programming in languages that aren't designed for it. You are paying more than you may realize if you've never profiled your code and compared. In languages that are designed for it and have the ability to optimize it, by all means, go for it.

The other thing you have to remember is that JITs are time-constrained as optimizers go. They have the advantage of access to real run-time information about how things are being used, but they also have very, very tight time budgets; on the whole the time budget's problems seem to dominate the knowledge advantages. The profiler is not allocated a lot of time to prove that a given function is pure and it's OK to synthesize a composed function rather than run two maps. I don't even know if any JS engine is smart enough to try that. (Input from anyone who knows welcome, I'd be interested to hear either way.)


You don't need the language to be designed for it or to prove it. Just document it as a contract for the caller. e.g. "the argument to map must be a pure function. For functions with side effects, use forEach. If an impure function is provided, the behavior is undefined." This isn't very different from contracts that require you not to change the length of an array when using iterators.


Yeah, I'm imagining trying to push that sort of thing out into the Javascript world, and maybe your model of Javascript programmers is a lot different than mine, but I don't see this going terribly well.

In the Javascript world's defense, I don't see this as a practical solution in very many languages at all. I don't think I can name any language that doesn't have a compiler-level enforced definition of "pure function" somehow where its programmers will across-the-board reliably know what a "pure function" is.

Much as I hate to lick HN's boots and inflate the already substantial ego we can have here sometimes, do remember that HN is generally populated by the upper echelon of programmers and there's plenty of people out there who would have no idea what this means. I can think of several coworkers over the years. This isn't even an insult in the sense you might think; not everyone programming is necessarily a "programmer" I expect to be super knowledgable about programming. I'm having a major issue right now at work where I've got a data scientist sort of pushed into doing even just a bit of "programming work" interacting with an engineering organization and it has been a freaking nightmare, and I can't even really complain because while they are wielding Python, programming is really just a side task in the world of data analysis. They may be able to program in Python but they have no idea about performance, super focused understandings of optimizations (at best, sometimes it's just zippo), an incredibly surface level understanding of Python syntax, etc. And why not? It's not actually what we're paying them for.


> In the Javascript world's defense, I don't see this as a practical solution in very many languages at all. I don't think I can name any language that doesn't have a compiler-level enforced definition of "pure function" somehow where its programmers will across-the-board reliably know what a "pure function" is.

IME Scala programmers generally don't have much trouble with this, and the language doesn't do anything to prevent side-effects wherever you feel like putting them. It's just culturally not very common. Similarly, you can use `null` for almost anything in Scala, but it's extremely rare to run into one in code that isn't interacting with Java. But nothing really stops you from using basically any feature as Java++.

For your Python programmer, like I mentioned they already have to deal with some form of no-side-effects with for loops: you should not modify the length of a data structure that you are iterating over (`for x in foo`), or you'll get weird/unexpected results (e.g. [0]). You don't need to even go full UB, and could just specify that the order that the arguments to chained folds get called in is unspecified, and that code that needs to care should use `forEach` or a for loop. IME if you're writing in a pipelined map/filter/fold style in the first place, the ordering question just doesn't come up much. With that style it's rare to need to mutate anything yourself because the mutation you need is baked into those loop primitives.

[0] https://stackoverflow.com/questions/38003119/what-are-the-ru...


I'm certainly not against chaining combinators in general. In fact, I love functional programming and I enjoy Scala. I'm only specifically criticizing it in JavaScript and other languages that decided to import functional programming features onto eager collections.

Scala's standard collections are implemented as persistent collections, so the overhead for each combinator call is small, and could even be optimized by the compiler. JavaScript doesn't have a compiler, so the best you could hope for is a JIT optimization, but even that's impossible for several reasons related to the dynamic nature of the language.

As an aside, I sometimes like to shit on Java, but the language is very well engineered, despite its "original sins" that make me hate it. When Java decided to import functional programming niceties, they didn't just tack `map` and `filter` onto `Collection<T>`. They added the whole `Stream` API which does the best possible thing given what the language already was.


It depends what you're aiming for. For accuracy, map and filter make it impossible to fall off the bounds of your iteration. While it would certainly be nice if the runtime could do that faster, slow + correct is often (not always) better than fast + broken.

(There are languages that make fast + correct easier. Unfortunately, JavaScript isn't really one of them).


JavaScript has `for-of` syntax for iterables, so you won't go out of bounds, regardless.


put the nice looking calls to `map`, `filter`, etc in a comment then rewrite it with a for loop under it.


That's a pretty nice suggestion. Honestly, though, the expanded for loop implementation is never really that complicated in practice.




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: