4 ms·
Okay then, I'm still not sure what you want lisp to do. >Rust is a clear example of this. No, it isn't. I entirely fail to see where rust has compound values.
by qwertyuiop924 10y ago
Okay then, I'm still not sure what you want lisp to do.
>Rust is a clear example of this.
No, it isn't. I entirely fail to see where rust has compound values.
I think you want the programming language to decide what equality operator to use for you. In which case, I wrote the code for that above. You have to wrap all mutators in macros for it to work, but you can fairly trivially write a macro to generate those.
>That makes it no different from Java: “You don't have to use == on value objects! Just use .equals() and you'll be fine!” The harsh reality is that programming with make-believe values is painful. I've been a longtime C++ programmer, and I know only too well how this “let's use a good subset of the language” story ends.
I fail to see how values are any more "make-belive" in Lisp than in any other language. This isn't Java. eq and equals are equally first class, unlike == and .equals(). Just know what kind of comparison you want, and choose accordingly. Is that really so hard?
- catnaroek 10y ago> No, it isn't. I entirely fail to see where rust has compound values. struct Vec2(usize, usize); let origin = Vec2(0, 0); // value let center = Vec2(0, 0); // same value let faraway = Vec2(123,456); // another value > I think you want the programming language to decide what equality operator to use for you. I want the programming language to let me compare the values I care about. I don't want to worry about irrelevant details, like the location, physical or abstract, where a value's representation is stored. Of course, I do care about the physical identity of objects. But objects are not values! > I fail to see how values are any more "make-belive" in Lisp than in any other language. The language forces me to care about a low-level implementation detail. Namely, that the compound values in my problem domain are realized as compound objects in Lisp. It fits the definition of “make-believe”. In any case, it wasn't my intention to single Lisp out. Most languages out there only have make-believe compound values.
- qwertyuiop924 10y agohere's something fun about that rust example: struct Vec2(usize, usize); let a = Vec2(0,0); let b = Vec2(0,0); a == b //true &a as *const usize == &b as *const usize //false And now the (near enough for this example) equivalent Scheme: (define-record vec2 x y) ;;There's no anonymous values in the default scheme record implementation, but it makes no difference for our purposes (define A (make-vec2 0 0)) (define B (make-vec2 0 0)) ;;No constants at a language level, but constant values are uppercase by convention. (equal? A B) ;true (eq? A B) ;false True, the syntax is a bit different (rust doesn't like identity checks), but the semantics, save the above notes, are identical. What you call "values" in one language are identical to what you call "objects" in another. Just use equal like you would in any other language. >I want the programming language to let me compare the values I care about. I don't want to worry about irrelevant details, like the location, physical or abstract, where a value's representation is stored. Than just use equal. >The language forces me to care about a low-level implementation detail You need only care about it if you want to. If you don't, just use equal. Are you starting to see a pattern?
- catnaroek 10y ago> here's something fun about that rust example: &a as *const usize == &b as *const usize //false Yes, in Rust, `a` and `b` are objects with identity. But their state is a compound value that can be easily copied to a different object, passed by value to a function, etc. > You need only care about it if you want to. If you don't, just use equal. A high-level language is supposed to provide abstractions that don't leak.
- qwertyuiop924 10y ago>Yes, in Rust, `a` and `b` are objects with identity. But their state is a compound value that can be easily copied to a different object, passed by value to a function, etc. And you can do the same in Lisp, but, like Python and other languages, it doesn't happen for you. >A high-level language is supposed to provide abstractions that don't leak That's not a leak: It's an escape valve. eq is an escape from the world of values for when you have to care about objects, the same way C has the & unary operator, and rust has the *const cast, and ruby has the equals? message, and python has the is operator. The only reason Haskell doesn't have the same is that it's pure, at least in theory, so there isn't a meaningful distinction. But in languages where state is mutatable, you need eq, or an equivalent, for when you have to care about object identity.
- catnaroek 10y ago> And you can do the same in Lisp, but, like Python and other languages, it doesn't happen for you. No, the state of a Lisp or Python object isn't a value. You can't pass it around without manually deep-cloning everything. Cloning a value doesn't even make sense - there's always only one of it! > The only reason Haskell doesn't have the same is that it's pure, at least in theory, so there isn't a meaningful distinction. ML isn't pure, but it confines physical equality to mutable objects, and not everything is a mutable object. This discussion has absolutely nothing to do with purity. > But in languages where state is mutatable, you need eq, or an equivalent, for when you have to care about object identity. Haskell and ML have lots of mutable state, and don't need a distinction between eq and equal. The single equality testing operator does the right thing on values of different types.