4 ms·
> 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
by 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?
- 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?
- 10y ago