Refactoring to Immutability - Kevlin Henney

Поделиться
HTML-код
  • Опубликовано: 25 ноя 2024
  • НаукаНаука

Комментарии • 100

  • @nonchip
    @nonchip 4 года назад +122

    loved that array example, because it makes you realize that even an array is just that illusion, since you can happily have multiple pointers to the same piece of physical memory right before you screw everythiSegmentation Fault
    Received signal 11 (SIGSEGV), core dumped.

  • @UCH6H9FiXnPsuMhyIKDOlsZA
    @UCH6H9FiXnPsuMhyIKDOlsZA 2 года назад +23

    "I had a problem in my code. I used regular expressions to solve it, and now I have problem*" is such a brilliant formulation of the classic quote. You have somewhere between zero and infinity problems after using regular expressions.

  • @juaningles996
    @juaningles996 2 года назад +8

    Confucius say: "Man with clock always knows what time it is. Man with two clocks is never quite certain which time it is."

  • @jimifriis4507
    @jimifriis4507 6 лет назад +55

    Kevlin Henney really is a true master of explaining software patterns in a pragmatic and easy to understand language coupled to architecture and other great examples from history and art. Also he is a nice guy if you have the privilege to talk to him in person :)
    He is one of my top ten house goods in my world of software development.

    • @JosiahWarren
      @JosiahWarren 6 лет назад +1

      this guy is pleasant to watch but i don't think he is actively developing/coding and he is left far behind at this point

    • @illusion466
      @illusion466 4 года назад +14

      @@JosiahWarren nonsense. This guy is still well and truly ahead of 90% of devs out there. I don't think you realise how bad people are at their job

  • @stuartcoyle1626
    @stuartcoyle1626 3 года назад +43

    "Asking a question should not change the answer." - Obviously Bertrand Meyer had never studied Quantum Mechanics.

    • @RobBCactive
      @RobBCactive 3 года назад +1

      Or called rand() 😁😁

    • @JulianSildenLanglo
      @JulianSildenLanglo 2 года назад +2

      "How many times have I asked you this question?"

    • @alvaromoe
      @alvaromoe 2 года назад

      Nor been interested in the current time.

  • @covoeus
    @covoeus 2 года назад +1

    The Persistent Stack example was enlightening!

  • @dwhxyz
    @dwhxyz 4 года назад +11

    I think these types of talks would help people understand why immutability can be a good thing by explaining why languages choose to make strings immutable. I've found asking why strings are an immutable reference type in interviews (C#) quite interesting, everyone I've asked this question to is stumped and this highlights to me that most developers don't understand or really think about why being able to change state can lead to issues especially when multiple developers are working on something or when a bug is fixed/additional functionality is worked on at a later date.

    • @JulianSildenLanglo
      @JulianSildenLanglo 2 года назад

      Thanks for the question, I'll have to give it a think.

    • @Blaisem
      @Blaisem 2 года назад +1

      Why are strings immutable?

  • @aMulliganStew
    @aMulliganStew 4 года назад +5

    This weekend I applied some of these ideas to my favorite personal toy-program, Conway's Game of Life. I like it!

  • @SolomonUcko
    @SolomonUcko 4 года назад +38

    IMO, Rust solves the problem of mutable vs immutable perfectly: you can still use an imperative style, but you have to be explicit about when you are sharing mutable state.

    • @streetwear37
      @streetwear37 4 года назад +4

      Haha.. rust just stole that from so many other languages.

    • @TheMrKeksLp
      @TheMrKeksLp 4 года назад +12

      @@streetwear37 Rust didn't steal it's complete memory safety while being as fast as C from other languages though, did it

    • @nonchip
      @nonchip 3 года назад +2

      @@TheMrKeksLp no you're right it didn't steal it, because it doesn't have that. `unsafe` EVERYWHERE. by design.

    • @gabrielmachado5708
      @gabrielmachado5708 3 года назад +4

      @@nonchip the unsafe is for dereferencing raw pointers, it does not turn off the borrow checker.

    • @ed_iz_ed
      @ed_iz_ed 2 года назад +4

      @@nonchip unsafe is for writing provable modules that are safe to use

  • @antoniocolagrande9010
    @antoniocolagrande9010 4 года назад +11

    "this is just like putting needles in your eyes but without the fun"

  • @KoenZyxYssel
    @KoenZyxYssel 4 года назад +22

    "mother was a psychotherapist and it has had no effect on me whatsoever" /sarcasm
    As a software engineer with a psychotherapist mother this hits me in the solar plexus.

  • @timseguine2
    @timseguine2 4 года назад +8

    I enjoy watching Kevlin's talks and I actually agree with a lot of what he has to say. Something undefinable rubs me the wrong way about him though.

    • @shoulderstack5527
      @shoulderstack5527 4 года назад +2

      I often watch talks by people I don't like because sometimes I realise I had misjudged them, and you can learn a lot that way. But I always get the same thing from this guy... pleasant waffle that seems to be important or profound but actually never makes a real point. For example at 1:50 he talks about platonic solids. That is classic Henney: profound waffle to no point... ie the Greek's concept of immutable solids adds nothing to the argument, and is not actually related to the type of immutability in question; it's just the same word in a different context.
      I can't stand his talks but apparently he is a very nice guy.

    • @davidwagstaff5494
      @davidwagstaff5494 4 года назад +1

      @Tim Sequine Me too. I think a comparison will help. Kevlin is like House from the TV series House M.D. He's smart and informative, and enjoys pointing out how stupid other people are. The latter aspect is funny at first, and then gets tiring after a while. I quit watching House after a couple of seasons. Like House who nearly kills the patient with his own mistakes, Kevlin doesn't get less arrogant in time. Not worth my time to point out Kevlin's coding and process mistakes. I do believe he could take his presentations to the next level by adding humility.
      When I listen to the meta message of all his presentations (I watch them all), I hear:
      I'm smart. You're stupid. That makes me right. Hire me as your next consultant if you want to do it right.
      Seriously, listen for how many times in any of his presentations he uses the words "wrong" to describe others, and "right" to describe himself.
      The condescension factor is real, and it's amplified, at least for American ears, by an English accent. It's hard to find a Disney animation where the condescending villain is not instantly identified by an English accent.

    • @davidwagstaff5494
      @davidwagstaff5494 4 года назад +1

      @ shoulder stack Personally I quite like the random side trips. I do agree they are unrelated and add nothing to the argument.
      Maybe he is nice in private. I wouldn't know. Based on his public speaking style, I doubt it. I predict he's still a pompous ass in private. I'm sure he'd correct me. "It's 'arse'. You must learn to say and spell it correctly." I could be wrong. I hope so.

    • @SimGunther
      @SimGunther 3 года назад

      @@davidwagstaff5494 The other meta message is "give credit where credit was due and acknowledge most of your 'innovations' are from the 1960s. What else can we do with computers? I'm sick of reliving the '60s, where most people had a clue on what to innovate! BTW engrain this sharing quadrant into your brain. I'm sure you'll need it someday..."

  • @sodiboo
    @sodiboo 3 года назад +4

    36:10 off the top of my head:
    - Python: you can do some real horrible shit in the operator overloads because it's dynamically typed
    - Swift: Compound assignment operators are overloaded separately from the actual operators. To support this, operators can have inout parameters (ref in C#), and they are implicitly passed as such when used (so you can not only change object state, but reassign the whole variable to whatever you damn well please)

  • @trejkaz
    @trejkaz 2 года назад +4

    I too wish more languages would take on units of measure as part of the type system. I didn't know F# had that.

    • @lepidoptera9337
      @lepidoptera9337 Год назад

      If you think units are a good idea, then you weren't paying attention in at least three disciplines: physics, numerical math and computer science. Instead you should be normalizing your data as soon as possible. That way all of your "units" can only go wrong in two places, at most: at the input and the output.

  • @Erhannis
    @Erhannis 2 года назад +3

    29:12 It's not just "a few characters typing"; I've seen these things get threaded through function after function after function, 5 levels deep, through the whole program.

    • @lepidoptera9337
      @lepidoptera9337 Год назад +1

      Only five? You were lucky. I did twelve to myself once. That was just around the time when I gave up on the idea that this was a good idea. I still have to ask myself if that was a coincidence or an ape actually learned a better way to use his tools... ;-)

  • @DevToolsMadeSimple
    @DevToolsMadeSimple Год назад

    "Your code should be reasonable" . While this idea certainly sounds like a lack of ambission, it shouldn't. At the end of the day, the spirit behind the latest best practices stems from this idea of "reasonability". And any innovation that goes against it eventually evolves so as to become "reasonable", or it gets replaced by one that does.

  • @timh.6872
    @timh.6872 6 лет назад +11

    I think the immutability fans miss a crucial aspect of how the idea gets implemented. Immutable doesn't mean that state never changes, but that there is an essential data "flow" from immutable inputs to well defined outputs, which could change from what it was because one of the inputs changed (not universally immutable, only locally immutable).
    The flipping of data from mutable output to immutable input is where we can get a lot of the performance boosts, but only if we're doing immutable everywhere.

    • @ozjuanpa
      @ozjuanpa 4 года назад

      @rasuru Haskell wiki

  • @cameronduffy6979
    @cameronduffy6979 2 года назад +1

    I'm in to any insights or beneficial behaviours I can immediately deploy and its amusing to listen to Kevlin's polemics.
    I'm a big fan of software anthropo-archaeology so seeing that slim Lisp 1.5 manual did bring a tear to the eye (the one with needles in it)
    Anyway while I would rather drink my own vomit than perform test driven development, banning the IF statement has become a moral imperative.

  • @peterw.gstettner7737
    @peterw.gstettner7737 6 лет назад +11

    at around 53:45: "… and now I have *-problems …", did I mention, that I like recursive jokes?

    • @rafeu2288
      @rafeu2288 4 года назад +1

      Isn't to say "now I have {0 or more} problems"? Not sure to see the recursion here, but I may be mistaken. ^^

  • @HollywoodCameraWork
    @HollywoodCameraWork 2 года назад +2

    Red is not the universal color of danger. In Italy, it's routinely used for "Order Placed Successfully!"

  • @waynemv
    @waynemv 4 года назад

    How many times have you been asked this question?

  • @zumalifeguard3493
    @zumalifeguard3493 8 месяцев назад

    This is a great if you're a beginner, and six years ago this was great. The problem is a lot of people have moved on from this, and there is a whole other list of lessons to be learned that are introduced by using this approach to coding.
    For instance, how multiple threads modify their own copy of an immutable data-structure and have each of their changes get merged into the master version.
    Second is that all the places where we still do loops because we're not transforming data, but instead issuing commands, eg. I need to launch 50 rockets. And also in the middle of transforming, you ma want to update status on the client screen, or you want to log the data one can monitor the results. There's different philosophies to this, including assuming logging and status updates are outside the transformation domain. That works, but is not the only option.
    What we don't have is a robust debate about these various things. Instead what we have is yet another presentation such as this one, still being created that's about "hey don't use loops"

  • @7th_CAV_Trooper
    @7th_CAV_Trooper 5 лет назад +6

    What is the nuget package with all these awesome immutable collection ideas already implemented for me?

    • @7th_CAV_Trooper
      @7th_CAV_Trooper 3 года назад +3

      2 years later I have an answer - they're part of c# 8.

  • @superpcstation
    @superpcstation 6 лет назад +4

    Please post higher resolutions

  • @casperes0912
    @casperes0912 4 года назад +1

    How dare you, Kevlin?! I am a Timelord. I was woven on Gallifrey

  • @ImperatorZed
    @ImperatorZed 2 года назад

    What time is it?
    What time is it?
    Whoops

  • @GeorgeTsiros
    @GeorgeTsiros 3 года назад

    17:15 128 MB and he was worried? 😂 ShellOS is a preemptive multitasking operating system for a calculator with 128 KILObytes of ram...

  • @RoamingAdhocrat
    @RoamingAdhocrat 6 лет назад +2

    Time is a tool you can put on the wall, or wear it on your rizd.
    The past is far behind us - the future doesn't exist.

    • @illusion466
      @illusion466 4 года назад

      Come on guys, stop mucking around

  • @jakubl8271
    @jakubl8271 4 года назад +1

    Nice example, except that now() isn't constant. So passing the now() value as an argument is a thin ice ((eager) argument evaluation moment vs moment that value is being used), and having a wish to call now() twice with a function makes ice not existing at all.

    • @TheRiskyChance
      @TheRiskyChance 2 года назад +2

      If you need to use now() twice, pass the function itself ad an argumrnt rather than the function's output.

  • @FalcoGer
    @FalcoGer 2 года назад +1

    So let me get this straight and do a real world analogy of what you just proposed
    You buy a clock and make the vendor (constructor) set the clock to the current time. Then you make space on your wall to hang it up (allocate memory (though technically that's the first step)). So if someone wants to know the time, they don't look at the clock (access it by reference), you instead take the clock off the wall go to the vendor and make him give you a second, identical clock (construct a new clock object with the same values). You give that clock to the person who wants to know the time (transfer of ownership only for the copy).
    Then the inevitable happens and a second passes by. Your clock now shows the wrong time. Instead of updating the clock (updating the values in place inside your clock object), you take the clock to the vendor and create a second clock (constructor, new memory allocation, copy values), only with the extra second on the display. Then you go home, pull the old clock from the wall and put the new clock in it's place (assign your clock variable the new reference to the new clock object). You put the old clock onto a garbage pile of clocks until eventually and non deterministically a garbage truck comes by to collect them all (gc collects non referenced clocks).
    Did I get that right? Because that's about as ridiculous as you can make it just so that clocks are never changed. Clocks are meant to change. A Time value might not change. But clocks are. The reasonable thing to do would be to have the clock return an immutable time object when you ask for it. Aka
    ```c++
    class Clock {
    private:
    Time time;
    [...]
    public:
    const Time getTime() const { return Time(this->time); }
    [...]
    };
    class Time {
    private:
    int hour;
    int minute;
    public:
    Time(int hour, int minute) { [bounds checking and assignment here] }
    Time(const Time& time) { [assignment here] }
    [...]
    ```
    You just declare your return type const and voila, immutable. a const type can only call const declared functions. And const declared functions may never call non const functions or change members. no need to do crazy stuff.

    • @Danagon1
      @Danagon1 2 года назад +1

      So if you just rename the class to Time instead of Clock you're okay with it? I think the class is supposed to represent time values, so maybe clock is just unfortunate naming. Also, you don't create a new copy when someone just wants to look at the clock. Only when they want to change the clock you give them a new clock to play with.

    • @ankor7625
      @ankor7625 2 года назад

      @@Danagon1 If you rename it to Time then functions nextHour and nextMinute become kinda hard to reason about - why does one need to increase the time by an minute or hour (I would understand if it was something like addPeriod)? Existence of those functions shows that it is not a representation of time, but representation of a time counting device - essentially clock.

    • @lepidoptera9337
      @lepidoptera9337 Год назад

      @@ankor7625 Time is that which the clocks show. In physics you have to learn to reason about the behavior of clocks that are in motion relative to each other. In CS I would suggest not to try that because it's hard (the only software that I know of that can't get around that hardship is GPS firmware).

  • @lepidoptera9337
    @lepidoptera9337 Год назад

    If you put state into a class, then you are a fool. If you put state into an FP program then you stop having an FP program. ;-)

  • @osten_petersson
    @osten_petersson 3 года назад

    technics 1200

  • @streetwear37
    @streetwear37 4 года назад +1

    So to summaries an hour of talk, kill C# use F# (for .Net)
    F# can't do more than C# in respect to computability. But it can do more things in respect to optimization, and your coding practice if you stay within the functional paradigm part for the most part of your code.
    A rather good comparison. Assume you build a house let's call that house C#, it works but a long the way you have to alter the house because your needs changes. I.e. you get a car, kids and such. It works but it is not pretty or effecient.
    Okay 20-30 years later you get a new neighbor, he to build a new house let's call that F#. From technical specification it can exactly the same as your house, the only difference is that all the extra you put into your house came by default, hence it is designet into making the house pretty and effecient to live in.
    That is mostly the differences between C# and F#. Years of research of language design and complaints about C#. Indentation do make code more readable than enclosement.
    A language that is build around a very strong type system do help you get less bugs at run time, and easy bug tracing when writing code. Immutable values does make 'constant copy propagation' code an other type of optimization more common, because it takes a problem of reference counting from a graph problem to making it a simple counting problem.
    Explicit mutable declaretion, does enhance readability and understandability of the code, and forces the coder more offent than explicit immutability declaretion to do so. Since a mutable value can stay the same through a life cycle, (you can ignore declaring a value 'const') but a immutable can't change. (You cannot ignore declaring a value 'mutable') Hence telling a reader of what to expect without looking through hundreds to thousand if not millions lines of code to track if a value change over time. To looking at that line of code and knowing.
    Replacing loops with map, filter, fold and scan, eliminates index mismatching. And make the code more understandable.
    I.e.
    Map : we transform a collection of elements of type 'a to a collection of elements of type 'b.
    Filter : under some predicatic (function) filter the collection such that only those where the predicate holds are returned.
    Fold : given a collection of element of type 'a, transform it into a value of type 'b. (Map is strict subset of this) think of you putting a IKEA furniture together, taking a collection of pieces and folding them together to an whole. (Taking it from each other is also a fold operation)
    Scan: same as fold just give me a full collection containing each iteration of fold.

  • @bocckoka
    @bocckoka 5 лет назад +11

    that's not the pythonic way. if you want something to be immutable, just don't change it.

    • @TheMrKeksLp
      @TheMrKeksLp 4 года назад +7

      This is why I hate Python

    • @dylanjonesSD
      @dylanjonesSD 2 года назад +1

      Haha, actually, you just make it immutable. You would just use the property decorator to add setters that throw errors and instead of initializing using __init__ you would overload the constructor (__new__)

  • @LucKyStyleRu
    @LucKyStyleRu 6 лет назад +9

    Completely disagree about the interface naming showed here. When i look at a source code and see IRepository i immediately know that is an interface and nothing else.
    That would be really confusing to me:
    ==========ExampleContext.cs==========
    class *ExampleContext* {
    private readonly *Repository* _repository; // is this an interface or a class? who the hell knows?
    }
    ==========ExampleContext.cs==========

    • @ddanielsandberg
      @ddanielsandberg 6 лет назад +17

      He is exactly right. As he is saying -"IClock is a failure of abstraction".
      It's NOT an interface and It's not a class - it's an abstraction. The client (ExampleContext) of your repository does not care if it's a concrete class, an abstract class or interface - it's an object following a contract.
      "// is this an interface or a class? who the hell knows?" - If you need to know, you missed the point of OO.

    • @Captain93Morgan
      @Captain93Morgan 6 лет назад +5

      Dmitry Aph but in this position it's completely irrelevant whether it is one or the other

    • @timh.6872
      @timh.6872 6 лет назад +4

      Classes are structs with an implicit interface, or alternately an interface with a default implementation. The question "Is this a class or an interface?" should have the answer "yes". Languages that don't were not designed with both concepts in mind.

    • @FreeApophis
      @FreeApophis 5 лет назад +6

      Why do you care if it is a interface or a class? First: you only should program against interfaces anyway, so I hope it is an interface. And second: what is the difference if it would be a class and not an interface? Exactly: nothing.

    • @lincolnsand5127
      @lincolnsand5127 4 года назад +3

      @@FreeApophis Well. That's a really silly question. If I am implementing an interface, I need to know which is the interface and which is the concrete class. Having `IName` ensures that I know I am supposed to implement it where `NameSomething` ensures I'm not.

  • @ace100hyper3
    @ace100hyper3 6 лет назад +11

    What is unclear about strings in .NET? Whose terminology is confusing? In .NET strings are immutable reference types compared by value. This is how it should be for various reasons, which are beyond the scope of this trolling comment. Any class or struct that is immutable and compared by value ("has no identity") will be a "value object" in their terminology, they don't have to be value types (copied by value) to be value objects, reference type can satisfy these conditions too. There is nothing unclear except maybe repetition of the word "value". There is no such thing as "struct type" (good grief, programming 101), there is only "value type" and "reference type". It just so happens that structs are value types and classes are reference types in .NET.
    Maybe you guys should program a bit to shake the confusion away instead of just whining about programming conventions that don't make sense to you and showing textbook examples?
    I hope you guys made so much money talking bout "intro to functional programming". This craps is flooding youtube.

    • @striker865
      @striker865 6 лет назад +9

      I don't understand your point, you act as if Developers already know the majority of their code should be immutable. Take a look at the 5 most widely used langauges, Java, Python, C, Javascript and C#. None of those langauges have the default setting to be immutable, they all assume mutable. Therefore there is no way the majority of programmers embrace this concept, and we are going to see talk after talk until we either use langauges that embrace immutability or developers worldwide make this a standard.

    • @ace100hyper3
      @ace100hyper3 6 лет назад +3

      EDIT: This talk mostly isn't about immutability, it's preaching to the converted about values of good practices and personal opinions. Some of it is loosely connected to immutability but nothing you don't know already.
      @Everyone: It should be mutable, this is not the holy grail you're looking for. If any of these seminar junkies actually wrote a line of code in their life they'd realize this doesn't work. It is piss poor for performance and will slow you down more than the bugs correcting you'd _presumably_ be spending time on otherwise. Try it on your projects with real human colleagues and you'll see how quickly this line of thinking gets severely limiting, not to mention hard to debug. This is called mental masturbation. Real teams have their own patterns and practices that ensure the codebase does not get crappy. If you're in a crappy codebase, the new language or paradigm is not going to magically make it better. It will simply trade a set of known problems for a set of unknown problems. You give crappy people functional style and now you have more crappy code, just in functional style.
      @striker The reason these talks exist is not to make the coding world a better place, it is to raise awareness of someone or make money for someone. The reason anything in the world exists is because someone had a business model to make it. People are talking about functional because it is popular and gets lots of buzz. Next 3 years it will be something else, they just need to make a catchy name for it (serverless ?! wow that sounds revolutionary!) to get people enticed. These fads come and go from time to time.
      It might as well have been "back to procedural". In fact, he tried that too. People are looking for a holy grail... experience is the holy grail. Besides the warts in some languages, the existing paradigms are completely sufficient. The size of the codebase doesn't matter much, in fact in a well groomed codebase things get faster the more code you have. Watch Bob Martin talks, he's right about that part. It becomes about how quickly, reliably and how speedy you can make it. And people don't have the skills and experience because they started by copy pasting f-king JavaScript at 25.
      Come on guys, IFs confuse people and functional programs are easier to read... How much bullshit will you be sold?!

    • @striker865
      @striker865 6 лет назад +9

      I really... don't understand your point here. Why does it upset you he is sharing good practices and personal opinions? And are you saying immutable by default is the right way to go? And it is buggier to make things immutable? What kind of code base are you coming from??

    • @ViktorEngelmann
      @ViktorEngelmann 6 лет назад +14

      Locking mutexes is way slower and super confusing (have you ever debugged a cycle-lock?). And when you nest your error-testing if-then-elses for example, it does get confusing - especially when you try to exploit overlapping conditions. And don't tell me to use error-guards (if error then return false / throw exception at the beginning) I have worked under code guidelines that forbid using exceptions at all or a return anywhere other than at the end of the method - even the use of break and continue.
      I also love Bob Martins talks and I don't always agree with Henney, but in my experience, code that is more the way he suggests here, is more reliable (or becomes reliable faster), more maintainable and much shorter.
      But of course, yes, nothing beats experience.

    • @striker865
      @striker865 6 лет назад +5

      Viktor Engelmann couldn't agree more, mutex/locks are so much more complicated and slow than just like... Making it immutable.

  • @TheMrKeksLp
    @TheMrKeksLp 4 года назад +3

    Yawn, functional this functional that. Copying your data on every mutation is the lamest way imaginable of solving shared state

    • @brixomatic
      @brixomatic 4 года назад +4

      only you don't necessarily copy, but reference and patch.

    • @DylanYoung
      @DylanYoung 2 года назад +1

      You didn't watch the talk did you?
      Nor is it just about shared state, though this talk unfortunately doesn't touch on the other benefits of immutability.

  • @ericray7173
    @ericray7173 2 года назад

    What the hell are you all talking about lol

  • @itsfarseen
    @itsfarseen 2 года назад +2

    Boring. Nothing new here.

    • @julians.2597
      @julians.2597 2 года назад +1

      I believe that's the main point. It's nothing new, but people still seem to have problems grasping it

    • @0ptikGhost
      @0ptikGhost 2 года назад +1

      Too many modern languages leaving out these old concepts. As a professional you learn these things as you gain experience and learn how to do it well within your language of choice. These things are *not* obvious to recent college grads. Our modern languages and learning institutions are doing a disservice to future programmers. As a result many modern programmers are rediscovering or reinventing tools and techniques that are 40 - 60 years old.

  • @ryanmcinnis3607
    @ryanmcinnis3607 3 года назад

    The past tiger realistically tickle because debt controversly hug unlike a serious sandwich. terrible, spurious fiber

  • @johnzaky6487
    @johnzaky6487 4 года назад

    Yawn, functional this functional that. Copying your data on every mutation is the lamest way imaginable of solving shared state

    • @hocenplocas
      @hocenplocas 4 года назад +4

      Immutable-specific data structures exist for a reason.