Hacker News new | past | comments | ask | show | jobs | submit login

It's oh so convenient until it isn't; until you need to make distinctions between missing values and booleans.

I still haven't decided if it's a good idea or not, and I've been hacking Common Lisp for more than 20 years.




In general, even if you do have a separate boolean type, you need to distinguish between the function which intended to return null and the function which was unable to return anything.

We see here also the distinction between sum types and union types: Maybe Maybe a has three variants: None, Some None, and Some Some a; but (T | null) | null collapses to just T | null.


This has a simple solution. In the same way that Maybe is effectively a container, use a container for the Lisp value. I.e., a list.

    None -> '() 
    Some None -> '(nil)
    Some Some a -> '(a)


Yes, and this is what e.g. assoc and member do. But in those cases there's already a container, whereas in a hash table you would have to construct a new one. I do think that multiple values are easier to use and result in more direct code; the problem is that they don't enforce correct usage the way a container does.


SQL has true, false, and null, for a good reason.

The nil / null value is an attempt to cheaply produce from type T a type like Maybe T, or Optional<T>, or basically T | nil. It's sort of practical. OTOH making false and nil indistinguishable is much less convenient than one might think, and leads to subtle errors.


You're saying I should use custom symbols like 'true and 'false and put in checks like (eq 'false x) instead of (null x)? To avoid subtle errors? Honest question.


Postmodern (https://quickref.common-lisp.net/postmodern.htm), a library to interface with Postresql will use the keyword `:null` to represent null, and T and nil to represent boolean true and false.


And then SQL implementations use empty string as null :)


JS has false, null, and undefined... and NaN and 0... and nobody is ever confused.


In which data structures? For example in CL hashes use multiple returns so in 99% of cases you can just not care, and when you do care about the difference you just check the second return value.


I've run into issues when interfacing databases and writing interpreters, and probably more that I've forgotten.

They're just minor culture clashes that add up...


I like the way CL does things but it makes dealing with JSON occasionally annoying.


Do you mean, for example, a null node versus a missing node?


I mean distinguishing between `null`, `false`, and `[]` on the JSON side. Most JSON libraries for CL by default parse them all as `nil`. (ST-JSON excepted.)


I guess that means you can't generate false and [] either?

So this would be a good example the culture clashes I mentioned, handled badly.


Yes, I think the two return values convention in CL mostly makes this a non-issue.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: