Branch: Difference between revisions
mNo edit summary |
No edit summary |
||
Line 1: | Line 1: | ||
{{Built-in|Branch|→}} is a [[Primitive function|primitive]] [[ | {{Built-in|Branch|→}} is a special [[Primitive function|primitive]] with a [[function]]-like syntax which provides a way to control execution flow in an APL program. It fulfils the role of [[wikipedia:goto|goto]], [[wikipedia:return statement|return statement]]s, and [[wikipedia:Call_stack#Unwinding statement|call stack unwinding]] in other programming languages, though it is slightly more powerful in APL. | ||
[[File:A Formal Description of System-360 page 258b.png|thumb|right|Iverson notation using flow arrows with conditions]] | |||
== Behaviour == | |||
Branch was the only form of flow control in early versions of APL, having been carried over from the conditional flow arrows of [[Iverson Notation]]. Some APL dialects later added the more modern [[control structure]]s leading to deprecation of Branch. | |||
Branch is unusual having syntax resembling a [[monadic function]], but affecting program flow rather than altering arrays. In addition, a so called "naked branch", that is, a [[niladic]] <source lang=apl inline>→</source> will cut one level off the call stack. | |||
In a [[tradfn]], Branch can take a [[scalar]] or [[vector]] argument, and immediately cause execution to resume on the line indicated by the first element of the argument, which must be a non-negative integer. If the line number is 0, the function will return to its caller. If the argument is empty, the effect is that of consuming the argument and giving no result, equivalent to the dfn <source lang=apl inline>{}</source>. Inserting a label (an identifier followed by a colon <source lang=apl inline>:</source>) into a function, in a sense declares a name as a constant with the scalar value of the current number for whichever line the label occurs on. This ensures stability when lines are inserted into a function. | |||
[[Dfn]]s do not support branching except the naked branch to cut the stack. | |||
In a [[tacit]] function (which doesn't have its own stack frame), the effect of Branch will be exercised in its caller. Tacit functions containing Branch can therefore be used to write covers for Branch, including various conditions. | |||
==Examples== | ==Examples== | ||
Branch function can be used to implement [[wikipedia:Structured programming|structured programming]] constructs without the use of special keywords:<ref>[[Garth Foster|Garth H. Foster]]. (1975). [https://doi.org/10.1145/800117.803792 What lies beyond the branch arrow?].</ref> | Branch function can be used to implement [[wikipedia:Structured programming|structured programming]] constructs without the use of special keywords:<ref>[[Garth Foster|Garth H. Foster]]. (1975). [https://doi.org/10.1145/800117.803792 What lies beyond the branch arrow?].</ref> | ||
Line 8: | Line 18: | ||
⍝ If-Then-Else construct | ⍝ If-Then-Else construct | ||
→(~B)/Else | →(~B)/Else | ||
S1 | |||
→End | |||
Else: | Else: | ||
S2 | |||
End: | End: | ||
</source> | </source> | ||
Line 18: | Line 28: | ||
→(Case1, Case2, Case3, Case4)[i] | →(Case1, Case2, Case3, Case4)[i] | ||
Case1: S1 | Case1: S1 | ||
→Next | |||
Case2: S2 | Case2: S2 | ||
→Next | |||
Case3: S3 | Case3: S3 | ||
→Next | |||
Case4: S4 | Case4: S4 | ||
Next: | Next: | ||
Line 29: | Line 39: | ||
⍝ While-Do construct | ⍝ While-Do construct | ||
While: →(~B)/Done | While: →(~B)/Done | ||
S1 | |||
→While | |||
Done: | Done: | ||
</source> | </source> | ||
Line 36: | Line 46: | ||
⍝ Repeat-Until construct | ⍝ Repeat-Until construct | ||
Repeat: S2 | Repeat: S2 | ||
→(~B)/Repeat | |||
</source> | </source> | ||
Note that <source inline lang=apl>Else</source>, <source inline lang=apl>End</source>, <source inline lang=apl>CaseN</source>, <source inline lang=apl>Next</source>, <source inline lang=apl>While</source>, <source inline lang=apl>Done</source>, <source inline lang=apl>Repeat</source> in the examples above are all user-defined labels rather than keywords. | Note that <source inline lang=apl>Else</source>, <source inline lang=apl>End</source>, <source inline lang=apl>CaseN</source>, <source inline lang=apl>Next</source>, <source inline lang=apl>While</source>, <source inline lang=apl>Done</source>, <source inline lang=apl>Repeat</source> in the examples above are all user-defined labels rather than keywords. | ||
Line 44: | Line 54: | ||
* Bernard Legrand. [https://www.dyalog.com/uploads/documents/MasteringDyalogAPL.pdf#page=208 Mastering Dyalog APL (page 208)]. [[Dyalog Ltd]]. November 2009. | * Bernard Legrand. [https://www.dyalog.com/uploads/documents/MasteringDyalogAPL.pdf#page=208 Mastering Dyalog APL (page 208)]. [[Dyalog Ltd]]. November 2009. | ||
=== Documentation === | === Documentation === | ||
* [http://microapl.com/apl_help/ch_020_010_043.htm APLX] | |||
* [https://help.dyalog.com/18.0/Content/Language/Primitive%20Functions/Branch.htm Dyalog] | * [https://help.dyalog.com/18.0/Content/Language/Primitive%20Functions/Branch.htm Dyalog] | ||
===References=== | ===References=== |
Revision as of 19:12, 27 July 2020
→
|
Branch (→
) is a special primitive with a function-like syntax which provides a way to control execution flow in an APL program. It fulfils the role of goto, return statements, and call stack unwinding in other programming languages, though it is slightly more powerful in APL.
Behaviour
Branch was the only form of flow control in early versions of APL, having been carried over from the conditional flow arrows of Iverson Notation. Some APL dialects later added the more modern control structures leading to deprecation of Branch.
Branch is unusual having syntax resembling a monadic function, but affecting program flow rather than altering arrays. In addition, a so called "naked branch", that is, a niladic →
will cut one level off the call stack.
In a tradfn, Branch can take a scalar or vector argument, and immediately cause execution to resume on the line indicated by the first element of the argument, which must be a non-negative integer. If the line number is 0, the function will return to its caller. If the argument is empty, the effect is that of consuming the argument and giving no result, equivalent to the dfn {}
. Inserting a label (an identifier followed by a colon :
) into a function, in a sense declares a name as a constant with the scalar value of the current number for whichever line the label occurs on. This ensures stability when lines are inserted into a function.
Dfns do not support branching except the naked branch to cut the stack.
In a tacit function (which doesn't have its own stack frame), the effect of Branch will be exercised in its caller. Tacit functions containing Branch can therefore be used to write covers for Branch, including various conditions.
Examples
Branch function can be used to implement structured programming constructs without the use of special keywords:[1]
⍝ If-Then-Else construct →(~B)/Else S1 →End Else: S2 End:
⍝ Select construct →(Case1, Case2, Case3, Case4)[i] Case1: S1 →Next Case2: S2 →Next Case3: S3 →Next Case4: S4 Next:
⍝ While-Do construct While: →(~B)/Done S1 →While Done:
⍝ Repeat-Until construct Repeat: S2 →(~B)/Repeat
Note that Else
, End
, CaseN
, Next
, While
, Done
, Repeat
in the examples above are all user-defined labels rather than keywords.
External links
Tutorials
- Bernard Legrand. Mastering Dyalog APL (page 208). Dyalog Ltd. November 2009.