# Dfn: Difference between revisions

m (Text replacement - "<source" to "<syntaxhighlight") |
|||

(8 intermediate revisions by 4 users not shown) | |||

Line 1: | Line 1: | ||

: ''"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"). | 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 [ | 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 [[wikipedia:lexical scoping|lexical scoping]], in contrast to the dynamic scoping of [[tradfn]]s. In other words, a dfn cannot "see" locals of its caller, but can see locals of its definer. | 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 [[wikipedia:lexical scoping|lexical scoping]], in contrast to the dynamic scoping of [[tradfn]]s. In other words, a dfn cannot "see" locals of its caller, but can see locals of its definer. | ||

Line 8: | Line 10: | ||

== Examples == | == Examples == | ||

< | <syntaxhighlight lang=apl> | ||

{⍵*0.5} 16 ⍝ square root | {⍵*0.5} 16 ⍝ square root | ||

4 | 4 | ||

3 {⍵*÷⍺} 27 ⍝ ⍺th root | 3 {⍵*÷⍺} 27 ⍝ ⍺th root | ||

3 | 3</syntaxhighlight> | ||

=== Default left arguments === | |||

Assignment to <syntaxhighlight 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> | |||

<syntaxhighlight lang=apl> | |||

root←{ | root←{ | ||

⍺←2 ⍝ square root by default | ⍺←2 ⍝ square root by default | ||

⍵*÷⍺ ⍝ result | ⍵*÷⍺ ⍝ result | ||

} | }</syntaxhighlight> | ||

=== 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: | |||

<syntaxhighlight lang=apl> | |||

root←{ | root←{ | ||

⍺=0:0 ⍝ return zero if zeroth root | |||

⍺=0:0 ⍝ zero if zeroth root | |||

⍵*÷⍺ ⍝ result | ⍵*÷⍺ ⍝ result | ||

}</ | }</syntaxhighlight> | ||

=== Error-guards === | |||

Dyalog APL dfns support error-guards for processing errors by error codes.<ref>[https://help.dyalog.com/latest/#Language/Defined%20Functions%20and%20Operators/DynamicFunctions/Error%20Guards.htm Error Guards] – Dyalog APL.</ref> | |||

In the following example, there are two error-guards for the error code 11 (DOMAIN ERROR):<ref>[https://help.dyalog.com/latest/#Language/Errors/APL%20Errors.htm#APLErrors APL Error Messages and Codes] – Dyalog APL.</ref> | |||

<syntaxhighlight 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 <syntaxhighlight 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]]: | |||

<syntaxhighlight lang=apl> | |||

assert ← {⍺←'assertion failure' ⋄ 0∊⍵:⍺ ⎕signal 8 ⋄ shy←0}</syntaxhighlight> | |||

== External links == | == External links == | ||

Line 35: | Line 65: | ||

* [https://help.dyalog.com/latest/#Language/Defined%20Functions%20and%20Operators/DynamicFunctions/Dynamic%20Functions%20and%20Operators.htm Dyalog] | * [https://help.dyalog.com/latest/#Language/Defined%20Functions%20and%20Operators/DynamicFunctions/Dynamic%20Functions%20and%20Operators.htm Dyalog] | ||

* [https://www.gnu.org/software/apl/apl.html#Section-3_002e7 GNU APL] | * [https://www.gnu.org/software/apl/apl.html#Section-3_002e7 GNU APL] | ||

== References == | |||

<references/> | |||

{{APL syntax}}[[Category:Kinds of functions]][[Category:Defining functions]] | {{APL syntax}}[[Category:Kinds of functions]][[Category:Defining functions]] |

## Latest revision as of 22:11, 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

{⍵*0.5} 16 ⍝ square root 4 3 {⍵*÷⍺} 27 ⍝ ⍺th root 3

### Default left arguments

Assignment to `⍺`

is unusual in that the entire statement is only executed if the dfn is called monadically:^{[1]}

root←{ ⍺←2 ⍝ square root by default ⍵*÷⍺ ⍝ result }

### Guards

Guards provide dfns with support for basic flow control.^{[2]} This is a multiline dfn with a conditional result:

root←{ ⍺=0:0 ⍝ return zero if zeroth root ⍵*÷⍺ ⍝ result }

### 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]}

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

### Shy results

Roger Hui's `assert`

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:

assert ← {⍺←'assertion failure' ⋄ 0∊⍵:⍺ ⎕signal 8 ⋄ shy←0}

## 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.