5

How do I pass a function as an argument?

The basic idea is something like this (which doesn't work):

∇R ← double a
R ← 2 × a
∇

∇R ← a applytwice f
R ← f f a
∇

5 applytwice double

Is there something like \fun in erlang or function-pointers in C?

Hyperboreus
  • 31,997
  • 9
  • 47
  • 87

3 Answers3

9

In APL, functions may not be passed as arguments to functions. However, APL has operators, which are higher order functions, that can take functions as arguments. There are primitive operators like / (reduction) used for example to sum up a vector +/v. The function + is the left operand and is passed into the operator /.

In Dyalog APL, there is a primitive operator using the (named "power") for apply a function n times so we can write:

      double←{2×⍵}
      (double ⍣ 2) 7
28
      (double ⍣ 10) 7
7168

You can also write your own operators (in most APLs). In Dyalog APL we can write your applytwice operator as:

     applytwice←{⍺⍺ ⍺⍺ ⍵}
     double applytwice 7
28

Finally, you can pass functions around by putting them in a namespace and passing the namespace around instead. This is like a very light weight instance of class with a method. For example:

       s←⎕NS ''
       s.f←{2×⍵}
       ApplyFTwice←{⍺.f ⍺.f ⍵}
       s ApplyFTwice 7
28

In this case, the function has to be named f, but we could many different functions named f, each in its own namespace.

Paul Mansour
  • 1,436
  • 9
  • 11
  • Thanks to you ample answer, I figured out how to define operators in GNU APL (simply adding some parentheses). Looks like in APL there is a strict distinction between operator and function, and "operator" refers to functors. – Hyperboreus Nov 08 '13 at 00:29
5

Your applytwice was not that far from correct. In Dyalog APL and possibly others, the non-dfn (legacy function definition) code would look something like this:

       ∇ R ← (f applytwice) a
  [1]   R ← f f a
       ∇

       - applytwice 42
  42

       {2×⍵} applytwice 42
  168

In APL, any "program" which accepts zero, one, or two data arguments is a "function". Built-in functions such as + - etc. might be called "primitive functions". The double function in the examples would be a "defined function". An "operator" accepts functions and data as arguments. +/ and +\ are examples of the reduction and scan operator, + is the function left argument for the / or \ operator. By contrast, the compress and expand functions use the same symbols (/ and \ ) but have a left data argument.

Such is the APL nomenclature.

Lobachevsky
  • 1,222
  • 9
  • 17
0

You can also get around this by quoting. You can pass a char array and then execute it within the function. This string might contain the name of a defined function or a direct definition.

luser droog
  • 18,988
  • 3
  • 53
  • 105
  • A good solution which would work on nearly all APL implementations, from IBM APL.SV (ca. 1970) and up. APL\360 (1968) didn't have execute, but everything that came later did. – Lobachevsky Aug 04 '19 at 13:09