rslt ← cond (⍺⍺ ##.else ⍵⍵) argt            ⍝ Condition f else g ...

Conditional  application  of  left  or  right operand. Returns: if cond is true,
⍺⍺ argt, otherwise ⍵⍵ argt.

NB: This operator is largely superseded by the more general →cond←.  However, it
is retained partly as an example of a simple operator  and partly for reasons of
nostalgia, being the oldest piece of code in the dfns workspace:

        'd t'attrib'else'   ⍝ oldest op in WS.
    1998-03-05 16:41:54

[else]  is more versatile than it might at first appear. In the following (⍺) is
a  boolean  singleton; (⍵), (L) and (R) are arrays and (⍺⍺) and (⍵⍵) are monadic
functions.

case    calling syntax      if      then    else
----    --------------      --      ----    ----
[1]     ⍺ ⍺⍺ else ⍵⍵ ⍵      ⍺       ⍺⍺ ⍵    ⍵⍵ ⍵
[2]     ⍺ ⍺⍺ else ⊢  ⍵      ⍺       ⍺⍺ ⍵    ⍵
[3]     ⍺ ⍺⍺ else{R} ⍵      ⍺       ⍺⍺ ⍵    R
[4]     ⍺  ⊢ else ⍵⍵ ⍵      ⍺       ⍵       ⍵⍵ ⍵
[5]     ⍺  ⊢ else{R} ⍵      ⍺       ⍵       R
[6]     ⍺ {L}else ⍵⍵ ⍵      ⍺       L       ⍵⍵ ⍵
[7]     ⍺ {L}else ⊢  ⍵      ⍺       L       ⍵
[8]     ⍺ {L}else{R} ⍵      ⍺       L       R

Notice  that  (L) and (R) may be arbitrarily complex _expressions_, which return
an array value but which are evaluated _only_ if (⍺) selects that case.

Phil Last suggests an _ambivalent_ variant of the operator:

    else←{              ⍝ {condition} f else g ...
        ⍺←⊢
        1≡⍺ 1:⍺⍺{       ⍝ valence test
            ⍺⍺ ⍵:⍵      ⍝ monad: ⍺⍺ is test - nop if true
            ⍵⍵ ⍵        ⍝                     else run ⍵⍵
        }⍵⍵ ⍵
        ⍺:⍺⍺ ⍵          ⍝ dyad:   ⍺ is test - run ⍺⍺ if true
        ⍵⍵ ⍵            ⍝                     else run ⍵⍵
    }

Notice Phil's technique used in the first two lines of the code. More often than
not,  all  that  is  needed  for  a missing left argument is to supply a default
value.  In this case however, the code needs to know _explicitly_ whether a left
argument  is  present.  The  first line ⍺←⊢, makes ⍺ the identity function if no
left  argument  has been passed. The guard on the second line 1≡⍺ 1, will "fire"
only  in this case, as _any_ array passed as left argument would strand with the
rightmost 1 to form a 2-vector, which cannot possibly match 1.

The  ambivalent  version  adds  the  following  cases  in which (T) is a boolean
singleton and (tt) is a monadic function returning a boolean singleton:

case    calling syntax      if      then    else
----    --------------      --      ----    ----
[9]     tt else ⍵⍵ ⍵        tt ⍵    ⍵       ⍵⍵ ⍵
[10]    tt else{R} ⍵        tt ⍵    ⍵       R
[11]    {T}else ⍵⍵ ⍵        T       ⍵       ⍵⍵ ⍵
[12]    {T}else{R} ⍵        T       ⍵       R

Notice  in  the  examples below,  that  ⍺←⊢ is used to _pass on_ a possibly non-
existent  left  argument  to  a  called function. In the following, if [main] is
called without a left argument, then so is [sub].

    main←{
        ⍺←⊢
        ⍺ sub ⍵
    }
                                                                            case
Examples:                                                                   ────

      open←{⍺←0                           ⍝ File tie, optionally exclusive.
          ⍺ (⍵∘⎕fstie) else (⍵∘⎕ftie) 0   ⍝ ⍺=1: shared else exclusive.      [1]
      }

      close←{⍺←0                          ⍝ File untie, optional resize.
          ⎕funtie ⍺ ⎕fresize else ⊢ ⍵     ⍝ ⍺=1: squeeze file else don't.    [2]
      }

      openc←{⍺←⊢                          ⍝ open as above - unless tie number
          (0∊∊⍵) ⊢ else (⍺∘open) ⍵        ⍝ tie←share openc file             [4]
      }

      closec←{⍺←⊢                         ⍝ close as above - if opened by openc
          (⍺⍺≡⍵) ⊢ else (⍺∘close) ⍵       ⍝ squeeze(file closec)tie          [4]
      }

      openc←{⍺←⊢                          ⍝ open as above - unless tie number
          (0∘∊∘∊) else (⍺∘open) ⍵         ⍝ tie←share openc file             [9]
      }

      closec←{⍺←⊢                         ⍝ close as above - if opened by openc
          (⍺⍺∘≡) else (⍺∘close) ⍵         ⍝ squeeze(file closec)tie          [9]
      }

See also: cond pow and or

Back to: contents

Back to: Workspaces