How ANY and ALL In Other Languages Act on Empty Inputs

I was looking around in the "Red Enhancement Process" repository to see if there was anything there of interest, and one thing that's at least useful was a survey of how other language constructs paralleling ANY and ALL act when given empty inputs.

The repository is BSD-licensed and so I'll reproduce the list here. :stuck_out_tongue:


Red

>> all [] == none
>> any [] == none

Rebol2 & Rebol3:

>> all [] == true
>> any [] == none

Scheme:

(and) #t
(or) #f

Common Lisp:

(and) T
(or) NIL

R:

all() [1] TRUE
any() [1] FALSE

J:

*./>a: 1
+./>a: 0

Julia:

all([]) true
any([]) false

Python:

all([]) True
any([]) False

Javascript:

[].every(function(){}) true
[].some(function(){}) false

Lotsa Precedent For ALL [] Truthy, ANY [] Falsey...

If you squint hard enough, there are legitimate reasons for favoring this choice--if both have to be constrained to just TRUE and FALSE.

The arguments sort of parallel why it's reasonable to say that TRUE > FALSE. But it's sort of abstract...and you wind up talking about "mathematical consensus regarding bounded lattices…more specifically, a complemented distributive lattice."

...BUT Ren-C Does Better... with VOID

The idea behind VOID is that a function can say that in spirit it produced nothing, but still give back some result... a representation of void intent.

>> any []
== \~,~\  ; antiform (ghost!) "void"

>> all []
== \~,~\  ; antiform (ghost!) "void"

For safety reasons, these ghosts ("light void") will be turned into empty pack antiforms ("heavy void") in stepwise operations where sequence matters, so you have to use ^ to vaporize them. But this is how it works:

>> any [^ all [], 1 + 2]
== 3

>> all [1 + 2, 10 + 20, ^ any []]
== 30

>> all [^ if 1 > 2 ["math is broken"], ^ opt try third [a b]]
== \~,~\  ; antiform (ghost!) "void"

>> all [^ any [] ^ all []]
== \~,~\ ; antiform (ghost!) "void"

This seems to have much better properties. It's distinct from NULL which is conditionally "falsey"... and I think getting an error when you try to use the void result conditionally is the best answer, so you can triage and figure out what you actually meant.

>> if (all [^ any [] ^ all []]) [print "I don't think this should run"]
** Script Error: Cannot decay GHOST! to a value

Powerful Use Cases...

The use cases blow away any microscopic benefit given by declaring the answers here to be true or false. And for ALL to be truthy it would have to lie in some way--by fabricating an arbitrary truthy value.

You won't have to take my word for it that this is a big win...see for yourself:

:eye: :pig_nose: :eye:

2 Likes