{fix} ← ##.defn name                        ⍝ D-fine function.

Defn lets us type multi-line definitions directly into the session using ⍞ input
and output.

Defn anticipates the input of closing braces and infers an appropriate indentat-
ion  for  each prompt. "White dots" are included at each tab point in the prompt
to assist in keeping track of nesting levels.

In  the following annotated example, notice which characters are included in the
prompt and which must be typed when defining the sample function. In particular,
notice that no closing braces need be typed:

                        prompt      typed
    defn'dup'       ←   ------      -----
dup←{               ←   "dup←{"   |       Enter
·   {               ←   "·   "    | "{"   Enter
·   ·   ⍵ ⍵         ←   "·   ·   "| "⍵ ⍵" Enter
·   }⍵              ←   "·   }"   | "⍵"   Enter
}                   ←   "}"       |       Enter

Defn is a candidate for inclusion in a utility directory in ⎕SE, which is refer-
enced  using  ⎕PATH.  In  order to have the target function fixed in the calling
namespace, we must change the second line of the function:

from:
        ⎕FX···                                      ⍝ fix accumulated lines.
to:
        (⍎⊃⎕NSI).⎕FX···                             ⍝ fix accumulated lines.

In addition, we could include the following function somewhere along ⎕PATH. When
activated, it copies defn dynamically from this workspace to define a multi-line
D-function  in  reponse  to  the  SYNTAX ERROR  generated by the entry of an in-
complete line.

    din←{                                           ⍝ Multi-line D-input off/on.
        ⍺←0                                         ⍝ 0 => initialise ⎕trap
        ⍺≡0:⍵{                                      ⍝ set din on/off.
            ⍺:⎕trap,←⊂⍵                             ⍝ on: append trap entry.
            ⎕trap~←⊂⍵                               ⍝ off: remove trap entry.
        }(,2)'E' '(⎕cs'''')din ⎕io⊃¯2↑⎕se.Log'      ⍝ syntax error:: copy defn.
        ~'←{'≡¯2↑⍵:↑⎕DM                             ⍝ not defn: pass back error.
        (⍎⍺).{                                      ⍝ in calling space,
            defn←{}                                 ⍝ local defn function.
            ⍎'''defn''⎕cy''dfns'' ⋄ 0 defn ⍵'       ⍝ copy & define,
        }⍵                                          ⍝ called with first fn line.
    }

Having arranged that ⎕path can find din, we should be able to type:

      din 1         ⍝ trap incomplete dfn definitions.

      dup←{         ⍝ define multi-line dfn.
  ·   ·    ⍵ ⍵
  ·   }

      dup 0         ⍝ apply fn.
0 0
      ⎕cr'dup'      ⍝ show source.
dup←{
    ⍵ ⍵
}
      din 0         ⍝ revoke trap.

      dup←{         ⍝ incomplete dfn is now a syntax error.
SYNTAX ERROR

Technical notes:

After defining some local functions, the action takes place in an inner function
whose  right  argument  is a buffer of characters-to-be-processed and whose left
argument maintains state in the 4-tuple (dp bk la ca):

     ⍵  (buffer) characters input and waiting to be processed.

    dp  (depth) number of tab stops to indent next prompt.
    bk  (back) exdent next prompt and append '}'.
    la  (line accumulator) complete lines processed .
    ca  (character accumulator) characters processed in current line.

bk is set if the (rightmost diamond segment in a) line is not an assignment or a
guard. In this case defn infers that the following line should start with an ex-
dented closing '}'.

    {           ← opening brace: indent following line: dp+1
    ·   a←⍵     ← assignment: bk←0: don't exdent following line
    ·   1:⍵     ← guard:      bk←0:     ..      ..      ..
    ·   2+⍵     ← otherwise:  bk←1: exdent next line and prompt with '}'
    }           ← exdented closing brace prompt.

Examples:

      defn'dup'
dup←{⎕io←0
·   omega←⍵
·   {
·   ·   {
·   ·   ·   ⍵ ⍵
·   ·   }⍵
·   }omega
}
      dup 9
9 9

See also: dots

Back to: contents

Back to: Dyalog APL

Trouble seeing APL font?