ALSO: Repurposed And Stylized After THEN and ELSE

Rebol2 had an ALSO operator, which I found to make code very unreadable.

  • It takes two arguments

  • It evaluates both

  • ...and it returns the product of the first evaluation

Consider this line from IN-DIR:

also do block change-dir old-dir

This is a shorthand for writing:

(temp: do block, change-dir old-dir, temp)

But this can be done much better in Ren-C with ELIDE (and you can more comfortably split the lines apart, since you're using an arity-1 vanishing operator on a single expression, vs. using an arity-2 operator on two expressions):

eval block, elide change-dir old-dir

eval block
elide change-dir old-dir

That's the tip of the iceberg of the benefits of Ren-C's VOID. Go read up on that if you aren't already familiar!

But This Post Is About The New ALSO...

ALSO is in the same family as THEN and ELSE. It's like a THEN (runs when the left hand side is not null) BUT it discards the evaluative product of its branch, and passes through the non-null value it got as input:

tester: func [num] [
    switch num [
        1 [<one>]
        2 [<two>]
     ] also [
        print "It was one or two"
     ] else [
        print "It was neither one nor two"
     ]
]

>> tester 1
It was one or two
== <one>  ; the ALSO branch ran, but didn't modify the overall result

>> tester 3
It was neither one nor two

I like that it's the same number of letters as THEN and ELSE. :slight_smile:

2 Likes

The historical ALSO always plays havoc with my comprehsion, an infix form looks far more natural to me.

2 Likes

So I think ALSO becomes more useful when it is like an anti-EXCEPT.

Instead of being NULL/VOID reactive (like a THEN/ELSE), it's FAILURE!-reactive.

That gives it usefulness for the pattern:

 some-expression also [
    code to run if there's no FAILURE!
    ... but discard and eval to some-expression's result ...
 ] except (e -> [
    code to run on FAILURE!
 ])

This comes up much more often.