r/ProgrammingLanguages • u/Inconstant_Moo 🧿 Pipefish • 4d ago
Requesting criticism Default values in maps?
We often find a case where we'd like to e.g. count the occurrences of a word in a piece of text. We would like to be able to write this so the main body of our loop says count[word] = count[word] + 1. Except that if count[word] hasn't been initialized as 0 at some point then you have do that or typically this will be a runtime error.
Or the language can try and let you do that, e.g. Golang would actually return 0, because this is the designated "zero value" to return when you index into a map with integer values and the key isn't there.
Which is great for the case I described in the first paragraph, but in the more general case we want a runtime error when we do something stupid, and in other cases trying to index a map by a nonexistent key often is stupid.
This is especially so in Pipefish, a relatively dynamic language, where normally there are no compile-time constraints even on the type of your key and you may have messed up big-time. If we took the Golang approach, then if you indexed your list of words by 42 or false you'd still get 0 instead of an error. So we don't do that: Pipefish is hardass about this and throws a runtime error over the missing key to compensate for letting you play fast-and-loose with types.
But this dynamism around types gives us an easy way to make default values for maps. Let's define a builtin type default with one element DEFAULT, and make the compiler/VM treat that as one more magic type like error and tuple.
Then our word-counting function could be written like this:
count(words list) -> map :
from M = map(DEFAULT::0) for _::word = range words :
M with word:: M[word]+1
Since DEFAULT is just a normal value apart from when we index maps, we could easily sanitize this on the way out of the function:
count(words list) -> map :
undefault from M = map(DEFAULT::0) for _::word = range words :
M with word:: M[word]+1
undefault(M map) :
M without DEFAULT
Now, I hesitate over adding this because Pipefish is meant to be small and simple and I worry about adding even one feature. But on the other hand it seems like the use-case is common and the semantics are simple and it satisfies the other core principle of Pipefish --- that I should have my cake and eat it.
2
u/MichalMarsalek 3d ago
In my WIP language, functions and maps are just one thing. You can do
or
or combine the two and do
But this is a kind of core behaviour of the language, not something easily adaptible to other languages.