Dfn: Difference between revisions
m (Link to definition of "shy") |
m (Text replacement - "</source>" to "</syntaxhighlight>") |
||
Line 14: | Line 14: | ||
4 | 4 | ||
3 {⍵*÷⍺} 27 ⍝ ⍺th root | 3 {⍵*÷⍺} 27 ⍝ ⍺th root | ||
3</ | 3</syntaxhighlight> | ||
=== Default left arguments === | === Default left arguments === | ||
Assignment to <source lang=apl inline>⍺</ | Assignment to <source lang=apl inline>⍺</syntaxhighlight> is unusual in that the entire statement is only executed if the dfn is called monadically:<ref>[https://help.dyalog.com/latest/#Language/Defined%20Functions%20and%20Operators/DynamicFunctions/Default%20Left%20Argument.htm Default Left Argument] – Dyalog APL.</ref> | ||
<source lang=apl> | <source lang=apl> | ||
root←{ | root←{ | ||
⍺←2 ⍝ square root by default | ⍺←2 ⍝ square root by default | ||
⍵*÷⍺ ⍝ result | ⍵*÷⍺ ⍝ result | ||
}</ | }</syntaxhighlight> | ||
=== Guards === | === Guards === | ||
Guards provide dfns with support for basic flow control.<ref>[https://help.dyalog.com/latest/#Language/Defined%20Functions%20and%20Operators/DynamicFunctions/Guards.htm Guards] – Dyalog APL.</ref> This is a multiline dfn with a conditional result: | Guards provide dfns with support for basic flow control.<ref>[https://help.dyalog.com/latest/#Language/Defined%20Functions%20and%20Operators/DynamicFunctions/Guards.htm Guards] – Dyalog APL.</ref> This is a multiline dfn with a conditional result: | ||
Line 28: | Line 28: | ||
⍺=0:0 ⍝ return zero if zeroth root | ⍺=0:0 ⍝ return zero if zeroth root | ||
⍵*÷⍺ ⍝ result | ⍵*÷⍺ ⍝ result | ||
}</ | }</syntaxhighlight> | ||
=== Error-guards === | === Error-guards === | ||
Line 49: | Line 49: | ||
Gravity 1.99e30 5.97e24 0 ⍝ trigger division by zero | Gravity 1.99e30 5.97e24 0 ⍝ trigger division by zero | ||
N/A | N/A | ||
</ | </syntaxhighlight> | ||
=== Shy results === | === Shy results === | ||
[[Roger Hui]]'s <source lang=apl inline>assert</ | [[Roger Hui]]'s <source lang=apl inline>assert</syntaxhighlight> is a dfn that has become the de facto standard when it comes to test suites.<ref>Stefan Kruger. [https://www.dyalog.com/blog/2021/04/2020-problem-solving-competition-phase-ii-highlights/ 2020 Problem Solving Competition – Phase II highlights]. [[Dyalog Ltd.|Dyalog]] blog. April 30, 2021.</ref>. In it, Hui uses both a [[default left argument]] and a final assignment to make the dfn [[shy]]: | ||
<source lang=apl> | <source lang=apl> | ||
assert ← {⍺←'assertion failure' ⋄ 0∊⍵:⍺ ⎕signal 8 ⋄ shy←0}</ | assert ← {⍺←'assertion failure' ⋄ 0∊⍵:⍺ ⎕signal 8 ⋄ shy←0}</syntaxhighlight> | ||
== External links == | == External links == |
Revision as of 21:45, 10 September 2022
- "dfns" redirects here. For the workspace by Scholes, see dfns workspace.
A dfn (contraction of direct function or dynamic function, pronounced "dee fun") is an alternative way to define a function and operator, invented by John Scholes. A dfn operator can also be called a dop (pronounced "dee op").
John Scholes was responsible for numerous presentations and publications on and about dfns, and until his passing he maintained the dfns workspace, a collection of dfns examples.
As of 2020, dfns are fully implemented in Dyalog APL, NARS2000, ngn/apl, dzaima/APL, and partially in GNU APL, although not all dialects implement lexical scoping, in contrast to the dynamic scoping of tradfns. In other words, a dfn cannot "see" locals of its caller, but can see locals of its definer.
Wikipedia includes a thorough treatment of dfns.
Examples
<source lang=apl>
{⍵*0.5} 16 ⍝ square root
4
3 {⍵*÷⍺} 27 ⍝ ⍺th root
3</syntaxhighlight>
Default left arguments
Assignment to <source lang=apl inline>⍺</syntaxhighlight> is unusual in that the entire statement is only executed if the dfn is called monadically:[1] <source lang=apl>
root←{ ⍺←2 ⍝ square root by default ⍵*÷⍺ ⍝ result }</syntaxhighlight>
Guards
Guards provide dfns with support for basic flow control.[2] This is a multiline dfn with a conditional result: <source lang=apl>
root←{ ⍺=0:0 ⍝ return zero if zeroth root ⍵*÷⍺ ⍝ result }</syntaxhighlight>
Error-guards
Dyalog APL dfns support error-guards for processing errors by error codes.[3]
In the following example, there are two error-guards for the error code 11 (DOMAIN ERROR):[4] <source lang=apl> Gravity←{
G←6.6743E¯11 ⍝ gravitational constant 11::'N/A' ⍝ second DOMAIN ERROR: return 'N/A' 11::∇⍎¨⍵ ⍝ first DOMAIN ERROR: maybe the argument is a vector of strings? G×⍵[1]×⍵[2]÷⍵[3]*2 ⍝ the argument is a vector of numbers
}
⍝ Calculate gravity force between the Earth and the Sun Gravity '1.99e30' '5.97e24' '1.50e11'
3.524119391E22
Gravity 1.99e30 5.97e24 1.50e11
3.524119391E22
Gravity 1.99e30 5.97e24 0 ⍝ trigger division by zero
N/A </syntaxhighlight>
Shy results
Roger Hui's <source lang=apl inline>assert</syntaxhighlight> is a dfn that has become the de facto standard when it comes to test suites.[5]. In it, Hui uses both a default left argument and a final assignment to make the dfn shy: <source lang=apl> assert ← {⍺←'assertion failure' ⋄ 0∊⍵:⍺ ⎕signal 8 ⋄ shy←0}</syntaxhighlight>
External links
Tutorials
- APL Cultivation: Diving Into Functions in APL
- Mastering Dyalog: page 174
Documentation
References
- ↑ Default Left Argument – Dyalog APL.
- ↑ Guards – Dyalog APL.
- ↑ Error Guards – Dyalog APL.
- ↑ APL Error Messages and Codes – Dyalog APL.
- ↑ Stefan Kruger. 2020 Problem Solving Competition – Phase II highlights. Dyalog blog. April 30, 2021.