| > It's pretty common to want to write something like [. . .] without wanting to destructure a list or use the call-values hack. This makes no sense. You want feature X (the ability to return multiple values) without having to either (a) pick apart a simple structure containing those values or (b) assign names to those values, letting the runtime system pick them apart (or never stick them together, its choice) for you.
So what more do you want?! You want an option type, right? Well what's an option type? Let's consider Haskell: data Maybe a = Nothing | Just a No matter what kind of cleverness you do in memory or whatever, in the end this type is a tuple of two values: (constructor, data). The only special thing going on is that the type system makes sure that (a) constructor == Maybe or constructor == Just, and (b) if constructor == Maybe the data field is meaningless (has no type, can't be read, does not effect equality, whatever). But it's still a tuple. The cons cell is the exact same thing in the absence of a strict compile-time type system, except for your code example we have it flipped: (data, constructor) (well, actually you seem to have a flipped 'Either String a' going on there, but let's stick with option for now) where data is actual data or nil when meaningless, and constructor is like Just when nil and like Nothing when true (btw, lisp convention is the other way around; second value is true like Just and false/nil like Nothing). Just like the original linked article, what your complaint boils down to is "non-compile-time-typed systems allow you to do things which would break compile-time-typed systems"—and while I love compile-time typing as much as the next Haskell aficionado, I don't demand compile-time typing in a language [family] whose very essence is its absence. EDIT: if you could reply and explain what would resolve this "shortcoming of the language", maybe I could understand better what you're trying to say... |
I was actually aiming for (b) here, just incorporated directly into the normal function call and return syntax. Why shouldn't you be able to return multiple values in registers or on a results stack without "tupling them up"? It's clearly supported by the hardware. By "call-values" (sp) hack, I meant that needing to use "call-with-values" and "values" is the hack. Lua, for instance, lets you (with very clean syntax) return multiple values from a function, and assign the results to separate variables, during which at no point is an intermediate table constructed:
I don't think I got it quite right with my angular brackets, but I was trying to think of a nice, clear syntax for multiple return values that wouldn't look out of place in a Lisp.Maybe I was being misleading by using an example that resembled option types. I wasn't trying to bring static typing into this, though I am interested in static type systems and curious about static Lisps, it's just that emulating simple option types for error handling purposes is a very common usage for multiple return values in dynamically typed languages (and, cough, static ones like Go that have lame type systems).
> data Maybe a = Nothing | Just a
> No matter what kind of cleverness you do in memory or whatever, in the end this type is a tuple of two values: (constructor, data).
Is that true? "Maybe" seems like the perfect candidate for a nullable pointer representation, or at least some kind of small tag. I'd be surprised if GHC represents Maybe as a full blown tuple.