4 ms·
Fairly long post with a simple message: Data is the truth, it is useful to think about the values that live in the program, and about their relations. It is use
by jstimpfle 10y ago
Fairly long post with a simple message: Data is the truth, it is useful to think about the values that live in the program, and about their relations. It is useful to think about what things are "objects" and thus need identities.
This is not obvious to OOP people. In OOP everything (each object) has implied identity: their address in memory. This is brutally wrong for most use cases in most programming domains. What usecase justifies new Integer(3) != new Integer(3)? Most languages support overriding an equality method as a partial fix, but that's far from elegant.
On the other hand it should be fairly obvious to people who like relational databases.
- hughw 10y agoWell put and spot on. The trouble with OO is it's not a data model. Objects aren't rows of a database table. Programmers mutate data fields of objects and enforce the consistency logic manually. As a thought experiment I've considered how you'd write, say, a window system in a logic language like SQL or Prolog. Which pixels are visible and which hidden by other windows? The answer is a join over entities like Window, Pixel, and maybe a ZOrder... something like that, you get the idea. All state transitions bounded by transactions. No way to throw your program into an inconsistent state.
- lacampbell 10y ago> This is not obvious to OOP people. Citation needed!! > In OOP everything (each object) has implied identity: their address in memory. That's not an implied identity at all. That's a default identity. You're meant to override it. What sane default would you propose? Objects are not structs or records. > This is brutally wrong for most use cases in most programming domains. What usecase justifies new Integer(3) != new Integer(3)? What OOP language provides numeric literals that don't have a built in integer class, with an equality method that makes sense!? Complete strawman. > Most languages support overriding an equality method as a partial fix, but that's far from elegant. A partial fix? It is how you solve the problem with objects. I am not sure what other method you would propose.
- jstimpfle 10y agoIt is an identity you can't get rid of, and which is often misused, or accidentally used, to create a lot of complexity. No, you can't override '==' in Java and other OO languages. You can override .equals() which defaults to ==. > A partial fix? It is how you solve the problem with objects. I am not sure what other method you would propose. You mentioned it yourself: structs or records, a.k.a value semantics. Here is a resource from people with more authority (esp. Guy Steele) http://cr.openjdk.java.net/~jrose/values/values-0.html http://cr.openjdk.java.net/~jrose/values/values-0.html
- lacampbell 10y ago> It is an identity you can't get rid of, and which is often misused, or accidentally used, to create a lot of complexity. No, you can't override '==' in Java and other OO languages. You can override .equals() which defaults to ==. Using Java as an example to prove something about OO isn't very useful IMO. It'd be like holding up rust as an example for how functional languages do things - yes, it's fairly functional but hardly canonical. In ruby, for example, you can indeed override ==. > You mentioned it yourself: structs or records, a.k.a value semantics. Here is a resource from people with more authority (esp. Guy Steele) http://cr.openjdk.java.net/~jrose/values/values-0.html http://cr.openjdk.java.net/~jrose/values/values-0.html I think you're conflating structural equality on the one hand, and reference semantics on the other. The two aren't related in real OO. For example, here's a class that defines equality the same way an ML record might: class Value def ==(other) if other.class != self.class then return false end self.instance_variables.each do |v| if instance_variable_get(v) != other.instance_variable_get(v) then return false end end return true end end Then we can use it to define a simple point class: class Point < Value def initialize(x, y) @x, @y = x, y end end And there you go - structural equality, but still passed as references. Point.new(0, 0) == Point.new(1, 2) => false Point.new(0, 0) == Point.new(0, 0) => true