5 ms·
> ...And thus we get to the crux of the matter. You seem to think that an object must be immutable to be first class. No, that's not what I'm saying. You're st
by catnaroek 10y ago
> ...And thus we get to the crux of the matter. You seem to think that an object must be immutable to be first class.
No, that's not what I'm saying. You're still not getting the distinction I'm making:
(0) A value is something you can bind to a variable. (At least in a call-by-value language, which Lisp most definitely is.) It doesn't matter, or even make sense, to ask whether “this 2” is different from “that 2”. There is always one number 2, regardless of how many times the number 2 is stored in physical memory. Nor does it make sense to ask whether 2 will suddenly become 3 tomorrow. 2 and 3 are always distinct values.
(1) An object is an abstract memory region. Every object has an identity and a current state. The identity is always a primitive, indecomposable value. The state may be compound, but it isn't always a value. (This depends on the language.) Even if the current state is a value, the state at a later point in time might be a different value. Objects with immutable state are largely impractical - why bother distinguishing the physical identities of entities that never change?
The benefits of values and objects are largely complementary:
(0) Values are easier to reason about. Algebraic laws can be stated and proven to hold for large classes (not in the CLOS sense) of values. It's very convenient to delimit these classes using static types, although this isn't strictly necessary. Values shine as the backbone of data structures and algorithms.
(1) Objects can evolve over time, by mutating their slots, or even by changing their class (in the CLOS sense). Using static types to describe object structure is counterproductive. (Hence the pain of programming in Java!) Objects are very convenient when implementing the parts of a program that must adapt to changes in the environment.
> Lisp's lists, maps, and vectors are ALL first class objects, by that definition, which is the most common one.
Of course Lisp has first-class compound objects. But objects are not values! Practical functional languages have both compound values and compound objects.
- qwertyuiop924 10y agoOkay, thank you, I get it. However... >Practical functional languages have both compound values and compound objects. Lisp isn't functional. Not even close. You can DO functional programming in lisp, of course, but lisp itself isn't functional. That is why it doesn't have your compound values. The other reason it doesn't have compound values is that compound values, from a low-level perspective, don't exist: They are an abstraction that doesn't make sense in a language that doesn't have strong typing and/or strong immutability guarantees. Most lisps have neither. And Lisp's opinion on physical identity is that if only matters if you want it to: If you don't want to use eq, than don't use eq. You can even remove eq from scope, making it a runtime error to call any function that uses eq. >Values shine as the backbone of data structures and algorithms. Than treat the data there as values! Lisp isn't stopping you from not mutating your values, and it doesn't stop you from using equal on them. OTOH, it doesn't stop you from mutating them either. Lisp isn't big on guarantees and limits.
- catnaroek 10y ago> Lisp isn't functional. Not even close. This much is fine. > You can DO functional programming in lisp, of course, but lisp itself isn't functional. That is why it doesn't have your compound values. Even non-functional languages can benefit from compound values. Rust is a clear example of this. > The other reason it doesn't have compound values is that compound values, from a low-level perspective, don't exist: From an even lower-level point of view, not even primitive values exist - all memory is addressable! Values are a useful abstraction in high-level programming, though. > They are an abstraction that doesn't make sense in a language that doesn't have strong typing and/or strong immutability guarantees. Most lisps have neither. Immutability is a red herring - you're still thinking in terms of memory locations. The entire point to using values is not worrying about memory locations when you don't need to! > And Lisp's opinion on physical identity is that if only matters if you want it to: If you don't want to use eq, than don't use eq. 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. > You can even remove eq from scope, making it a runtime error to call any function that uses eq. But I don't want to program only with values. A practical language needs objects too.
- qwertyuiop924 10y agoOkay 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?