Defined function (traditional): Difference between revisions

Jump to navigation Jump to search
no edit summary
No edit summary
(10 intermediate revisions by the same user not shown)
Line 1: Line 1:
A '''user-defined function''' (or '''tradfn''', for "traditional function", in [[Dyalog APL]]) is a function defined using a header that includes the function's name. Introduced in [[APL\360]], function definition was universally supported by APL dialects for much of the language's history, and is still commonly used in mainstream APLs. Since the 1990s other ways to [[Function styles|describe functions]] have appeared, with [[J]] and [[K]] rejecting function definition in favor of [[anonymous function]] description. Beginning in the 2010s [[Dyalog]]-based APL dialects including [[ngn/apl]], [[dzaima/APL]], and [[APL\iv]] have removed function definition in favor of [[dfn]]s.
A '''user-defined function''' (or '''tradfn''', pronounced "trad fun", for "traditional function", in [[Dyalog APL]]) is a function defined using a header that includes the function's name. Introduced in [[APL\360]], function definition was universally supported by APL dialects for much of the language's [[history]], and is still commonly used in mainstream APLs. Since the 1990s other ways to [[Function styles|describe functions]] have appeared, with [[J]] and [[K]] rejecting function definition in favor of [[anonymous function]] description.


In many dialects the function header syntax of defined functions is adapted to allow user-defined [[operator]]s as well.
{{Anchor|Representations}}The canonical representation form is equivalent to what the user would type into the [[line editor]] to define the function.<ref>[[Dyalog Ltd.]] Programming Reference Guide. [https://help.dyalog.com/latest/#Language/Defined%20Functions%20and%20Operators/Canonical%20Representation.htm Canonical Representation].</ref> An alternative representation consists of the entire [[session]] log transcript, including [[Del]]s (<source lang=apl inline>∇</source>) and line numbers, after having such a definition has been made.<ref>[[Dyalog Ltd.]] Language Reference Guide. [https://help.dyalog.com/latest/#Language/System%20Functions/vr.htm Vector Representation].</ref>
 
Beginning in the 2010s [[Dyalog]]-based APL dialects including [[ngn/apl]], [[dzaima/APL]], and [[APL\iv]] have removed function definition in favor of [[dfn]]s. Wikipedia has a comparison of [[Wikipedia:Direct_function#Dfns_versus_tradfns|dfns versus tradfns]].
 
In many dialects the function header syntax of defined functions is adapted to allow user-defined [[operator]]s as well. A tradfn operator can also be called a '''tradop''' (pronounced "trad op"), parallel to how a "dfn" operator can be called a ''dop''.


== Examples ==
== Examples ==
Line 7: Line 11:
A simple [[dyadic function]]:
A simple [[dyadic function]]:
<source lang=apl>
<source lang=apl>
∇ r←l Tradfn r
      ∇ r←l Tradfn r
  ⍝ ...do something
        ⍝ ...do something
  r←l r
        r←l r
     
</source>
</source>
{{Works in|[[Dyalog APL]], [[APL2]], [[GNU APL]], [[NARS2000]], [[APLX]], and every older APL from [[APL\360]]}}
{{Works in|[[Dyalog APL]], [[APL2]], [[GNU APL]], [[NARS2000]], [[APLX]], and every older APL from [[APL\360]]}}
Line 16: Line 20:
An [[ambivalent function]] with an optional left argument, a conditional [[control structure]], one local variable, and a [[#Shyness|shy]] result:
An [[ambivalent function]] with an optional left argument, a conditional [[control structure]], one local variable, and a [[#Shyness|shy]] result:
<source lang=apl>
<source lang=apl>
∇ {res}←{left} AddMult2 right;local
      ∇ {res}←{left} AddMult2 right;local
  :If 0=⎕NC'left'    ⍝ if variable "left" is not defined already
        :If 0=⎕NC'left'    ⍝ if variable "left" is not defined already
      left←0
            left←0
  :EndIf
        :EndIf
  local←left+right
        local←left+right
  res←2×local
        res←2×local
     
       AddMult2 3    ⍝ result is "shy"
       AddMult2 3    ⍝ result is "shy"
       ⎕←AddMult2 3  ⍝ coerce display of result
       ⎕←AddMult2 3  ⍝ coerce display of result
Line 33: Line 37:


=== Brackets ===
=== Brackets ===
[[GNU APL]] allows functions and operators to accept an [[function axis|axis]] argument:<ref>[https://www.gnu.org/software/apl/apl.html#Section-3_002e2 3.2 Axis argument in defined functions] – GNU APL Manual</ref>
[[GNU APL]] allows functions and operators to accept an [[function axis|axis]] argument:<ref>[[GNU APL community]]. GNU APL Info Manual. [https://www.gnu.org/software/apl/apl.html#Section-3_002e2 Axis argument in defined functions].</ref>
<source lang=apl>
<source lang=apl>
∇ Z←Average[X] B
      ∇ Z←Average[X] B
  Z←(+/[X]B) ÷ (⍴B)[X]
        Z←(+/[X]B) ÷ (⍴B)[X]
     
       Average[1] 5 5⍴⍳25
       Average[1] 5 5⍴⍳25
11 12 13 14 15
11 12 13 14 15
Line 47: Line 51:
A [[monadic operator]] and a [[dyadic operator]], both deriving [[monadic function]]s:
A [[monadic operator]] and a [[dyadic operator]], both deriving [[monadic function]]s:
<source lang=apl>
<source lang=apl>
∇ res←(Function SELF) right
      ∇ res←(Function SELF) right
  res←right Function right
        res←right Function right
     
       ×SELF 1 2 3 4 5
       ×SELF 1 2 3 4 5
1 4 9 16 25
1 4 9 16 25


∇ res←(FunctionF HOOK FunctionG) right
      ∇ res←(FunctionF HOOK FunctionG) right
  res←right FunctionF FunctionG right
        res←right FunctionF FunctionG right
     
       ÷HOOK|2 0 ¯7
       ÷HOOK|2 0 ¯7
1 1 ¯1
1 1 ¯1
Line 62: Line 66:
A monadic operator and a dyadic operator, both deriving [[dyadic function]]s:
A monadic operator and a dyadic operator, both deriving [[dyadic function]]s:
<source lang=apl>
<source lang=apl>
∇ res←left (Function SWAP) right
      ∇ res←left (Function SWAP) right
  res←right Function left
        res←right Function left
     
       3 2 -SWAP 10
       3 2 -SWAP 10
7 8
7 8


∇ res←left (FunctionF OVER FunctionG) right
      ∇ res←left (FunctionF OVER FunctionG) right
  res←(FunctionG left) FunctionF (FunctionG right)
        res←(FunctionG left) FunctionF (FunctionG right)
     
       2 ¯7 2+OVER|¯3 1 4
       2 ¯7 2+OVER|¯3 1 4
5 8 6
5 8 6
</source>
</source>
{{Works in|[[Dyalog APL]], [[APL2]], [[GNU APL]], [[NARS2000]], [[APLX]]}}
{{Works in|[[Dyalog APL]], [[APL2]], [[GNU APL]], [[NARS2000]], [[APLX]]}}
== Representations ==
The canonical representation form is equivalent to what the user would type into the [[line editor]] to define the function. An alternative representation consists of the entire [[session]] log transcript after having such a definition has been made. A tradfn operator can also be called a '''tradop''' (pronounced "trad op").


== Properties ==
== Properties ==
Line 94: Line 95:
<source lang=apl>
<source lang=apl>
       name←1 2 3
       name←1 2 3
∇ res←Dummy
      ∇ res←Dummy
  ⎕SHADOW'name'
        ⎕SHADOW'name'
  name←42
        name←42
  res←name
        res←name
∇                       
      ∇                       
       Dummy
       Dummy
42
42
Line 108: Line 109:
<source lang=apl>
<source lang=apl>
       name←1 2 3
       name←1 2 3
∇ res←Dummy
      ∇ res←Dummy
  ;name
        ;name
  name←42
        name←42
  res←name
        res←name
∇                       
      ∇                       
       Dummy
       Dummy
42
42
Line 123: Line 124:
A tradfn can return a function value as result. The returned function will replace the function and its arguments (if any) in the calling expression:
A tradfn can return a function value as result. The returned function will replace the function and its arguments (if any) in the calling expression:
<source lang=apl>
<source lang=apl>
    Fn←Apply name       
      ∇ Fn←Apply name       
[1]    :If name≡'plus'     
        :If name≡'plus'     
[2]        Fn←+             
            Fn←+             
[3]    :ElseIf name≡'times'
        :ElseIf name≡'times'
[4]        Fn←×             
            Fn←×             
[5]    :EndIf               
        :EndIf               
    ∇                       
      ∇                       
      3(Apply'plus')4
      3(Apply'plus')4
7
7
      3(Apply'times')4
      3(Apply'times')4
12
12
</source>{{Works in|[[Dyalog APL]]}}
</source>{{Works in|[[Dyalog APL]]}}
Line 139: Line 140:


The right argument and the result can be a name list instead of single name. The interpreter will unpack the right argument when the function is called, and collect the result when the function returns.<ref>[[Dyalog Ltd.]] Programming Reference Guide.  [https://help.dyalog.com/latest/#Language/Defined%20Functions%20and%20Operators/Namelists.htm Namelists].</ref>
The right argument and the result can be a name list instead of single name. The interpreter will unpack the right argument when the function is called, and collect the result when the function returns.<ref>[[Dyalog Ltd.]] Programming Reference Guide.  [https://help.dyalog.com/latest/#Language/Defined%20Functions%20and%20Operators/Namelists.htm Namelists].</ref>
 
<source lang=apl>
== A+ ==
      ∇ (c b a)←Rev(a b c)
      ∇
      Rev 1 2 3
3 2 1
</source>{{Works in|[[Dyalog APL]]}}
=== A+ differences===
[[A+]] uses a reworked style of function and operator definition than maintains the principle of a header that matches the way the function will be used, but differs in many details:
[[A+]] uses a reworked style of function and operator definition than maintains the principle of a header that matches the way the function will be used, but differs in many details:
* The result name is not included in the header; instead, the result of the last executed statement is returned (and so functions that do not return a result cannot be defined).
* The result name is not included in the header; instead, the result of the last executed statement is returned (and so functions that do not return a result cannot be defined).
* The header is separated from the body with a colon, and the body of a multi-line function is enclosed in curly braces.
* The header is separated from the body with a colon, and the body of a multi-line function is enclosed in curly braces.
* Functions have lexical scope. Variables assigned are local by default, and can be made global by enclosing their names in parentheses when assigning.
* Functions have lexical scope. Variables assigned are local by default, and can be made global by enclosing their names in parentheses when assigning.
== Comparison to dfns ==
Wikipedia has a comparison of [[Wikipedia:Direct_function#Dfns_versus_tradfns|dfns versus tradfns]].


==External links==
==External links==
Line 155: Line 158:


=== Documentation ===
=== Documentation ===
* [https://help.dyalog.com/latest/#Language/Introduction/Functions.htm#Functions Dyalog – Introduction – Functions]
* Dyalog: [https://help.dyalog.com/latest/#Language/Introduction/Functions.htm Functions], [https://help.dyalog.com/latest/#Language/Introduction/Operators.htm Operators]
* [https://help.dyalog.com/latest/#Language/Defined%20Functions%20and%20Operators/Canonical%20Representation.htm#CanonicalRepresentation Dyalog – Defined Functions & Operators] <!-- links to Canonical Representation, but it's a bit confusing -->
* APLX: [http://microapl.com/apl_help/ch_020_010_070.htm User-defined Functions], [http://microapl.com/apl_help/ch_020_010_090.htm User-defined Operators]
* [http://microapl.com/apl_help/ch_020_010_070.htm APLX]


=== References ===
=== References ===

Navigation menu