▲ | Imagining a language without booleans(justinpombrio.net) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
56 points by todsacerdoti 2 days ago | 62 comments | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | jbreckmckye 2 days ago | parent | next [-] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Now that we have defined a language without booleans, we need some way to coalesce these optional values We ideally want an infix function that can reduce the "truthiness" of two values. Let us imagine this language is a Haskell-type-thing, and we can define pseudo-operators with pattern matching
Hmm, let's see how that looks
The good news is that we are free from the tyranny of booleans. The bad news is that we just reinvented JavaScript :-) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | munificent 2 days ago | parent | prev | next [-] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Really cool post. I've had roughly similar thoughts when noodling on my current hobby language [1], but didn't work all the way through it to see if it hangs together. It seems like it might! > Let me know if you’ve seen anything more similar. If you take static typing off the table, then Icon's goal-directed execution is very much an inspiration in this area. [1]: https://journal.stuffwithstuff.com/2023/01/03/type-checking-... | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | Y_Y 2 days ago | parent | prev | next [-] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
https://en.wikibooks.org/wiki/Haskell/Understanding_monads/M... This looks homeomorphic to the Maybe monad. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | legacynl 2 days ago | parent | prev | next [-] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
I don't really get it.. In one of the last example's he writes: ` if (node.last_child(s) is Ok(last_child))` Is the part between the () not ultimately the same as a boolean expression? Like he wrote his own implementation of if/else syntax? Also in the beginning he says: "An if with an else can produce a value", but isn't this just 'syntactic sugar'? I think the code that actually runs is the same as if you'd write if (value x = some_value) {value = something} else {value = something_else} ? | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | Twey a day ago | parent | prev | next [-] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Definitely a fun alternative-history! It's a nice take to see `Option`s or `Result`s as a step towards logic programming. Typically once you introduce loops you need to have a way to combine `E`s; the way to represent an ordered set of things e.g. to be combined is to return a list of things, and then you're in logic programming world. [1] [1]: https://wiki.haskell.org/Logic_programming_example It's a bit weird to me that the result `not` discards the content of the value rather than just swapping its truthiness (not A?E : E?A). > The closest thing I’ve seen is fallible expressions in Verse, but those are pretty different because they (i) don’t assign a value to an if without an else, and (ii) involve speculative execution. Traditional ifs, and the ifs here, also involve speculative execution :) (i.e. execution that happens regardless of which branch you end up on). It's just delimited by the brackets of the if condition (a ‘failure context’ in Verseland). It's true that traditionally logic languages don't assign a value to failure. I guess algebraic effects (of which `Result` can be an example) can be seen as a generalization of failure in that way. Amr Sabry &a. also have an interesting notion of ‘failure with value’ as the semantics of their negative types: https://dl.acm.org/doi/abs/10.1145/3434290 , http://lambda-the-ultimate.org/node/4964 (LtU for an older paper from the programme). | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | jayd16 2 days ago | parent | prev | next [-] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
If you're looking to imagine a world without bools, do some branchless gpu shader coding. Certainly its a different way to think about processing data. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | jerf 2 days ago | parent | prev | next [-] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Unfortunately, you're invariably going to end up with a "Some<false>" at some point, and you're going to spend the next 20 years explaining to people why that's not a wart in your language that your if "treats it as true", no matter how much you say "my language doesn't even have true so that's not a valid statement". It isn't going to matter that it's technically a "JSON::false" or whatever... you're still going to get people calling that a wart forever. ("But a JSON::false would be a None" - no, you need that for either "null" or "missing". A JSON library has to have an exposed "false" value to distinguish it from null and missing, both for input and output.) I'm not saying that doesn't mean to try this out, but as more of a heads up and something to talk about explicitly in the eventual tutorial. Personally, I find myself fairly satisfied with if statements rigidly requiring a boolean and refusing to have a concept of "truthiness", which I consider a mistake, and I'm not sure this is solving real problems I've had. A user can always write the Option vs. None themselves in an if statement with mandatory else if they want. This introduces a wrapper level of Option that may not always play nice in real code (I mean, a lot of sum type types essentially already have it built in with things like "type Color = Red | Blue | Green | Unspecified" where adjoining a None is often unnecessary) and may really tempt you towards a concept of truthiness that may be a bigger wart than when you're trying to fix. It's pretty hard for a computer programming language to essentially evict the concept of a "bit" from the language. I'm not sure it can be done in practice, but it's fun to think about it and I encourage the pondering. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | rhaps0dy 2 days ago | parent | prev | next [-] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Basically Emacs Lisp. Where `nil` is the only falsy value, and anything else (including `t`, which analogizes to `Some(())`) are truthy values. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | Aardwolf 2 days ago | parent | prev | next [-] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
So basically, C before version C99 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | seanhunter 2 days ago | parent | prev | next [-] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Imagine a language that not only doesn't have booleans, it only has positive fractions. It also doesn't have any keywords, yet it is Turing-complete. Struggling to imagine it? Don't worry. John H Conway has done it for you. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | taylorallred 2 days ago | parent | prev | next [-] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
I love seeing these kinds of explorations in the realm of language design. I've wondered about expanding the notion of boolean operators like this. For all its flaws, one thing I've always liked about JS is the overloaded (||) and (&&) operators. It's really slick to write something like `foo.get_that_can_fail(x) || "default value"`. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | cryptonector 2 days ago | parent | prev | next [-] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
This:
is still booleans.Icon and Verse use failure (backtracking!) as false and all values as true, but you still have conditionals and boolean logic even though you don't (or may not) have a boolean type. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | kayodelycaon 2 days ago | parent | prev | next [-] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
I'm pretty sure Ruby already does this. if statements are expressions that return a value and return nil if there is no else. (Also 0 == true in Ruby. Only false or nil are not true.) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | asplake 2 days ago | parent | prev | next [-] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Perhaps it’s cheating, but last I checked, Gleam has no “if”, only “match”. With that, and in languages with sum types, you can easily define your own boolean and boolean-adjacent types. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | jujube3 2 days ago | parent | prev | next [-] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Most dialects of BASIC didn't have booleans. Everything old is new again. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | kazinator 2 days ago | parent | prev | next [-] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> Can we go further Yes. we can get a Lisp background to get a better rounded and wiser perspective on all these topics. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | Retr0id 2 days ago | parent | prev | next [-] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
funny, I've been toying with the idea of a language with only booleans | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | elcapitan 2 days ago | parent | prev | next [-] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Too good to be true or false | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | moltar 2 days ago | parent | prev | next [-] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Perl | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | brador 2 days ago | parent | prev | next [-] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Booleans are a remnant of limited RAM. 2025, we can all just use integers and carry one less variable type in our sack. Next we replace integers with floats and we’re done. 3 birds, 1 stone. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | nh23423fefe 2 days ago | parent | prev | next [-] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Not really without. More like obscured booleans, 2 embeds into T+1 which embeds into T+U. I mean C used the sign bit to do the same. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | weatherlight 2 days ago | parent | prev | next [-] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
I can. it's called Erlang. true an false are just atoms. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | nahumba 2 days ago | parent | prev [-] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Headline no bit. Then attack if. There would be no branching if there were no "if". It's basic assembly. Not jumps. No loops. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|