1. 7

    I see kemitchell, I upvote. Is there anyone else hacking on OSS licensing? Your efforts are appreciated, Kyle.

    Like others, I’m defaulting to xGPL these days.

    1. 7

      I use appreciate their work, and the Blue Oak Model is a gem especially, as are much of their blogging, but very little is the licenses here are OSS, rather most are explicit attempts at business proprietary licensing, but in a generic way borrowed from OSS.

      1. 4

        Most of the lawyers here are also up to good hijinks: https://writing.kemitchell.com/lists/Blogroll.html

        None of the stuff mentioned in the blog post is my work alone!

        1. 2

          I wouldn’t count this as “hacking on” but I’ve become a fan of the UPL since I found out about it: https://lobste.rs/s/u0illx/universal_permissive_license

          1. -1

            I’m defaulting to CDDL these days just to keep xGPLers out of my projects. (Also, MIT-0 for those projects which I want to be wide-spread.)

            1. 4

              That… sounds very stupid? Why would you purposefully prohibit yourself from using any GPL code? You choose to be unable to dynamically link against GPL libraries, and to be unable to statically link against LGPL libraries, and for what? To make some imagined other people a bit less happy?

              1. 1

                Honestly, I have not missed any GPL library in the past few years. I think that this is a hypothetical problem, after all.

                Leaving this aside, I find the CDDL rather fitting for most of my projects which is a better reason, I guess.

          1. 8

            I don’t think I’m ever going to not hate Typescript. What’s worse is that I both feel it would most likely would keep things cleaner in the long run and it would help noobs get into my codebase more easily. It feels like a semi-enforced documentation step.

            But I hate it. I hate how it looks. I hate having a compiling step. I hate having to annotate everything. I hate how everyone thinks that you need it for modern development and that without it you’re coding in the stone ages. I hate that it’s really just suggesting types when I can just use any as void* which based on my aversion I almost always do whenever I’ve had to deal with it in the past. I even hate that the article’s author is using a ligature based font - and that one isn’t even fair.

            /rant

            If someone started a project with it I could understand why. It really does make a lot of sense. But I’ll never use it of my own free will.

            1. 3

              Some people may have thought I wrote the above rant (including about the font). What I really dislike is how it’s treated as defacto. When I see a team implement Haskell on the back-end because they value types but also strictness in managing IO, no any, and ergonomics composition for a functional code base, then say “yup, TypeScript and fp-ts is good enough for our front-end”.

              1. 2

                I mean, TS with strict mode, noUncheckedIndexedAccess, plus all the ESLint rules that forbid any and all other unsafety is getting pretty close to Haskell in terms of type safety IMO.

                1. 2

                  Out of curiosity, have you used Haskell professionally?

                  1. 2

                    No, although from what I gather from people who have, it’s used quite differently to Haskell in academic contexts. Much fewer weird tricks (lenses was the example they gave), and a willingness to accept IO in places where fundamentally it is necessary (e.g. managing application state shared across concurrency boundaries).

                  2. 2

                    Without an IO monad, do, and composition infix operators, it not close in ergonomics.

                    1. 2

                      Well, Promise is the equivalent of the IO monad, which makes async/await equivalent to do in that domain. Not having general monads for failure or immutable state is clunky though. Composition/infix can be emulated with “fluent” object interfaces.

                      So yes, they’re obviously very different languages, but the point is that TS can be a very safe, expressive type system if you use it right.

                      1. 1

                        I’d disagree, not that your perspective of similarity is wrong, but because those differences matter a lot to me. Having seen a lot of libraries with .pipe(), et.al. all over the place, it’s very hard to read when you know the author would rather be in a language where this style is supported first-class. Comparing Promise isn’t great either: it’s not synchronous, it’s immediately evoked when constructed so many thunk it, canceling is a pain and rarely supported, and the error handling with reject and catch is a mess across libraries instead of branching Result or Either.

                2. 2

                  Please note that I’ve used TS in many different contexts beyond your standard browser or node server and a portion of my frustration comes from trying to get TS running in atypical environments.

                  For me TS is still frustrating with new projects. I’ve found that the configuration for getting a new TS project up and running with tests and build targets is very complex and fragile. The few times I’ve tried to start with TS I found it cost me so much time in setup that I would have been better off sticking with plain JS. In addition, I have encountered runtime errors multiple times despite compiling in strict mode and using as much typing as possible.

                  Given this, I do think it does provide some minimal benefit around things like basic type and name errors being caught, that I think can be worthwhile for most projects to use.

                  1. 2

                    How much experience do you have with languages that require compilation? I ask, because my experience (not with Typescript, but in general) is that I tend to dislike dynamic languages (even though I love using Lua) because the types are so loose (I learned C early on in my career). I have a table in Lua, I have no idea what can be in it, whereas in C, I know because I can look up the structure definition.

                    1. 1

                      C++, Go, and Java. Java professionally. I dislike them all equally on the typing front. If anything it would be nice if types just magically sprung up after I’ve finished writing the rough draft of the code and had no enforcement until I’ve left the code base for a while. The thing is that while I’m in the code I know what I’m doing. It’s after I come back from working on something else I’m lost.

                      1. 1

                        Have you ever used languages with whole program type inference? (E.g., Haskell, F#) That might be what you are looking for.

                  1. 5

                    What does “teaching/coding language” mean? What are you even trying to teach? I think the subtext is that all the things the IDE make convenient, things that you would need to learn if you were using Vim, they are not coding? Am I right?

                    Why not just write that then? I am not saying IDE’s are bad, but now that we are implicitly redefining words, why don’t you just let me redefine coding as “non-HTML based cross-platform GUI coding”? Now F# suddenly doesn’t seem like a good “coding language” ;)

                    Here comes my typical Haskeller retort: because F# doesn’t have a sufficiently strong type system (effectful code based on higher-ranked polymorphism is not popular in F#), you are not really doing FP. Without higher-rank polymorphism, you’re stuck in the pure part of FP, which is the easy one. F# jumps the shark on the hard parts, and it isn’t convenient to write modularized effectful code.

                    So is the implication here that “teaching language” means you don’t need to worry about effects? I think teaching should be about doing it right. If F# guides you down a wrong path, is it really a good teaching language?

                    I’d agree more to something like “beginner FP language”.

                    1. 5

                      because F# doesn’t have a sufficiently strong type system (effectful code based on higher-ranked polymorphism is not popular in F#), you are not really doing FP. Without higher-rank polymorphism, you’re stuck in the pure part of FP, which is the easy one. F# jumps the shark on the hard parts, and it isn’t convenient to write modularized effectful code.

                      For anyone unfamiliar with these terms: functional programming and higher-rank polymorphism are completely unrelated concepts.

                      Functional programming is about avoiding mutation and side effects, and higher-rank polymorphism is a type-checking feature. Functional code doesn’t stop being functional if you remove the type-checking step from your build, so it’s not possible for higher-rank polymorphism to be a requirement for doing FP.

                      1. 6

                        I don’t understand this FP gatekeeping.

                        Functional programming is about avoiding mutation and side effects, and higher-rank polymorphism is a type-checking feature. Functional code doesn’t stop being functional if you remove the type-checking step from your build

                        A couple years back, there were lots of posts about JavaScript being functional. At that time, I remember hearing arguments that closures and functions were what functional programming is really about.

                        Personally, I’m inclined to slightly agree with the grandparent comments: without higher ranked types it is tricky to represent IO in an immutable fashion. Since the alternative is to bail out and just use mutation (as F# does) then it isn’t as functional as it could be (by your own definition of “avoiding mutation and side effects”).

                        1. 1

                          without higher ranked types it is tricky to represent IO in an immutable fashion. Since the alternative is to bail out and just use mutation (as F# does) then it isn’t as functional as it could be (by your own definition of “avoiding mutation and side effects”).

                          Elm is a typed pure functional language without higher-ranked types, and Elm is even stricter about purity of effects than Haskell, which has unsafePerformIO. (Elm has no equivalent of that.)

                          I don’t think there’s anything particularly tricky about it!

                          1. 5

                            Elm chooses to limit pretty strongly what sort of IO the user does to the point that I’m not sure it counts as a general purpose programming language. For example: what is the type of a function that reads a file? How do you capture those effects? You can definitely avoid using monads for IO, but IMO it leads to less powerful or less usable systems. For example: Haskell initially modeled IO using infinite lists (and it wasn’t very usable).

                            unsafePerformIO is a compiler hack. It isn’t part of the Haskell specification, it is just used for FFI interop with other languages. EDIT: the legitimate use cases for unsafePerformIO are extremely rare and are (to my knowledge) always around some performance optimization that is made outside of Haskell 98.

                            1. 1

                              You can definitely avoid using monads for IO, but IMO it leads to less powerful or less usable systems.

                              Elm does use monads for I/O, it just doesn’t call them that.

                              Here is Elm’s equivalent of Haskell’s IO (except that it includes error handling, which Haskell’s IO doesn’t):

                              https://package.elm-lang.org/packages/elm/core/latest/Task#Task

                              Nothing tricky about it imo.

                              1. 2

                                Can I define my own Task to call a C function using FFI? Can’t find it.

                                1. 3

                                  Only if your name starts with Evan. ;-)

                                  1. 1

                                    Elm compiles to JavaScript, so no.

                                    Given that the thread was about whether functional programming has anything to do with higher-ranked types, I’ll assume this change of topic means that discussion is over.

                                  2. 2

                                    Oh man, that link reminds me of Elm’s time handling approach that made me want to take Evan’s hand and tell him “Kid, it’s not as easy as you think it is. You think you had a really smart idea there, but really, you didn’t.”.

                                    1. 1

                                      Interesting - I had the opposite reaction. I’ve never used a time API I liked as much as Elm’s. What didn’t you like about it?

                                      1. 1

                                        From an ergonomic perspective, an example problem (of many!) is the choice to make time zones explicit. I suppose that this comes from the SPA tradition, where ad-hoc user input (“Choose your language”) or Web browser APIs are used to establish a preferred presentation language instead of content negotation. However, just like with the Unicode sandwich technique, we can have a UTC Sandwich design where times on Earth are handled uniformly, and only the outermost presentation layers need to worry about timezones.

                                        Worse, in my opinion, is the decision to make access to timers unprivileged. This invites timing side-channels. I know of no solutions besides making them explicit parameters instead of allowing them to be ambiently imported.

                                        In general, Elm’s libraries and designs are oriented towards SPAs but not towards backend services, ruining the hope of so-called “isomorphic” deployments where identical code runs in the Web browser and the backend.

                                        1. 1

                                          From an ergonomic perspective, an example problem (of many!) is the choice to make time zones explicit. […] However, just like with the Unicode sandwich technique, we can have a UTC Sandwich design where times on Earth are handled uniformly, and only the outermost presentation layers need to worry about timezones.

                                          I personally like this technique - explicit time zones are one of my favorite parts about the design of the elm/time package - but fair enough if your preferences differ from mine!

                                          Worse, in my opinion, is the decision to make access to timers unprivileged. This invites timing side-channels. I know of no solutions besides making them explicit parameters instead of allowing them to be ambiently imported.

                                          Hmm, how would a language (any language!) support even basic current-time use cases (like obtaining a current timestamp) without making timing attacks possible?

                                          1. 1

                                            Time-zone handling isn’t just a preference. We’ll necessarily incur an extra table lookup if we want to decode a historical timestamp which is relative to some time zone, so it’s slower. That extra table has to be from an old time-zone map, so we must store an ever-growing number of old time-zone maps, so it’s bigger. And it is another thing that programmers might get incorrect, so it’s got more potential for bugs.

                                            By “explicit parameters” for timers, I mean that the application’s entry points would accept timer values as parameters, and invoking those timer values would produce timestamps. Timing attacks are still possible, but they no longer have the potential to run rampant through a codebase. For a practical example, this Monte module implementing Python’s timeit algorithm is parameterized upon some timer object, but doesn’t have automatic access to any privileged clocks or timers. This module drawing some console graphics explicitly requests the system clock Timer and syntactically reveals where it is used.

                                            1. 1

                                              We’ll necessarily incur an extra table lookup if we want to decode a historical timestamp which is relative to some time zone, so it’s slower.

                                              I see - so, to check my understanding: for reasons beyond your control, it’s stored in the database (or you get it from an external data source) relative to a particular time zone, and you want to decode it (and then work with it?) while staying relative to that time zone?

                            2. 2

                              functional code doesn’t stop being functional if you remove the type-checking

                              Like the “Rust is NP-hard” post shows, the type system is also used for code generation. So I can’t even run my code after removing the type checker.

                              We don’t need to mince words about what FP is, because this is a discussion about what F# is missing. I should have said “pure typed FP”. Would you agree with me then?

                              1. 3

                                I should have said “pure typed FP”. Would you agree with me then?

                                Also no; a counterexample would be Elm, which is a typed pure functional language without higher-rank polymorphism!

                                1. 6

                                  You can also have an effect system (like Koka) and still not have higher-kinded types. These are only necessary if you want to abstract over monads.

                          1. 4

                            In my experience, TCO is often relied on for correct behavior as opposed to just being bonus performance. That means the following is a pretty significant downside!

                            But since it is only applied under certain circumstances, the downside of is that when it is not applied, we won’t be made aware of it unless we check for it.

                            Are there any plans to add some sort of syntax to indicate to the compiler that it should error if it can’t perform TCO? OCaml has @tailcall for this purpose and Scala has @tailrec, although in Scala’s case the compiler won’t even try to do TCO unless you request it.

                            Also: how does Elm handle source maps for TCO functions? As I recall, increased debugging difficulty was one of the reason V8 backed out of automatically doing TCE (and switched to backing explicit tail calls instead).

                            1. 2

                              The article buries the lede, but it’s exactly announcement of a tool that checks Elm code for TCO.

                              1. 1

                                Maybe my coffee hasn’t fully kicked in yet, or maybe it’s been too long since I’ve programmed in a proper functional language, but how or when would TCO change behavior?

                                1. 4

                                  One example that comes to mind: TCO can be the difference between “calling this function with these arguments always returns the correct answer” and “calling this function with these arguments sometimes returns the correct answer, and sometimes crashes with a stack overflow.”

                                  1. 1

                                    Put slightly differently, TCO makes some partial functions total.

                                    1. 3

                                      If running out of stack frames and/or stack memory counts as making a function partial, then does the OS possibly running out of memory mean that no functions are ever total?

                                      Right? Since “the stack” isn’t an explicit abstraction in most programming languages, I don’t think it’s quite correct/useful to say that a recursive function is partial when it can’t be TCO’d.

                                      1. 3

                                        I don’t think it’s out of bounds to say that. It really depends on the conceptual model that your language is providing. For example, it seems to be an operating principle of zig: every function in the stdlib that allocates takes an allocator so you can handle out of memory exceptions intelligently.

                                        But, I get your point: it isn’t an explicit part of the conceptual model of most languages so it’s shifting the window a bit to refer to non-TCO functions as partial. I think it’s potentially useful perspective and, for what it’s worth, most languages don’t really describe their functions as total/partial anyways.

                                  2. 2

                                    Recursion in a language without TCO feels like a fool’s errand. Source: I tried to implement some recursive algorithms in C…. on 16-bit Windows. On a modern CPU, you can probably get away with recursion even if it eats stack, because you have virtual memory and a shitload of address space to recurse into. Not so much on a 286….

                                    1. 1

                                      I definitely agree! I never, ever, write recursive code in a language that doesn’t have a way to at least opt-in to recursion optimization.

                                      But to me, that’s still “performance” and not really “behavior”. But maybe I’m defining these things a little differently.

                                    2. 1

                                      Not sure if @harpocrates meant this but:

                                      Often, if the recursion depth is large enough, the unoptimized version uses a lot of stack space, even potentially an unbounded amount, where the optimized version uses constant space.

                                      So the unoptimized version is not only slower but actually crashes if the stack is used up.

                                      1. 1

                                        Hmm. I assumed that “bonus performance” would include memory usage. And I would’ve lumped the resulting stack overflow in with “performance” concern, but I guess I can see how that might actually be considered behavior since the “optimized” version will complete and an unoptimized version might not.

                                        It’s just weird because I don’t think anybody would tell me that putting an extra private field that I never use on a class would be a “behavior change” even though that makes my class use more memory and therefore will OOM on some algorithms when it might not OOM if I remove the field.

                                        1. 1

                                          An additional private field in a class that is used a million times on the stack might be similar, true. The heap may often be bigger (citation needed).

                                          With recursive calls, you can use up a lot of memory for innocent looking code that e.g. just sums up a list of integers.

                                  1. 26

                                    These are all valid criticisms of certain patterns in software engineering, but I wouldn’t really say they’re about OOP.

                                    This paper goes into some of the distinctions of OOP and ADTs, but the summary is basically this:

                                    • ADTs allow complex functions that operate on many data abstractions – so the Player.hits(Monster) example might be rewritten in ADT-style as hit(Player, Monster[, Weapon]).
                                    • Objects, on the other hand, allow interface-based polymorphism – so you might have some kind of interface Character { position: Coordinates, hp: int, name: String }, which Player and Monster both implement.

                                    Now, interface-based polymorphism is an interesting thing to think about and criticise in its own right. It requires some kind of dynamic dispatch (or monomorphization), and hinders optimization across interface boundaries. But the critique of OOP presented in the OP is nothing to do with interfaces or polymorphism.

                                    The author just dislikes using classes to hold data, but a class that doesn’t implement an interface is basically the same as an ADT. And yet one of the first recommendations in the article is to design your data structures well up-front!

                                    1. 15

                                      The main problem I have with these “X is dead” type article is they are almost always straw man arguments setup in a way to prove a point. The other issue I have is the definition or interpretation of OOP is so varied that I don’t think you can in good faith just say OOP as a whole is bad and be at all clear to the reader. As an industry I actually think we need to get past these self constructed camps of OOP vs Functional because to me they are disingenuous and the truth, as it always does, lies in the middle.

                                      Personally, coming mainly from a Ruby/Rails environment, use ActiveRecord/Class to almost exclusively encapsulate data and abstract the interaction with the database transformations and then move logic into a place where it really only cares about data in and data out. Is that OOP or Functional? I would argue a combination of both and I think the power lies in the middle not one versus the other as most articles stipulate. But a middle ground approach doesnt get the clicks i guess so here we are

                                      1. 4

                                        the definition or interpretation of OOP is so varied that I don’t think you can in good faith just say OOP as a whole is bad and be at all clear to the reader

                                        Wholly agreed.

                                        The main problem I have with these “X is dead” type article is they are almost always straw man arguments setup in a way to prove a point.

                                        For a term that evokes such strong emotions, it really is poorly defined (as you observed). Are these straw man arguments, or is the author responding to a set of pro-OOP arguments which don’t represent the pro-OOP arguments with which you’re familiar?

                                        Just like these criticisms of OOP feel like straw men to you, I imagine all of the “but that’s not real OOP!” responses that follow any criticism of OOP must feel a lot like disingenuous No-True-Scotsman arguments to critics of OOP.

                                        Personally, I’m a critic, and the only way I know how to navigate the “not true OOP” dodges is to ask what features distinguish OOP from other paradigms in the opinion of the OOP proponent and then debate whether that feature really is unique to OOP or whether it’s pervasive in other paradigms as well and once in a while a feature will actually pass through that filter such that we can debate its merits (e.g., inheritance).

                                        1. 4

                                          I imagine all of the “but that’s not real OOP!” responses that follow any criticism of OOP must feel a lot like disingenuous No-True-Scotsman arguments to critics of OOP.

                                          One thing I have observed about OOP is how protean it is: whenever there’s a good idea around, it absorbs it then pretend it is an inherent part of it. Then it deflects criticism by crying “strawman”, or, if we point out the shapes and animals that are taught for real in school, they’ll point out that “proper” OOP is hard, and provide little to no help in how to design an actual program.

                                          Here’s what I think: in its current form, OOP won’t last, same as previous form of OOP didn’t last. Just don’t be surprised if whatever follows ends up being called “OOP” as well.

                                      2. 8

                                        The model presented for monsters and players can itself be considered an OO design that misses the overarching problem in such domains. Here’s a well-reasoned, in-depth article on why it is folly. Part five has the riveting conclusion:

                                        Of course, your point isn’t about OOP-based RPGs, but how the article fails to critique OOP.

                                        After Alan Kay coined OOP, he realized, in retrospect, that the term would have been better as message-oriented programming. Too many people fixate on objects, rather than the messages passed betwixt. Recall that the inspiration for OOP was based upon how messages pass between biological cells. Put another way, when you move your finger: messages from the brain pass to the motor neurons, neurons release a chemical (a type of message), muscles receive those chemical impulses, then muscle fibers react, and so forth. At no point does any information about the brain’s state leak into other systems; your fingers know nothing about your brain, although they can pass messages back (e.g., pain signals).

                                        (This is the main reason why get and set accessors are often frowned upon: they break encapsulation, they break modularity, they leak data between components.)

                                        Many critique OOP, but few seem to study its origins and how—through nature-inspired modularity—it allowed systems to increase in complexity by an order of magnitude over its procedural programming predecessor. There are so many critiques of OOP that don’t pick apart actual message-oriented code that beats at the heart of OOP’s origins.

                                        1. 1

                                          Many critique OOP, but few seem to study its origins and how—through nature-inspired modularity—it allowed systems to increase in complexity by an order of magnitude over its procedural programming predecessor.

                                          Of note, modularity requires neither objects nor message passing!

                                          For example, the Modula programming language was procedural. Modula came out around the same time as Smalltalk, and introduced the concept of first-class modules (with the data hiding feature that Smalltalk objects had, except at the module level instead of the object level) that practically every modern programming language has adopted today - including both OO and non-OO languages.

                                        2. 5

                                          I have to say, after read the first few paragraphs, I skipped to ‘What to do Instead’. I am aware of many limitations of OOP and have no issue with the idea of learning something new so, hit me with it. Then the article is like ’hmm well datastores are nice. The end.”

                                          The irony is that I feel like I learned more from your comment than from the whole article so thanks for that. While reading the Player.hits(Monster) example I was hoping for the same example reformulated in a non-OOP way. No luck.

                                          If anyone has actual suggestions for how I could move away from OOP in a practical and achievable way within the areas of software I am active in (game prototypes, e.g. Godot or Unity, Windows desktop applications to pay the bills), I am certainly listening.

                                          1. 2

                                            If you haven’t already, I highly recommend watching Mike Acton’s 2014 talk on Data Oriented Design: https://youtu.be/rX0ItVEVjHc

                                            Rather than focusing on debunking OOP, it focuses on developing the ideal model for software development from first principles.

                                            1. 1

                                              Glad I was helpful! I’d really recommend reading the article I linked and summarised – it took me a few goes to get through it (and I had to skip a few sections), but it changed my thinking a lot.

                                            2. 3

                                              [interface-based polymorphism] requires some kind of dynamic dispatch (or monomorphization), and hinders optimization across interface boundaries

                                              You needed to do dispatch anyway, though; if you wanted to treat players and monsters homogenously in some context and then discriminate, then you need to branch on the discriminant.

                                              Objects, on the other hand, allow interface-based polymorphism – so you might have some kind of interface […] which Player and Monster both implement

                                              Typeclasses are haskell’s answer to this; notably, while they do enable interface-based polymorphism, they do not natively admit inheritance or other (arguably—I will not touch these aspects of the present discussion) malaise aspects of OOP.

                                              1. 1

                                                You needed to do dispatch anyway, though; if you wanted to treat players and monsters homogenously in some context and then discriminate, then you need to branch on the discriminant.

                                                Yes, this is a good point. So it’s not like you’re saving any performance by doing the dispatch in ADT handling code rather than in a method polymorphism kind of way. I guess that still leaves the stylistic argument against polymorphism though.

                                              2. 2

                                                Just to emphasize your point on Cook’s paper, here is a juicy bit from the paper.

                                                Any time an object is passed as a value, or returned as a value, the object-oriented program is passing functions as values and returning functions as values. The fact that the functions are collected into records and called methods is irrelevant. As a result, the typical object-oriented program makes far more use of higher-order values than many functional programs.

                                                1. 2

                                                  Now, interface-based polymorphism is an interesting thing to think about and criticise in its own right. It requires some kind of dynamic dispatch (or monomorphization), and hinders optimization across interface boundaries.

                                                  After coming from java/python where essentially dynamic dispatch and methods go hand in hand I found go’s approach, which clearly differentiates between regular methods and interface methods, really opened my eyes to overuse of dynamic dispatch in designing OO apis. Extreme late binding is super cool and all… but so is static analysis and jump to definition.

                                                1. 4

                                                  Since 2017 the interest for Clojure dropped significantly, almost to zero, to a 2008 level (the language was created in 2007): https://trends.google.com/trends/explore?date=all&q=%2Fm%2F03yb8hb

                                                  This sounds scary. No one would invest in such a curve.

                                                  More, the founders / the company behind Clojure were bought up last year by a bank. We all know what this means in other areas.

                                                  And so on.

                                                  I’ve started learning Clojure a month ago. And these are my back-thoughts on it.

                                                  1. 10

                                                    The trends chart for Apache Spark shows interest in that technology near a 5-year low and trending downward. Interest in SQL, Java, JavaScript have been on downward trajectories for 15+ years, and are currently at an interest level metric very near to Clojure.

                                                    Would it be fair to call it scary to invest in those technologies?

                                                    1. 8

                                                      Since 2017 the interest for Clojure dropped significantly, almost to zero, to a 2008 level (the language was created in 2007): https://trends.google.com/trends/explore?date=all&q=%2Fm%2F03yb8hb

                                                      This sounds scary. No one would invest in such a curve.

                                                      If you think that’s scary, wait ’til you see the same graph for Java!

                                                      https://trends.google.com/trends/explore?date=all&q=%2Fm%2F07sbkfb

                                                      Or C#!

                                                      https://trends.google.com/trends/explore?date=all&q=%2Fm%2F07657k

                                                      Or JavaScript!

                                                      https://trends.google.com/trends/explore?date=all&q=%2Fm%2F02p97

                                                      Or C!

                                                      https://trends.google.com/trends/explore?date=all&q=%2Fm%2F01t6b

                                                      Or C++!

                                                      https://trends.google.com/trends/explore?date=all&q=%2Fm%2F0jgqg

                                                      I used to think Google Trends correlated with language popularity, but these are pretty strong counterexamples.

                                                      1. 6

                                                        Right, G Trends shows even React is in a serious downward spiral.

                                                        Point taken, thanks for everybody clarifying this.

                                                      2. 5

                                                        More, the founders / the company behind Clojure were bought up last year by a bank. We all know what this means in other areas.

                                                        I don’t. What’s the concern about being owned by a bank?

                                                        1. 3

                                                          More, the founders / the company behind Clojure were bought up last year by a bank. We all know what this means in other areas.

                                                          This also happened to Elixir and it seems to be doing fine?

                                                          1. 3

                                                            Google trends isn’t really a useful metric. What’s more interesting is that there are more and more companies using Clojure commercially. For example, we had Clojure/north conference in Toronto where lots of people presented from companies that are entirely built on Clojure stack. There are lots of new companies popping up doing innovative stuff with Clojure every year. Roam Research being a good example.

                                                            The communities on Slack, Reddit, and Clojureverse are very active, and constantly growing.

                                                            There are now projects like Clojurists Together for funding open source ecosystem and ensuring that it’s sustainable. Incidentally, one of the first things that happened from Cognitect being bought by Nubank was that they started funding open source developers on Github.

                                                            Clojure is a mature language, with a large ecosystem around it, and a very active community. It’s not a hype driven language, but it’s very much sustainable and has been for many years now.

                                                            1. 1

                                                              Definitely, I choose Clojure/Script as an alternative to JavaScript web dev due to all the above.

                                                              However I still don’t feel safe, because of the language popularity. For example on the 2020 Stack Overflow Dev Survey (https://insights.stackoverflow.com/survey/2020#technology) Clojure didn’t hit the list. A presence there would be reassuring.

                                                              I see Clojure a one way path: take a deep breath, go down into the rabbit hole (yes, Clojure learning is not simple at all, Clojure is unlike others) and never look back.

                                                              1. 2

                                                                This seems like a pretty limited perspective… Learn more languages and you’ll see that Clojure is easier to learn (and better to use) than most if not all.

                                                                If the syntax, style, or ideas seem foreign, than all the better! You can write (C, Lisp, Cobol) in any language, and learning the pros and cons of each style is never time wasted.

                                                                1. 1

                                                                  Clojure is the 9th language I’m learning.

                                                                  So far I find it so strange like Assembly. And functional programming such a shift when I transitioned from procedural programming (C) to object-oriented programming (C++).

                                                                  These makes one cautious.

                                                                  For example, with React was no question to learn it, to invest in. It was the solution for the problem I was waiting for ages.

                                                                  On Clojure I can’t see really that clear path. Functional programming, for example, is solved elsewhere more thoroughly and in a simpler way (https://github.com/MostlyAdequate/mostly-adequate-guide).

                                                                  That’s why language popularity would be a good indicator whether to adopt it, or not.

                                                                  However, on HN, the comments on this same article are more alarming: https://news.ycombinator.com/item?id=27054839

                                                                  It seems to explain why the language popularity is dropping. Clojure starts as a nice promise, then problems rise, people flock away.

                                                                  1. 13

                                                                    Been writing Clojure professionally for a little over nine years, both on teams of hundreds and as a solo engineer. I can’t speak to popularity, but Clojure has been (and remains!) an exceedingly nice language choice for long-running services and desktop applications. It combines a well-designed standard library, reasonable performance, an emphasis on immutability and concurrency-safety without being dogmatic about evaluation semantics, just the right amount of syntax, excellent JVM interop, and access to a huge swath of Clojure and other JVM libraries. It’s a generally mature, stable language which solves data-oriented problems well. The major drawbacks, in my view, are a lack of static typing (though I’ve used spec, schema, and core.typed to some avail here), unnecessarily unhelpful error messages, slow (~5 to ~20s) startup times, and that working with JVM primitives efficiently is more difficult than one might like. And, of course the usual JVM drawbacks: garbage collection, for instance.

                                                                    None of this is really new per se. I wouldn’t worry too much about popularity metrics or library churn rate–one of the nice things about Clojure is that it’s fairly stable, and libraries from a decade ago tend to work basically unchanged. After Scala, that was a breath of fresh air for me. What I’d ask, were I in your position, is whether the language’s ergonomics, libraries, and speed are suitable for the kind of work you’re trying to do.

                                                                2. 2

                                                                  My team’s been using Clojure for around a decade now, and things have only been getting better all around in that time. I think the most important part is that there are a lot of companies using it nowadays as their core platform. There is a lot of commercial interest in keeping the language and its ecosystem alive and active. I don’t think Clojure will ever get big like Java or Python, but I really don’t see it going away either at this point.

                                                                  It’s also worth noting that Clojure can be sustainable with a smaller community because it piggy backs on JVM and Js runtimes. We have access to entire ecosystems from these platforms, and can seamlessly leverage all the work from the broader community.

                                                              2. 2

                                                                I’m not so sure about Google trends as real data point… but there seems to be less buzz, but people are still using it.. and I don’t think there ever was a real hype.

                                                                I had noticed that my personal interest had diminished a bit and when most of the people from the irc channel migrated to Slack I didn’t join them. Stuff still seems to get regular updates and as just a casual user no Clojure release really excited or disturbed me - that could be because I’d neber used it to its full potential (likely) or that they were just iterating in small steps and not being revolutionary (also likely). I don’t think I’ve had to do meaningful changes over the years to the codebases I started between 2011 and 2013 and they run on the lastest Clojure version…

                                                              1. 2

                                                                I wish they also published something like this about the build system they use.

                                                                1. 9

                                                                  We use Shake and esbuild!

                                                                  We used to have a custom Webpack replacement called Jetpack (motivated by Webpack being unacceptably slow for us), but esbuild is fast enough that we switched to it and no longer need Jetpack.

                                                                  https://shakebuild.com

                                                                  https://github.com/NoRedInk/jetpack

                                                                  https://esbuild.github.io

                                                                1. 6

                                                                  I work at NoRedInk - happy to answer any follow-up questions about this!

                                                                  1. 7

                                                                    Things that are appealing to me about this:

                                                                    1. It’s short and permissive, like MIT
                                                                    2. It gives patent grants, like Apache2 (MIT lacks this)
                                                                    3. It’s compatible with GPLv2 (Apache2 lacks this)
                                                                    4. It’s vetted by OSI, FSF, and Oracle lawyers, and all three groups seem to agree it’s legit

                                                                    The only other license I know of that satisfies 2 and 3 at the same time is https://opensource.org/licenses/BSDplusPatent but it doesn’t seem to be as vetted as UPL, and also has the misfortune of sharing a name with the now-infamous Facebook “BSD+patents” license that did something very different.

                                                                    Coming out of Oracle isn’t doing this any favors in terms of reputation, but I assume if it were using nefarious legal language, OSI and/or FSF would have shouted about that from the rooftops instead of giving it their approval.

                                                                    Setting aside adoption rate, is this maybe the best permissive license out there? On paper there seems to be a compelling case for it.

                                                                    1. 5

                                                                      I deeply agree.

                                                                      After 16 years of web design and development I’m thinking to quit. As a last resort / ESCAPE I’m now learning Clojurescript.

                                                                      I’ve started first with PHP (Wordpress, Laravel, Yii), then with Ruby (Rails, Sinatra), now with Javascript (vanilla, jQuery, Gulp, Foundation, Gatsby, Next, React, Lodash, Immer, Typescript). I also do / did static sites with Jekyll, or my own framework.

                                                                      Among all Javascript is far the worst experience. In all areas like the language, the types, the state, the hooks, blogging engine, toolbelt, hosting, packaging, publishing, documenting, the community.

                                                                      The situation is so bad that it eats my nerves. Instead of creating I’m patching and fixing bugs all day. I read Vercel got $$$ investment yet their service / code is broken at an unseen level. Please head over Github and check the issues, how they close it without solving it, how many duplicated issues rise up, and how frustrated everyone is. Never saw anything like this in my career. And I’ve migrated from Gatsby, where I’ve met the ugliest source code in production ever.

                                                                      Ok, I’m stopping now, it’s getting too much.

                                                                      That’s why the web is what it is today. It’s Javascript driven, and Javascript is totally flawed.

                                                                      1. 4

                                                                        I haven’t tried ClojureScript, but your story is a common one in the Elm community. It goes something like “I was so sick of frontend development I was desperate to get away from it, and then I tried Elm, and now I’ve gone 180 degrees and love programming again.”

                                                                        Elm functions can’t even directly call JS functions (there’s a way to do interop, but it’s not with direct function calls), so you don’t get a “blend” of the two languages. The entire https://package.elm-lang.org ecosystem is all Elm code; it’s not possible to publish JS code to it.

                                                                        I can’t guarantee you’ll love it, but I can say it’s worth a weekend to try out! https://elm-lang.org/

                                                                        1. 1

                                                                          Thanks for the tip! Good to see there are alternatives. For now I’m hooked by the Lisp syntax so much I’ll start pursuing this way.

                                                                          What’s sure, from now on, I’ll invest time regularly checking up new languages vs sticking to a single one.

                                                                        2. 3

                                                                          As a last resort / ESCAPE I’m now learning Clojurescript.

                                                                          I switched to Clojurescript 3 years ago and I am never going back. Frontend development can be fun, reliable and productive. You just need to take Javascript and its ecosystem out of the equation.

                                                                          I’m genuinely happy that you found one of the right solutions to this problem before giving up altogether. I almost gave up as well.

                                                                          1. 1

                                                                            I was watching a few dozen of talks to warm up. So far, joy and relaxation everywhere. I’ve touched the docs, downloaded example apps, and it’s a different level, another tone. I can see myself in this community / environment on the long run.

                                                                            As disappointed I was a couple of days ago as happy I am now. Finally it seems I can get back to design aided by code, not made impossible by code.

                                                                        1. 11

                                                                          I always felt like SPAs were created to make data on pages load faster, while simplifying for mobile web, but they ended up making development more complicated, introduced a bunch of bloated frameworks, required tooling to trim the bloat, and ultimately tried to unnecessarily rewrite HTTP.

                                                                          1. 13

                                                                            Yeah, we started with “no need to load data for the header twice” and ended up with bloated multi-megabyte javascript blobs with loading times in tens of seconds. :(

                                                                            1. 6

                                                                              I think the focus shifted more from “need to load data faster” to “need to be able to properly architecture out frontend systems”.

                                                                              Even though I still “just use jQuery like it’s 2010”, I can’t deny there aren’t problems with the ad-hoc DOM manipulation approach. One way to see this is that the DOM is this big global state thing that various functions are mutating, which can lead to problems if you’re not careful.

                                                                              So some better architecture in front of that doesn’t strike me as a bad thing as such, and sacrificing some load speed for that is probably acceptable too.

                                                                              That being said, “4.09 MB / 1.04 MB transferred” for the nytimes.com homepage (and that’s the minified version!) is of course fairly excessive and somewhat ridiculous. I’ve always wondered what’s in all of that 🤔

                                                                              1. 5

                                                                                “need to be able to properly architecture out frontend systems”

                                                                                An absolute shitload of websites are built with React that could be built entirely with server rendered HTML, page navigations, and 100 lines of vanilla JS per page. Not everything is Google Docs.

                                                                                Recent example: I recently was apartment hunting. All the different communities had SPAs to navigate the floor plans, availability, and application process. Fancy pop up windows when you click a floor plan, loading available apartments only when clicking on “Check Availability” and so on.

                                                                                But why? The pop up windows just made it incredibly obnoxious to compare floor plans. They were buggy on mobile. The entire list of available units for an apartment building could have been a few kilobytes of server rendered HTML or embedded JSON.

                                                                                Every single one of those websites would have been better using static layouts, page navigations, and regular HTML forms.

                                                                                1. 5

                                                                                  One reason for a lot of that is that people want to build everything against an API so they can re-use it for the web frontend, Android app, iOS app, and perhaps something else. I wrote a comment about this before which I can’t find right now: but a large reason for all of this SPA stuff is because of mobile.

                                                                                  Other than that, yeah, I feel most websites would be better with just server-side rendering of HTML with some JS sprinkled on top. But often it’s not just about the website.

                                                                                  1. 6

                                                                                    I don’t think an API and server-side rendering have to be incompatible, you could just do internal calls to the API to get the data to render server-side.

                                                                                    1. 5

                                                                                      That’s what we’re doing. We even make a call to API without HTTP and JSON serialization, but it’s still a call to an API which will be used by mobile app.

                                                                                      1. 1

                                                                                        Having done this, I feel this is the way to go for most apps. Even if the backend doesn’t end up calling a web API, just importing a library or however you want to interface is fine too, if not preferable. I’m a big fan of 1 implementation, multiple interface formats.

                                                                                    2. 1

                                                                                      I’ve worked in that industry. A large portion of it is based on the need to sell the sites. Property management companies are pretty bad at anything “technical,” and they will always choose something flashy over functional. A lot of the data is already exposed via APIs and file shipment, too, so AJAX-based data loading with a JavaScript front end comes “naturally.”

                                                                                2. 3

                                                                                  I agree. So, to answer the titular question, I would answer: websites and native applications.

                                                                                  Developing “stuff” that feels like a website fitting the HTTP paradigm is mostly straightforward, pleasant, inexpensive, and comparatively unprofitable.

                                                                                  Developing “stuff” that feels like an application fitting the native OS paradigm is relatively straightforward, occasionally pleasant, often expensive, and comparatively unprofitable.

                                                                                  If we’re limiting our scope to a technical discussion, it seems straightforward to answer the question. Of course, for better or worse, we don’t live in a world where tech stack decisions are based on those technical discussions alone; the “comparatively unprofitable” attribute eclipses the other considerations.

                                                                                  1. 1

                                                                                    That’s how I remember it. I also remember building SPAs multiple years before React was announced, although back then I don’t recall using the term SPA to describe what they were.

                                                                                  1. 10

                                                                                    I like the intention of this article, though I feel like Elm and Purescript are more children of Haskell than Julia. The Julia language feels like it was more influenced by Matlab, Common Lisp, and Python.

                                                                                    1. 2

                                                                                      Julia didn’t go public until 2012, which is also the year when Elm was “released” as Evan Czaplicki’s thesis project. Elm is implemented in Haskell and the design documents refer to Haskell in many places; I’ve never seen a mention of Julia there. Julia doesn’t even have Hindley-Milner type inference! I’m not as familiar with Purescript, but just from the surface syntax and typing discipline it obviously owes more to Haskell than anything else.

                                                                                      Edit: waitaminute, neither “Elm” nor “Purescript” even occur in this article! What the heck are you responding to?

                                                                                      1. 8

                                                                                        I read “I feel like Elm and Purescript are more children of Haskell than Julia” to mean “I feel it’s more fair to call Elm and PureScript children of Haskell than it is to call Julia a child of Haskell,” which I’d agree with.

                                                                                        Separately, I would definitely say Rust is descended from OCaml, not Haskell. Before it was self-hosted, Rust’s original compiler was written in OCaml, and there are a bunch of direct OCaml influences in the language (e.g. the name Result, which OCaml uses, where Haskell uses the name Either). Both OCaml and Haskell are descended from ML, but I wouldn’t say Rust has any direct Haskell ancestry other than similarities between its trait system and Haskell’s typeclass system.

                                                                                        Idris is clearly descended from Haskell, so that part of the original article I’d agree with.

                                                                                        1. 2

                                                                                          Separately, I would definitely say Rust is descended from OCaml, not Haskell.

                                                                                          linear ML in C++ clothing, according to the original author of the language.

                                                                                          1. 1

                                                                                            Sounds catchy but misses how traits are basically typeclasses.

                                                                                            1. 3

                                                                                              curt reply: it also misses how || x syntax was borrowed from ruby.

                                                                                              longer reply: Rust has many features from many different languages, some langs contributed more (ML & C++), some less (Haskell & Ruby). It’s true that typeclasses are pretty close to traits, but:

                                                                                              • exhaustive matching by default
                                                                                              • match keyword
                                                                                              • 'a syntax for generics
                                                                                              • cute/weird rule about semicolons
                                                                                              • general vibe of strict functional language without HKT which compiles to efficient code

                                                                                              all associate with ML linage.

                                                                                          2. 1

                                                                                            Oh, gotcha, that makes way more sense than my parse. Seems like the author acknowledges that he’s being a bit idiosyncratic and narrow:

                                                                                            I count Julia as a child of Haskell (or maybe, I count Catlab.jl as a child of Haskell) because the idea of organizing computation with category theory would not exist in the same way if it weren’t for Haskell.

                                                                                            What do you think of the Eq/Ord traits in Rust? Do they owe anything to the analogous Haskell classes? I don’t know much about Rust, but that was always one of my least favorite parts of Haskell.

                                                                                            1. 3

                                                                                              What do you think of the Eq/Ord traits in Rust? Do they owe anything to the analogous Haskell classes?

                                                                                              Hard to say - the term Ord appears in OCaml but OCaml doesn’t have anything like Eq.

                                                                                              So Eq may have come from Haskell, but then again, Eq is also among the obvious name choices for something like that!

                                                                                            2. 1

                                                                                              Yep that’s what I meant. I should state that Graydon Hoare has deep experience with so many languages that I don’t want to discount Haskell just yet but agree the Ocaml seems to have had a slightly stronger influence.

                                                                                        1. 7

                                                                                          I think what this comes down to is that there isn’t a great language for building languages :-/

                                                                                          OCaml is supposed to be that language, and I even wrote in ~2015 on my website that I would write all future language projects in OCaml. Yet I didn’t go down that path for Oil, and I don’t regret it.

                                                                                          Instead I came up with this somewhat weird Python + ASDL + multiple code generator combo, but it has worked out well, and compiles to nice C++.

                                                                                          It’s both low level and high level at the same time. Languages need both because they’re extremely repetitive tree matching on the one hand, and very performance sensitive on the other (which I learned the hard way).


                                                                                          A few more threads about metalanguages, with extensive comments on using Rust to implement languages:

                                                                                          https://old.reddit.com/r/ProgrammingLanguages/comments/bkohba/what_language_did_you_use_to_implement_your/

                                                                                          https://old.reddit.com/r/ProgrammingLanguages/comments/ays7d7/languages_used_to_implement_compilers/

                                                                                          https://notamonadtutorial.com/an-interview-with-the-creator-of-gleam-an-ml-like-language-for-the-erlang-vm-with-a-compiler-e94775f60dc7


                                                                                          This is the programmer’s version of Guy Steele’s computer science complaint: https://www.youtube.com/watch?v=7HKbjYqqPPQ

                                                                                          That is, that the language used for describing languages is horribly imprecise and inconsistent.

                                                                                          1. 5

                                                                                            I guess it is supposed to be Racket … and yet often it doesn’t seem to play out that way.

                                                                                            As an outside observer, I wonder why that is.

                                                                                            1. 7

                                                                                              Yes exactly, Racket is supposed to be a language for languages. A bunch of reasons that I see:

                                                                                              1. Performance. As mentioned, I learned the hard way how performance-sensitive languages are. Racket was a CPython-like interpreter in C until recently: https://blog.racket-lang.org/2020/02/racket-on-chez-status.html

                                                                                              I wrote Oil in Python and it was way too slow. Racket would have been also too slow, and even with the new runtime, I doubt it would be fast for parsing shell. JITs tend to speed up numeric workloads more than string workloads. String workloads are dominated by allocations and the JIT may not see through those.

                                                                                              1. Algebraic data types. I’m not up to date on what Racket offers here, but all the Lispy mechanisms I’ve seen fall somewhat short of the real thing. Algebraic data types really help when dealing with languages. They affect 50-80% of the lines of code. Compilers and interpreters are full of conditionals, and it’s a huge help to encode those as data rather than code you have to step through.

                                                                                              2. Static types help too. Oil started out dynamically typed and is now statically typed with MyPy.

                                                                                              3. Syntax. Racket does support syntax unlike other lisps, but I think it’s not culturally there, and the support for parsing is relatively weak. For example, the C ecosystem has re2c, which I used in Oil, etc. The Python ecosystem has a number of options for parsing as well.

                                                                                              4. Runtime dependencies (for interpreters). As far as I call, the Shill shell (a research project) was written with Racket. But then they switched to something else because the runtime got in the way.

                                                                                              5. Build time dependencies (for compilers). Compilers are often bootstrapped in a unique way – e.g. Go compilers in Go, Rust in Rust, Zig in Zig, Clang in C++, etc. Compiler writers want to use their own language, and not someone else’s.

                                                                                              So in all of those areas, OCaml and Rust beat Racket IMO. And on top of that, I agree with the downsides about both OCaml and Rust. (Not that my own solution doesn’t have a lot of downsides. The important thing is that they’re all fixable because the code is small and under my control!)

                                                                                              I think Racket is probably very nice for prototyping languages. I’m not sure it’s good for production quality implementations, at least when you’re talking about competitors to CPython, LLVM, rustc, Go, Julia, etc.

                                                                                              Julia was bootstrapped in femtolisp though, which is interesting. I hacked on it at the beginning of Oil, but decided I didn’t like that style.

                                                                                            2. 3

                                                                                              From my perspective, as someone who’s spent the past 5 years doing more pure functional programming (Elm and Haskell) professionally than anything else, and who’s been working on a compiler written in Rust outside work…I would gladly describe Rust as “great for building languages.”

                                                                                              The learning curve was substantial, but now that I’m comfortable with Rust, I don’t think anyone could sell me on OCaml or Haskell (or any other language I’ve heard of) as a better choice for building a compiler.

                                                                                              Granted, that’s in large part because execution speed is extremely important to me. I have very high standards for how fast I think a compiler should run!

                                                                                              1. 6

                                                                                                I have very high standards for how fast I think a compiler should run!

                                                                                                Kind of ironic, since you’re using Rust. (I kid, I kid!)

                                                                                                1. 1

                                                                                                  Haha yeah rustc is definitely way below my bar!

                                                                                                  1. 1

                                                                                                    To be fair it is doing some amazing things :)

                                                                                                2. 2

                                                                                                  Purely opinion, based on looking at some code like

                                                                                                  https://github.com/gleam-lang/gleam/blob/main/src/typ/expr.rs

                                                                                                  (linked in the above threads)

                                                                                                  It looks more concise than C++, but a lot more wordy than OCaml (or Elm). I’d be interested in seeing other idiomatic Rust code that implements languages (compilers, interpreters, runtimes).

                                                                                                  1. 2

                                                                                                    I’m the author of this code. :)

                                                                                                    I did experiment with using OCaml to start with, and yes, the Rust version is a lot more verbose, especially when using shared mutable references (which are very concise in OCaml). Despite this I prefer the Rust experience, and I think it’s a more generally useful language to know.

                                                                                                    1. 2

                                                                                                      Yes I think we talked on the original Reddit thread which I quoted here

                                                                                                      https://lobste.rs/s/vmkv3r/first_thoughts_on_rust_vs_ocaml#c_v5ch1q (as well as your article)

                                                                                                      I think you said you prefer Rust there. That is a useful data point for sure. I’m not experienced with Rust but I can definitely see why it’s appealing for languages.

                                                                                                      I actually think that “procedural” / stateful code with algebraic data types is a pretty good combo. That’s basically how my Oil project is written, with statically typed Python + ASDL.


                                                                                                      I heard someone say that Rust shows you can “just mutate”. In other words, some languages like Clojure and Erlang rely on immutability for concurrency. But Rust relies on its type system for that, so you are safe with mutation.

                                                                                                      And I just read someone say something similar here:

                                                                                                      https://news.ycombinator.com/item?id=24295408

                                                                                                      Others sometimes don’t like to hear this, but IMO, Rust is not at all functional. … Rust is very much procedural

                                                                                                      Although not everyone agrees.

                                                                                                      I have come around to this viewpoint. I used to program in more of an immutable style, but now I favor local mutation and “principled” global mutation. It seems to work well for languages, e.g. lexing and parsing are inherently stateful. And that style does seems to be in line with Rust’s design.

                                                                                                3. 1

                                                                                                  Thanks for these resources, will read them!

                                                                                                1. 2

                                                                                                  I’d be curious what you think of this talk.

                                                                                                  It includes clips of interviews from decades ago from some of the originators of OOP as we know it today, talking about what their goals were and how they aimed to achieve them.

                                                                                                  https://youtu.be/6YbK8o9rZfI

                                                                                                  1. 2

                                                                                                    There’s that thing again.. It’s more of a wording issue but eventually translates into a thinking issue. Functional programming doesn’t erase or “remove” side effects. It just separates side effects from reduction rules.

                                                                                                    Also after I watched this video and thought on it a bit, a question arose: Is the modern stuff OOP at all? Has the definition been extended to cover every use of class-like structures?