Direct function

A direct function (dfn, pronounced "dee fun") is an alternative way to define a function and operator (a higher-order function) in the programming language APL. A direct operator can also be called a dop (pronounced "dee op"). They were invented by John Scholes in 1996. They are a unique combination of array programming, higher-order function, and functional programming, and are a major distinguishing advance of early 21st century APL over prior versions.

A dfn is a sequence of possibly guarded expressions (or just a guard) between {{code|

A dfn is a sequence of possibly guarded expressions (or just a guard) between {{code|

  • A dfn can be anonymous; a tradfn must be named.
  • A dfn is named by assignment (); a tradfn is named by embedding the name in the representation of the function and applying (a system function) to that representation.
  • A dfn is handier than a tradfn as an operand (see preceding items: a tradfn must be named; a tradfn is named by embedding ...).
  • Names assigned in a dfn are local by default; names assigned in a tradfn are global unless specified in a locals list.
  • Locals in a dfn have lexical scope; locals in a tradfn have dynamic scope, visible in called functions unless shadowed by their locals list.
  • The arguments of a dfn are named and and the operands of a dop are named and ; the arguments and operands of a tradfn can have any name, specified on its leading line.
  • The result (if any) of a dfn is unnamed; the result (if any) of a tradfn is named in its header.
  • A default value for ⍺ is specified more neatly than for the left argument of a tradfn.
  • Recursion in a dfn is effected by invoking or or its name; recursion in a tradfn is effected by invoking its name.
  • Flow control in a dfn is effected by guards and function calls; that in a tradfn is by control structures and (goto) and line labels.
  • Evaluating an expression in a dfn not ending in assignment causes return from the dfn; evaluating a line in a tradfn not ending in assignment or goto displays the result of the line.
  • A dfn returns on evaluating an expression not ending in assignment, on evaluating a guarded expression, or after the last expression; a tradfn returns on (goto) line 0 or a non-existing line, or on evaluating a control structure, or after the last line.
  • The simpler flow control in a dfn makes it easier to detect and implement tail recursion than in a tradfn.
  • A dfn may call a tradfn and vice versa; a dfn may be defined in a tradfn, and vice versa.


    Kenneth E. Iverson, the inventor of APL, was dissatisfied with the way user functions (tradfns) were defined. In 1974, he devised "formal function definition" or "direct definition" for use in exposition. A direct definition has two or four parts, separated by colons: name : expression name : expression0 : proposition : expression1 Within a direct definition, denotes the left argument and the right argument. In the first instance, the result of is the result of the function; in the second instance, the result of the function is that of if evaluates to 0, or if it evaluates to 1. Assignments within a direct definition are dynamically local. Examples of using direct definition are found in the 1979 Turing Award Lecture and in books and application papers.

    Direct definition was too limited for use in larger systems. The ideas were further developed by multiple authors in multiple works but the results were unwieldy. Of these, the "alternative APL function definition" of Bunda in 1987 came closest to current facilities, but is flawed in conflicts with existing symbols and in error handling which would have caused practical difficulties, and was never implemented. The main distillates from the different proposals were that (a) the function being defined is anonymous, with subsequent naming (if required) being effected by assignment; (b) the function is denoted by a symbol and thereby enables anonymous recursion.

    In 1996, John Scholes of Dyalog Limited invented direct functions (dfns). The ideas originated in 1989 when he read a special issue of The Computer Journal on functional programming. He then proceeded to study functional programming and became strongly motivated ("sick with desire", like Yeats) to bring these ideas to APL. He initially operated in stealth because he was concerned the changes might be judged too radical and an unnecessary complication of the language; other observers say that he operated in stealth because Dyalog colleagues were not so enamored and thought he was wasting his time and causing trouble for people. Dfns were first presented in the Dyalog Vendor Forum at the APL '96 Conference and released in Dyalog APL in early 1997. Acceptance and recognition were slow in coming. As late as 2008, in Dyalog at 25, a publication celebrating the 25th anniversary of Dyalog Limited, dfns were barely mentioned (mentioned twice as "dynamic functions" and without elaboration). As of 2019, dfns are implemented in Dyalog APL, NARS2000, and ngn/apl. They also play a key role in efforts to exploit the computing abilities of a graphics processing unit (GPU).