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