Hacker News Comments on
React.js Conf 2015 - Immutable Data and React
Meta Developers
·
Youtube
·
17
HN points
·
8
HN comments
- This course is unranked · view top recommended courses
Hacker News Stories and Comments
All the comments and stories posted to Hacker News that reference this video.Lee Byron on Immutable/React/Flux: https://youtu.be/I7IdS-PbEgI“I only have a minute left, which is more than enough time to build the undo stack”
Most functional languages have immutable persistent data structures that don't require a linear copy and are fairly efficient.For example in clojure, sequences are implemented as 32-ary tries so insert/delete/update to any particular index will only cost around sizeOfNode * numParents=32 * log_32(n). This comes with a cost that indexing is now log_32(n) but it's usually a fair price to pay.
In javascript, immutable.js implement these same ideas (as least according to these talks where they talk about index tries and hash array mapped tries: https://youtu.be/I7IdS-PbEgI?t=456)
If you want native support, javascript engines are actually free to swap out their implementation of arrays! I know they already do depending on whether they think your array is sparse("holey") or not: https://github.com/v8/v8/blob/8.1.81/src/builtins/builtins-a.... I also vaguely recall someone saying that unshift (push to front) is automatically optimized by switching to a deque/circular buffer but I might be remembering wrong. Anyway, they can make these optimizations in a distant future but I don't think do today.
⬐ repsilat> Most functional languages have immutable persistent data structures that don't require a linear copy and are fairly efficient.This is true, but unfortunately those libraries/languages don't make use of that tree structure for "partial memoization" of derived data. They very well could, but they don't -- even when you use Immutable.js in a Redux app, and you use Reselect, your selectors will take linear time when you mutate one element in an object/array instead of taking constant- or log-time.
⬐ fyp⬐ hatch_qYea that's a good point. This matters when your derived data takes linear time to recompute. There are still techniques to make this work (but not automatically afaik). For example it's easy to make them efficient again if your computation is just an associative fold or reversible fold: https://sci-hub.tw/https://link.springer.com/chapter/10.1007...⬐ repsilatThat article talks about map and filter and fold, but I think there are also (trickier) ways to make joins and sorts work as well.I think it could be a great technique for a lot of things -- compilers and database views, in addition to front-end state.
immutableJS gives you false sense of immutability - never forget that you have intrinsic reflection in Javascript and the only thing to force immutability is Object.freeze() which makes things unusably slow.⬐ jkoudys⬐ bchernyOr you can enforce it with readonlys in TypeScript. Not enforced by the engine of course, so there's always the danger some 3rd party component could get its fingers in your objects, but any of the devs on your project will be prevented from modifying their objects directly.TS and immutablejs work together surprisingly well. One enforces immutability via static analysis, and the other creates (relatively) efficient datastructures predicated on the assumption of immutability.
⬐ hatch_qTS works well. But ImmutableJS is slow, really slow. https://jsperf.com/immutable-js-iteration⬐ jkoudysI wouldn't go by benchmarks run against a 100-length array of numbers. That's so small it's practically a tuple. Where immutable.js improves your perf is if you need to have very large (1M+) datasets, and/or need to keep references to those data over time for thing like undo, diffing, saving those diffs, etc. If you used a pure array that's 1M, that'd be over 64MB per array, so at just 10 levels of undo you could already exhaust your heap. Immutable.js would be barely over 64MB for hundreds of levels of undo, since it can rely on the last state being immutable it can store only the diffs.Immutable.js was a bad solution when it was used purely to enforce immutability. Unfortunately that's what its reputation became, but really it should be thought of as a lib that takes advantage of immutable data, not a lib that checks for immutability.
A great resource for understanding how persistent data structures are implemented is Okasaki’s Purely Functional Data Structures: https://www.amazon.com/Purely-Functional-Data-Structures-Oka...Also available as a free PDF: https://www.cs.cmu.edu/~rwh/theses/okasaki.pdf
I found the explanation from the Immutable JS presentation easier to understand when talking about Immutable data structures [0]
For anyone interested, there's a great conference talk on this topic by Lee Byron from Facebook: https://www.youtube.com/watch?v=I7IdS-PbEgI
I attacked the modern Javascript approach through first focusing on functional programming.1. Python + functional programming in Python
Python is hardly a pure functional language, but it's lovely and simple and has all the core concepts including list comprehensions. This leads you on to...
2. Haskell
If you want to find a pure functional solution to a Python problem, first search for the Haskell one and translate it. Then read Learn You a Haskell [0] which was the funniest programming book I ever read and almost, almost taught me about monads (I had it for a second, then tried to explain it in Python and all was lost)
Now you can relax cause the hard bit is done.
3. Read Javascript the Good Parts and only pay attention to the functional programming bits. Suddenly mentions of currying aren't so scary.
4. Work your way through the funfunfunction [1] videos, especially the functional playlist [2] and for added bonus he has videos where he works through the first few chapters of Learn You a Haskell.
Then you've got map, reduce, filter all completely under control. Now immutability makes more sense, arrow functions don't look so strange, promises are just friendly monads really and we all love those.
Now you've got Immutable.js [3], lodash, underscore all reasonable to understand.
React's moaning about state and pure functions makes reasonable sense.
5. Babel really isn't that hard. Just following the Meteor + React tutorial [5] got that all working without me really noticing. Then, holy moly you're all reacted up, with JSX and pure sweet smelling functions.
6. Follow some of Dan Abramov's excellent blog posts such as about getting eslint up and working in Sublime Text [4].
Yeah that's as far as I've got, but adding in Redux to this mix doesn't seem so scary, at least I understand the language now. Angular will just have to wait.
[0]: http://learnyouahaskell.com/ [1]: https://www.youtube.com/channel/UCO1cgjhGzsSYb1rsB4bFe4Q/ [2]: https://www.youtube.com/playlist?list=PL0zVEGEvSaeEd9hlmCXrk5yUyqUag-n84 [3]: https://www.youtube.com/watch?v=I7IdS-PbEgI [4]: https://medium.com/@dan_abramov/lint-like-it-s-2015-6987d44c5b48 [5]: https://www.meteor.com/tutorials/react/creating-an-app
@diegorbaquero you should watch that https://www.youtube.com/watch?v=I7IdS-PbEgI.The author spoke about performance and immutability-data structures like Directional Acyclic Graphs and Trie.
IMHO, one-way data flow + immutability competes with (beats ?) observed mutations in many use cases.See https://youtu.be/I7IdS-PbEgI, and more specifically https://youtu.be/I7IdS-PbEgI?t=21m29s
⬐ sooheonI recently read the re-frame ~manifesto~README[1] which is a compelling write up about that concept. Could you share some others initiatives in this vein?⬐ netgustoAlso: https://twitter.com/teozaurus/status/518071391959388160:D
⬐ dominotwYour views are still observing/reacting to changes in stores no?⬐ wereHamsterI have a library which builds on top of O.o [1]. I dig immutability but immutable.js is far from perfect, especially when used from within a strongly typed language:The type checker can not verify that `first.foo.bar` exists and is of type Number!first.setIn(["foo","val"], 500)
Avers plays nicely with TypeScript (it's actually written in TS). If I add proper property type annotations to the objects, TypeScript will warn me when I try to access or modify a property which doesn't exist.
It is true that O.o libraries modify the objects in-place. But that's only an issue if you consider those objects the ground source of truth. But there is a different way to look at it: Treat O.o just as a way to observe changes, but then apply them to immutable stores. Something which I may add support for in the future (see [2], "Immutable applyOperation").
Another way to look at it is: When you render the UI with React, you have to pass React the data (stores, objects) as well as a specification how it is allowed to modify the data. Avers sort of combines the two so you only have to pass around one reference which includes both. How you handle the changes (whether by mutating the objects in-place or applying them to immutable stores) is up to you.
[1]: https://github.com/wereHamster/avers [2]: https://caurea.org/2015/02/08/the-future-of-avers.html
⬐ rsuelzerAs an aside around dealing with properties that don't exist yet, I have found the following pattern very useful. It greatly reduces the number of checks I have to do in an if statement and has made my code more maintainable by reducing the amount of boilerplate code I need to write inside of functions.http://adripofjavascript.com/blog/drips/making-deep-property...
⬐ wereHamsterThat avoids runtime exceptions, but won't save you from typos.