Care to explain why? Are you saying that immutable app states such as React/Redux shouldn't exist either? No wonder you got downvoted, just giving rants without proper arguments.
"the documentation describes the API in TypeScript, and then provides no examples at all! So the average JavaScripter can’t understand what the API looks like"
And:
"Add into the mix the way the documentation casually drifts into hard-core Computer Science and algorithmic discussions at inappropriate places, and you’re left with documentation that only the documentation’s auto-generator understands.
Don’t believe me? Just see this example describing Map, one of the most-used Immutable data structures:
Immutable Map is an unordered Iterable.Keyed of (key, value) pairs with O(log32 N) gets and O(log32 N) persistent sets.
OK. Er, of course it is."
If you don't know what you're doing, and you just want to know how to do it, everyone ends up suffering. And I don't know much about Typescript, but isn't it javascript with types? If the average javascripter can't figure out what's going on there...
This isn't helpful. This would be especially unhelpful and counter-productive within a team. Rather than criticize you could offer kind guidance on how the original author could improve. Who knows, perhaps we will disagree with your choices just as strongly?
This is off topic, but is the traffic from HN really that great?
It seems like websites are dead pretty often on HN, but on sites like Reddit where I assume there is a magnitude more traffic they seem to hold up pretty well (with some exceptions).
So what's going on here? Does HN really have a bunch of silent viewers? Or is it something more benign like sites that get submitted are often smaller?
I guess, but I've had a site I own get to the front page of a default sub on reddit, and it's impressive to say the least.
With the multiple-magnitude less comments and votes that HN submissions get, I can't imagine they can get anywhere near that unless HN has a LOT more non-contributing types.
Dynamically generated sites are a Bad Idea when they can be trivially statically generated.
A lot of people still think using WordPress or even Rails for site generation is fine, but both are hard to scale. And if the site is small or academic, it will fall over with not too much traffic.
I wrote a rant [1] about this a couple of weeks ago. I can guarantee that my site will never have a "Database Connection Failed" error (now), because there's no database backing it.
Even better would be if I moved hosting to S3/CloudFront. Dirt cheap, and Amazon isn't going to fall over even if a site hits Reddit's front page. I might not like the bill I get at the end of the month if it really goes crazy, though.
I actually heard of the /. hug of death first, (and your comment feels a little condescending there) and I know of them, but it just feels like HN is such a smaller community compared to Reddit and I see the "hug of death" so much more frequently on HN than I do on reddit (or any other site like them).
I was just curious about the reason why. Like does HN have a large "silent" group, or is it something like that on HN sites climb much faster so I see them when they are down before they've had a chance to recover.
> This is off topic, but is the traffic from HN really that great?
Hmm I wonder if there are any good traffic statistics. I had a library (msngr.js) hit the front page once over a year or so ago and while it helped me gain a bunch of GitHub stars looking at the traffic itself it wasn't really much at all. In fact it was significantly less than I would have expected. Granted maybe my library just wasn't that interesting to people but I would love to see somewhere with some good HN numbers.
When I posted a recent high ranking blog post[0], I received around 18,000 views over the next 24 hours according to Google Analytics. I don't believe this covers a lot of the bots and associated traffic that also crawled the site.
This amount is nothing for a Jekyll site, I had CPU hovering at around 4%, with a series of services also running on this server. This is, imo, where a "hug of death" should end.
I did however at the time, have several colleagues in web development express shock and awe at the fact the site stayed online with traffic levels such as this. Multiple people tried to school me on the need for Cloudflare at this incredible scale.
A lot of web developers think about "scale" in terms of many bloated CMS platforms, and it is with no surprise that the site in question is running Wordpress.
We had a friend's site a while back where we worked out, with just two desktops and spamming "F5" on the keyboard, we could take the site offline, and take several minutes to recover from after the fact. He went and posted for help on Reddit, and sure enough, the consensus was that his experience involved far more traffic than any website could reasonably be expected to handle.
Your answer therefore lies not in the silent HN users, but in the unusually poor performance of popular CMSs. And although I'm using Wordpress, it's not alone in this situation.
[0] https://news.ycombinator.com/item?id=12973181
See I understand the reasoning behind it, but I don't think that's it alone.
I'm saying that the frequency I see the "HN hug of death" is much more than the "Reddit hug of death" while having many of the same kinds of sites (the "bloated CMS platforms" you talk about).
Great article. I wonder what the performance implications would be vs using, for example, native (mutable) arrays. Such addition of analysis to the article would've made it just perfect.
@alexhayes it is a common color palette, I was going to link the most common place where I find it but I forgot about it, haha.
Immutable.js would be great if it were actually maintained. FB hasn't made or approved a real pull request since April, and there are hundreds of pending issues that haven't been addressed or even responded to in over a year.
Which is somewhat ironic, considering half of the reason to use it over Mori (which is better in some aspects) was that it was more maintained (Mori didn't pull anything in ages).
Now neither of them are really maintained.
For a lot of usages, something like Ramda or Lodash/FP will do the trick (Ramda lenses or Lodash/FP's get and set methods work great to handle immutable data structures), but if you really wanted structural sharing and stuff, now you're kindda stuck.
That's not the issue (we have our own lodash-ish thing for immutablejs at work). Its that immutablejs itself isn't maintained much. Doesn't matter how many layers you put on top.
I'm pretty sure that if you report an actual bug and submit a pull request, it'll be merged in no time, as the "Closed" list suggests. You can hardly call that unmaintained.
I went through the pull requests and checked 5 or so that were open for a long time, all of them were glaringly missing something.
Some do not pass tests, some have obvious styling issues, some people haven't signed the contributor agreement, some offer big changes with very little reasoning behind it.
I also prefer projects that are more explicit about the reason something is rejected and answer RTFM-type issues, but this is not a requirement to be a successful project.
I considered ImmutableJS a little while back. It's a great library but it makes you to a lot of work to go back and forth between native JS objects, and just abstracts you from the real objects underneath.
Instead I ended up just deepFreezing my data (only in development) and wrote a bunch of pure functions which perform all the important array/object functions but return a new array/object instead of mutating. It was a really great exercise in functional programming and I'd recommend it to anyone wanting immutable data and to understand immutable programming styles.
seamless doesn't implement the "persistent" part of immutable persistent data structures. The persistent part means you can create a cheap modification of the data structure, with structural sharing between "copies".
Aye. I found its interface to be simpler but it quickly became clear that it was fundamentally useless since I lost the performance gains of partial mutations that left unmutated parts of the structure with the same reference.
The person you are replying to is talking about things like maps implemented with persistent trees. Updating a value in such a map generally only involves copying O(log N) nodes in the tree: It's not necessary to shallow copy the entire tree itself.
Oops, didn't realize that seamless does its own shallow copying strategy with `merge`, `set`, `setIn`. I can't speak to how this compares to persistent data structures implemented by immutable.js, clojure, elm, etc. But it looks like the seamless author said the following about it:
> Persistent data structures are different, as their performance improvements are passive. Although seamless-immutable does not (and cannot, while maintaining its backwards compatibility with vanilla JS collections) use things like VLists under the hood, its cloning functions—such as merge—only bother to make shallow copies, as shallow and deep copies of immutable values are equivalent. In practice, this simple passive optimization has been sufficient; we have yet to encounter a performance problem that Bagwell-style persistent data structures would have solved.
The simplest example would be a persistent list. Think you first create a list [c,d,e]. You can safely share references to that. Then you attach a to one version and b to another:
a \
c-d-e
b /
The memory for the original list is still shared!
You can generalize that to trees and use that to implement, say, persistent hashmaps that can share data.
This is also awesome for parallelization where you want to share data but don't need synchronization!
The main benefit I derive from immutability in js is identity comparison (I.E. react's shouldComponentUpdate), I don't find the small performance hit of cloning to make a difference.
First, TypeScript type definitions are almost the same as standard JavaScript JSDoc type annotations, so (to the level they're used in Immutable.js), yes, people should learn them.
Second, TypeScript should be considered a best practice for nontrivial JavaScript development in 2016. And pretty much any app that would benefit from Immutable.js would be "nontrivial" by that definition.
Third, everyone using JavaScript or TypeScript knows what a Map is, I would hope. The docs for it that read "Immutable Map is an unordered Iterable.Keyed of (key, value) pairs with O(log32 N) gets and O(log32 N) persistent sets." are perfectly legible to me, having never used Immutable.js, just because I had a few undergrad (not "a Ph.D.") computer science classes. I don't even have a computer science degree [0] at all.
I actually personally despise lowest-common-denominator docs: Docs that tell me "what a Map is and how to use it" when what I want to know are things like what its get and set performance implications are, and whether you can iterate over it, and whether that iteration will be ordered, and so forth.
Sure, create a user's guide, but don't pick on the reference manual for being concise.
FWIW, I'm not a big fan of Immutable.js or immutable structures at all. I'm too performance-oriented to want a layer like that between me and the underlying data structures. Criticize it for being unmaintained [1], sure, but not for having docs that aren't aimed at beginners.
I feel the same about lowest common denominator, and even though facebook and google documentation can be on the far end of the austere spectrum, they are still putting out incredible libs for free.
For your comment about performance, immutable structure being comparable by reference can provide huge gains in read and re-use heavy environments, thanks to memoization-like techniques.
>For your comment about performance, immutable structure being comparable by reference can provide huge gains in read and re-use heavy environments, thanks to memoization-like techniques.
Fair enough. I'm often doing things to graphics, and the concept of using immutable data when the data is a bitmap with 4Mb of pixels, and you're trying to draw hundreds of sprites or shapes to it...well, let's just say that immutable doesn't make sense for that.
Even when I'm just working on a game, though, the more frequent allocations required by copy-on-write structures means more fragmentation of the heap and more deallocations later. Ideally during runtime nothing gets allocated.
You may even be right that the amortized speed of using immutable structures is the same as doing it with mutable data. But anything that adds a lot of allocations and therefore adds to the frequency of garbage collection will cause (or increase) jankiness in a game.
You have 16.66ms to accomplish all the work for a frame. If a garbage collector comes along and steals even 10ms, if you can't do the remaining work in 6.6ms, it will skip a frame, and users will see it.
And my current game needs to run in a browser, at least mostly. So here I am. :)
Documentation should absolutely be technical, exhaustive, and.. I dunno what to call it, "written for people who know what they're doing."
Then have a load of general examples to cover the non-experts and initiates. There's no faster way to learn how to begin using a library than to look at some complete examples. That's the one thing that Immutable documentation misses. I wish there was a "Show example" link on almost every non-trivial method.
But at least they shouldn't use phrases like `persistent sets` in the documentation. I confused that with the datatype on my first reading. Technical details are necessary but that is just creating unnecessary confusion. Compare that to the haskell documentation:
A map from hashable keys to values. A map cannot contain duplicate keys; each key can map to at most one value. A HashMap makes no guarantees as to the order of its elements.
The implementation is based on hash array mapped tries. A HashMap is often faster than other tree-based set types, especially when key comparison is expensive, as in the case of strings.
Many operations have a average-case complexity of O(log n). The implementation uses a large base (i.e. 16) so in practice these operations are constant time.
I've never seen code in which someone actually uses Immutable.js in a way that's superior than using the built-ins. In fact even this introduction the examples seem terribly contrived.
I'm not convinced this library is really that useful in a dynamic language. Considering the top 2 immutable libraries (Mori and now Immutable.js) are both essentially abandoned I get the feeling the public opinion is likely the same.
The decision axis for something like Mori or Immutable is not so much static versus dynamic typing but imperative versus functional code. Immutable/Mori lends itself handily to cases where you are writing a lot of pure functions that output a different state rather than manipulate an existing state. Immutable/Mori can help you ensure that your pure functions stay pure by making it almost impossible to mutate an existing state.
If you are less concerned with pure functions and happy with largely imperative or hybrid imperative code, then yes it is difficult to find a compelling example for Immutable.
(Immutable seems almost entirely stable at this point and covers just about the entire necessary API surface, so I think it's a case to call it "mature" rather than "abandoned".)
> If you are less concerned with pure functions and happy with largely imperative or hybrid imperative code, then yes it is difficult to find a compelling example for Immutable.
Meh, I don't see a lot of usage even with pure functions. JavaScript never really had any protections in it (minus the new-ish const and Object.freeze()) so most developers I know simply write as if something else has access to an object then it will mess with it so everything gets architected accordingly. Just seems to me a mostly non-issue in the JavaScript world.
> so I think it's a case to call it "mature" rather than "abandoned".
No I would most certainly call it abandoned. They have countless issues and pull requests from over half a year ago without even a single response from a human. While it may be a mature product, I would still call it abandoned.
Just because JS historically hasn't had too many protections built in doesn't mean that adding protections from a library aren't useful. Especially if you are coding from a functional language perspective (and not everyone believes this but JS can be a rather good functional language if you let it; it's not terribly far removed from the ML/OCaml family).
For what it is worth, anecdotally, I've been doing a lot of heavy work with RxJS observable pipelines (in a CycleJS-based application) where Immutable has absolutely made a big difference in performance and stability of complex "four dimensional" (lots of changes over time) "shared nothing" (pure) state tracking.
That may be a use of the language and a complex learning curve of a framework setup in which you never plan to work, but it's definitely an "issue" where libraries like Immutable and Mori turn out to be extremely useful (whether or not you think they are abandoned).
I've heard similar anecdotes from people using various combinations of things like React and Redux with Immutable.
Fair enough. I wouldn't be surprised a lot of folks found good uses for Immutable.js. I just hadn't seen anything that would appear to benefit from it in my travels and I think having immutability is a bit oversold IMO :)
50 comments
[ 0.23 ms ] story [ 106 ms ] thread"the documentation describes the API in TypeScript, and then provides no examples at all! So the average JavaScripter can’t understand what the API looks like"
And:
"Add into the mix the way the documentation casually drifts into hard-core Computer Science and algorithmic discussions at inappropriate places, and you’re left with documentation that only the documentation’s auto-generator understands.
Don’t believe me? Just see this example describing Map, one of the most-used Immutable data structures:
Immutable Map is an unordered Iterable.Keyed of (key, value) pairs with O(log32 N) gets and O(log32 N) persistent sets.
OK. Er, of course it is."
If you don't know what you're doing, and you just want to know how to do it, everyone ends up suffering. And I don't know much about Typescript, but isn't it javascript with types? If the average javascripter can't figure out what's going on there...
It seems like websites are dead pretty often on HN, but on sites like Reddit where I assume there is a magnitude more traffic they seem to hold up pretty well (with some exceptions).
So what's going on here? Does HN really have a bunch of silent viewers? Or is it something more benign like sites that get submitted are often smaller?
+ Most of my time on Reddit is specific (small-ish) subreddits, vs. HN where you can basically just look at the front page.
With the multiple-magnitude less comments and votes that HN submissions get, I can't imagine they can get anywhere near that unless HN has a LOT more non-contributing types.
A lot of people still think using WordPress or even Rails for site generation is fine, but both are hard to scale. And if the site is small or academic, it will fall over with not too much traffic.
I wrote a rant [1] about this a couple of weeks ago. I can guarantee that my site will never have a "Database Connection Failed" error (now), because there's no database backing it.
Even better would be if I moved hosting to S3/CloudFront. Dirt cheap, and Amazon isn't going to fall over even if a site hits Reddit's front page. I might not like the bill I get at the end of the month if it really goes crazy, though.
[1] https://realmensch.org/2016/11/22/drupal-is-dead-long-live-s...
You must be pretty young to not remember it happening to lots of sites regularly for a couple of years.
Part of the reason imgur took off was because people would repost content to imgur when Reddit took the source down, the web comic or whatever.
I was just curious about the reason why. Like does HN have a large "silent" group, or is it something like that on HN sites climb much faster so I see them when they are down before they've had a chance to recover.
Hmm I wonder if there are any good traffic statistics. I had a library (msngr.js) hit the front page once over a year or so ago and while it helped me gain a bunch of GitHub stars looking at the traffic itself it wasn't really much at all. In fact it was significantly less than I would have expected. Granted maybe my library just wasn't that interesting to people but I would love to see somewhere with some good HN numbers.
When I posted a recent high ranking blog post[0], I received around 18,000 views over the next 24 hours according to Google Analytics. I don't believe this covers a lot of the bots and associated traffic that also crawled the site.
This amount is nothing for a Jekyll site, I had CPU hovering at around 4%, with a series of services also running on this server. This is, imo, where a "hug of death" should end.
I did however at the time, have several colleagues in web development express shock and awe at the fact the site stayed online with traffic levels such as this. Multiple people tried to school me on the need for Cloudflare at this incredible scale.
A lot of web developers think about "scale" in terms of many bloated CMS platforms, and it is with no surprise that the site in question is running Wordpress.
We had a friend's site a while back where we worked out, with just two desktops and spamming "F5" on the keyboard, we could take the site offline, and take several minutes to recover from after the fact. He went and posted for help on Reddit, and sure enough, the consensus was that his experience involved far more traffic than any website could reasonably be expected to handle.
Your answer therefore lies not in the silent HN users, but in the unusually poor performance of popular CMSs. And although I'm using Wordpress, it's not alone in this situation. [0] https://news.ycombinator.com/item?id=12973181
I'm saying that the frequency I see the "HN hug of death" is much more than the "Reddit hug of death" while having many of the same kinds of sites (the "bloated CMS platforms" you talk about).
@alexhayes it is a common color palette, I was going to link the most common place where I find it but I forgot about it, haha.
The author spoke about performance and immutability-data structures like Directional Acyclic Graphs and Trie.
Now neither of them are really maintained.
For a lot of usages, something like Ramda or Lodash/FP will do the trick (Ramda lenses or Lodash/FP's get and set methods work great to handle immutable data structures), but if you really wanted structural sharing and stuff, now you're kindda stuck.
https://github.com/brianneisler/mudash
I went through the pull requests and checked 5 or so that were open for a long time, all of them were glaringly missing something.
Some do not pass tests, some have obvious styling issues, some people haven't signed the contributor agreement, some offer big changes with very little reasoning behind it.
I also prefer projects that are more explicit about the reason something is rejected and answer RTFM-type issues, but this is not a requirement to be a successful project.
Instead I ended up just deepFreezing my data (only in development) and wrote a bunch of pure functions which perform all the important array/object functions but return a new array/object instead of mutating. It was a really great exercise in functional programming and I'd recommend it to anyone wanting immutable data and to understand immutable programming styles.
https://github.com/rtfeldman/seamless-immutable
They are all just a few lines, so they make for great practice to write yourself.
Makes it very simple to use it anywhere you'd use a plain array or object, rather then always having to use immutable.js's api.
I.E. if I have {a:{aa:"1"},b:"cc"} and I change b, then {aa:"1"} will not be deep copied.
Are you talking about something like keeping a reference to the parent and sending lookups up the chain (with a prototype or some such?)
> Persistent data structures are different, as their performance improvements are passive. Although seamless-immutable does not (and cannot, while maintaining its backwards compatibility with vanilla JS collections) use things like VLists under the hood, its cloning functions—such as merge—only bother to make shallow copies, as shallow and deep copies of immutable values are equivalent. In practice, this simple passive optimization has been sufficient; we have yet to encounter a performance problem that Bagwell-style persistent data structures would have solved.
from: http://tech.noredink.com/post/107617838018/switching-from-im...
This is also awesome for parallelization where you want to share data but don't need synchronization!
Second, TypeScript should be considered a best practice for nontrivial JavaScript development in 2016. And pretty much any app that would benefit from Immutable.js would be "nontrivial" by that definition.
Third, everyone using JavaScript or TypeScript knows what a Map is, I would hope. The docs for it that read "Immutable Map is an unordered Iterable.Keyed of (key, value) pairs with O(log32 N) gets and O(log32 N) persistent sets." are perfectly legible to me, having never used Immutable.js, just because I had a few undergrad (not "a Ph.D.") computer science classes. I don't even have a computer science degree [0] at all.
I actually personally despise lowest-common-denominator docs: Docs that tell me "what a Map is and how to use it" when what I want to know are things like what its get and set performance implications are, and whether you can iterate over it, and whether that iteration will be ordered, and so forth.
Sure, create a user's guide, but don't pick on the reference manual for being concise.
FWIW, I'm not a big fan of Immutable.js or immutable structures at all. I'm too performance-oriented to want a layer like that between me and the underlying data structures. Criticize it for being unmaintained [1], sure, but not for having docs that aren't aimed at beginners.
[0] My degree is a B.S. in Cognitive Science [1] https://news.ycombinator.com/item?id=13051458
For your comment about performance, immutable structure being comparable by reference can provide huge gains in read and re-use heavy environments, thanks to memoization-like techniques.
Fair enough. I'm often doing things to graphics, and the concept of using immutable data when the data is a bitmap with 4Mb of pixels, and you're trying to draw hundreds of sprites or shapes to it...well, let's just say that immutable doesn't make sense for that.
Even when I'm just working on a game, though, the more frequent allocations required by copy-on-write structures means more fragmentation of the heap and more deallocations later. Ideally during runtime nothing gets allocated.
You may even be right that the amortized speed of using immutable structures is the same as doing it with mutable data. But anything that adds a lot of allocations and therefore adds to the frequency of garbage collection will cause (or increase) jankiness in a game.
You have 16.66ms to accomplish all the work for a frame. If a garbage collector comes along and steals even 10ms, if you can't do the remaining work in 6.6ms, it will skip a frame, and users will see it.
And my current game needs to run in a browser, at least mostly. So here I am. :)
Then have a load of general examples to cover the non-experts and initiates. There's no faster way to learn how to begin using a library than to look at some complete examples. That's the one thing that Immutable documentation misses. I wish there was a "Show example" link on almost every non-trivial method.
A map from hashable keys to values. A map cannot contain duplicate keys; each key can map to at most one value. A HashMap makes no guarantees as to the order of its elements.
The implementation is based on hash array mapped tries. A HashMap is often faster than other tree-based set types, especially when key comparison is expensive, as in the case of strings.
Many operations have a average-case complexity of O(log n). The implementation uses a large base (i.e. 16) so in practice these operations are constant time.
I'm not convinced this library is really that useful in a dynamic language. Considering the top 2 immutable libraries (Mori and now Immutable.js) are both essentially abandoned I get the feeling the public opinion is likely the same.
If you are less concerned with pure functions and happy with largely imperative or hybrid imperative code, then yes it is difficult to find a compelling example for Immutable.
(Immutable seems almost entirely stable at this point and covers just about the entire necessary API surface, so I think it's a case to call it "mature" rather than "abandoned".)
Meh, I don't see a lot of usage even with pure functions. JavaScript never really had any protections in it (minus the new-ish const and Object.freeze()) so most developers I know simply write as if something else has access to an object then it will mess with it so everything gets architected accordingly. Just seems to me a mostly non-issue in the JavaScript world.
> so I think it's a case to call it "mature" rather than "abandoned".
No I would most certainly call it abandoned. They have countless issues and pull requests from over half a year ago without even a single response from a human. While it may be a mature product, I would still call it abandoned.
For what it is worth, anecdotally, I've been doing a lot of heavy work with RxJS observable pipelines (in a CycleJS-based application) where Immutable has absolutely made a big difference in performance and stability of complex "four dimensional" (lots of changes over time) "shared nothing" (pure) state tracking.
That may be a use of the language and a complex learning curve of a framework setup in which you never plan to work, but it's definitely an "issue" where libraries like Immutable and Mori turn out to be extremely useful (whether or not you think they are abandoned).
I've heard similar anecdotes from people using various combinations of things like React and Redux with Immutable.