1. 7
  1.  

  2. 6

    There are parallels here with the object-relational mismatch,. as I understand it. A row in a SQL database isn’t a reification of an object in the outside world, it’s an assertion of truth about the outside world.

    If your tuple says { description: "White mug", price: 10.20 } then you know there’s a white mug out there which costs that much money. If you project this to drop the price attribute, so now you have { description: "White mug"}, now you know there’s a white mug in the world but you don’t know what it costs. Asking if it’s the same mug - that’s not even a meaningful question. The tuple is not a mug, it’s a statement about a mug.

    1. 4

      Math is value oriented programming.

      Oh and here we go again with the flawed analogies. So let’s dig deeper.. a deterministic view of the universe will be able to have a function describing the state of any particle/wave as a function of time. Another view is that things are scholastically mutating with time. Functions are not even primitive though if you consider them a special case of relations between sets.. and so on. Haskell does just fine with lambda calculus and category theory on the extreme end.

      One of the reasons why a program written in functional programming is less complex than an object-oriented program is because, as we have just seen, it is more complex to define the sameness of objects than the sameness of values.

      It’s less complicated because it tries its best to decouple code from state.

      1. 1

        When we decouple code from state, most of our code manipulates state.

        1. 1

          State is unavoidable but it’s best to contain it than spread it around like a toddler throwing spaghetti. Imagine writing a sql operation that saved state between calls? Yuck.. except that’s what ORM does in a sense :P

      2. 4

        This has led to the quip “a functional programmer knows the value of everything and the cost of nothing”.

        1. 16

          whereas a Pascal programmer knows the Wirth of everything.

          1. 5

            Whereas Europeans generally pronounce his name the right way (‘Nick-louse Veert’), Americans invariably mangle it into ‘Nickel’s Worth.’ This is to say that Europeans call him by name, but Americans call him by value.

            – Introduction by Adriaan van Wijngaarden at the IFIP Congress (1965).

          2. 2

            Since the discovery of efficient persistent data structures and Clojure implementation of HAMTs, FP doesn’t suffer from performance hit like it used to be with LISP when every piece of data was represented with an immutable list.

            1. 2

              I agree, I write Haskell for money and the cost of computing a value is much lower than advertised!

          3. 4

            The cost of the mug example is a great illustration of the ways that mental shortcuts can lead to big problems when we’re thinking about software. The problem I see starts with the simplification that a mug is just a description and a price. In other words:

            type Mug = (Description, Price)
            

            or if we want to use more fundamental types

            type Mug = (String, Integer)
            

            The author then raises the perfectly reasonable question “What if we want to change the price of the mug”. So far so good, but the next step the author makes is an error caused by conflating two different things. The author says “of course the attribute shouldn’t change! it’s the same mug!” but of course that’s completely wrong. We’ve already defined Mug to be, by definition, the product of a price and a description.

            Instead, we have implicitly moved to a second definition of a Mug that has some other defining attribute. Now, our price is in fact some function of time or some other global property, and the identifier of items in the shop:

            type Mug' = String
            mugPrice : Mug -> Integer
            

            Equality isn’t actually broken, or even unexpected in this view of the world, it’s simply that we’ve switched into an alternative definition of Mug and price in the second part of the description.

            1. 2

              Author here: If you read carefully the article you’ll see that I didn’t write: “a mug is a description and a price” but “a mug has a description and a price. It makes a big difference.

              An object has a state. An object is not a state.

            2. 3

              This is a good high-level overview of the philosophical challenges in equality and sameness. I recommend reading “Equal Rights for Functional Objects” to get a deeper grasp of how to implement equality.

              In the E tradition, there are two notions of equality: sameness, and also an “as-big-as” relation. Sameness works the same in E, Monte, or Grace; two objects are the same when no operation can distinguish them. The as-big-as relation is the interesting one, since it is often conflated with sameness in functional programming languages.

              Let’s have a user-defined partial order written as x >= y, where x is “greater-than-or-equal-to” y. We could also write this as y <= x. Then the as-big-as relation is written as x <=> y and is equivalent to x >= y && x <= y. This solves several practical problems:

              • Floating-point comparisons have many difficulties. One example is comparison with NaN. A way to solve this is to define NaN == NaN as true, since all NaNs are the same, but define NaN <=> NaN as false, and indeed define NaN <=> x false for all x.
              • Similarly, comparing sets can be expensive and nuanced, especially if they are insertion-order sets (e.g. in Haskell). The as-big-as relation can be used to explicitly manage whether insertion order is relevant to the comparison.
              • Generalizing the previous example, set inclusion is only one of many examples of partial orders which don’t give total orders. Another example built into E and Monte is interval literals, which are also partially ordered by inclusion.
              • Sometimes one simply wants to define a useful comparison operation by projecting an attribute, like when comparing vectors by magnitude or comparing dual numbers by real component. In these cases, the programmer can choose as-big-as instead of sameness and get the desired behavior.
              1. 3

                The usage of the term “object” from the referenced paper, from 1982, which predates Bertrand Meyer’s often cited “Object-Oriented Software Construction” by 4 years, matches the term “variable”, or even closer and more precisely, “object” from the C++ specification, which just refers to a region of storage (not necessarily an instance of a class). This makes sense when you read the paper and see: “Computers use objects to represent values” and then later on “For instance, 2 can be represented by a bit pattern in a register and in several memory locations. Therefore, everything ‘‘in’’ a computer is an object; there are no values in computers.” Note that the paper also assumes that objects are mutatable and shared, which is often not the case in modern OOP. This would more understandable if the article were titled something like, “FP vs Imperative programming.”

                I also find it odd that the posted article differences from the conclusions of the paper he cited, which says: “Programmers need objects” as well as “Programmers need values” and “We claim that programs can be made more manageable by recognizing explicitly the value/object distinction.” It would seem we have given the prevalence in modern OOP and imperative languages in general of Value Objects and other constructs to treat objects as values such as immutability, whether local or as an attribute as a parameter to a function, such as const.

                1. 3

                  The mug example is not convincing: all attributes are not born equal. Changing a descriptive attribute (price) is not the same as changing an identifying attribute (say, a serial number).

                  The matter of “identity” (“sameness” in the article) has been widely explored in Philosophy and also in Computer Science (which stole, and sometimes greatly distorted, the term “ontology”). See, for example, the work by Guarino and Welch Welty (circa 2000).

                  Edit: Fixed name.

                  1. 3

                    Article has moved to blog.klipse.tech/dop/2021/04/22/sameness-in-programming.html if anyone else was wondering.

                    1. 2

                      I don’t see what any of this has to do with functional or object-oriented programming. It seems more to do with referential transparency, which is not a distinguishing feature of functional programming languages (though it is admittedly more common among functional languages than others).

                      1. 1

                        I agree. But I think it that in OO, it’s very hard to embrace referential transparency.