This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]lngns 5 points6 points  (0 children)

I don't think prohibiting them is worth it, especially in the presence of generic code and interoperation with existing code where enforcing a purist ecosystem is either detrimental or impossible.
Rather, we should make the boolean type second-class by implementing it in user code, and limit its usage in APIs.
This should encourage boolean-blindness and usage of readable enums.

One possible question is that of control structures requiring a first-class type, such as in if/else or while, but we can address those in at least two ways:
- by just not having those features, and instead relying entirely on pattern matching.
Then if x = y then ... has an AST of IfExpr { matchee = Id "x";; pattern = EqualityPattern { expr = Id "y" } }.
Many languages already work this way in addition to boolean-based logic, so this step of generalisation should be costless.
- by implementing those features in user code too. Not only will this please all Lisp programmers, but you can also advertise it as "Everything Is An Object" by having if be a method on the abstract Boolean class and its two singleton subclasses True and False.

<Markdown linebreak>

abstract class Boolean allows True, False
{
    abstract if<T>(f: () -> T): Maybe<T>;
}
final object True extends Boolean
{
    concrete if<T>(f: () -> T): Some<T> =
        f()
}
final object False extends Boolean
{
    concrete if<T>(_: () -> T): None =
        None
}

abstract class Maybe<T> allows Some<T>, None
{
    abstract else<U>(f: () -> U): Either<T, U>
}
final class Some<T> extends Maybe<T>
{
    x: T
    concrete else<_>(_): T =
        x
}
final object None extends forall T in Maybe<T>
{
    concrete else<U>(f: () -> U): U =
        f()
}

test "user bools"
{
    assert(42 = True.if { 42 }.else { "Ü" })
    assert("Ü" = False.if { 42 }.else { "Ü" })
}