1. 20
  1. 21

    NAND is a universal programming paradigm.

    1. 8

      I mean yes that is a thing you could say, but at the same time I have difficulty coming up with an example where imperative programming is not also universal.

      1. 6

        This is a succinct piece that says something valuable:

        making the distinction between data, calculation, and action is an important skill to have as a programmer.

        The next skill is to express your functionality in these terms, and find the best boundaries between them. How do you decide what responsibilities should be held by each?

        1. 7

          Everything that can be data should be. If it can’t be data, it should be calculation. If it can’t be, it should be an action. This is pretty much the philosophy that Haskell programmers use daily - represent your data as precisely as possible (data: products and sums that represent only what’s allowed), define calculations to work on your data (pure functions), and then only the things which must be actions become actions that necessitate IO.

          1. 1

            Everything that can be data should be.

            Looking to apply that—Do you have an example of changing a design so that something becomes data that wasn’t?

            I would say you want to store your state in minimal sources of truth, use the type system to make only valid things possible, and calculate everything that can be derived from stored data. But I’m not sure that disagrees with you because storage and derivation aren’t exactly the same as data and calculation.

          2. 3

            How do you decide what responsibilities should be held by each?

            Carve your program at its joints. There will be two main criteria:

            1. Separating pure computations from effects. Put as much into the computation bucket as you can, this will greatly facilitate your tests.
            2. Find the natural interface boundaries, such that your classes/modules stay deep: you want small interfaces that hide significant implementations. (This also facilitate your tests, since now you have fewer functions to test).

            I personally find (1) to be very easy, and (2) kind of a black art. Thematic separation is easy, but when you have one big blob of something you’d like to separate to avoid writing spaghetti, finding the right place to cut it is a blend of experience and trial & error.

          3. 4

            I believe the author’s labeling of functional programming as “a universal programming paradigm” is to push back against the idea that functional programming is separate and isolated from the other ways of programming.

            Functional programming has a bad reputation of being touted by “purists” and academic researchers. This type of thinking is seen as not practical for someone wanting to make a decent living off of programming.

            I believe the thinking behind this post is to say that functional programming can/should be implemented in the standard behavior/thinking of programmers. Which is to say that it is not any more special or unique than other styles.

            The author probably should have elaborated on the “universal” label.

            1. 2

              What is functional programming, though? I thought it would be rude to ask at the top-level, but it’s still a potent question that typically ends up deconstructing the entire premise.

              1. 1

                Talking about functional programming is maybe like talking about agile. There is the doctrinal set of rules that is followed by purists. Some people might say you’re not doing agile or you’re not doing functional programming unless you follow the strict standards.

                I think in this case the author is talking about functional programming in the looser sense wherein you loosely follow the guidelines and core ideas to make your programming more clean and efficient. Much in the same way that people do “agile development” by just being more incremental and listening to customer feedback.

            2. 3

              What does it mean to say it’s “a universal paradigm”, as opposed to “the universal paradigm”?

              1. 7

                Turing machines and lambda calculus are both universal representations of computation, there can be many different things which are universal.

              2. 1

                Are there other universal programming paradigms? Are they “universal” in the sense of universal Turing machines, or is there another meaning?