Translation of D-functions into tacit form ------------------------------------------ The following monadic functions are said to be "extensionally equal" because given the same argument they return the same result. Conversely, they are "intensionally distinct" as their codings differ. {â¬â´â´âµ} â D-function (â¬â´â´) â Fork â¬ââ´ââ´ â Composition NB: these functions are extensionally equal only in a monadic context: if a left argument is supplied, their behaviours diverge: the dfn ignores it; the fork uses it; and the composition objects to it. (muse: A significant difference between the dfn coding and the other two is that the dfn's curly braces serve as a "quoting mechanism" with respect to the dereferencing (look-up) of names. Names in dfns are dereferenced at _application_ time, while those in trains and compositions are dereferenced at _definition_ time: tax â 10 â 10% tax dfn â {âµÃ1+tax÷100} â dfn including-tax calculation train â (1+tax÷100)Ã⢠â train .. .. .. comp â (1+tax÷100)âà â composition .. .. (dfn, train, comp) 20 â tests: 20 + tax â 22 22 22 22 dfn â train â comp â display of functions {âµÃ1+tax÷100} 1.1Ã⢠1.1âà tax â 12 â tax hike to 12% (dfn, train, comp) 20 â only dfn uses new tax rate 22.4 22 22 ) The following seven rules, applied recursively, transform a single line dfn into tacit form: {X f Y} â ({X} f {Y}) â fgh-fork rule: {XfY} { f Y} â ( f {Y}) â gh-atop {fY} {A f Y} â ( A f {Y}) â Agh-fork {AfY} {X f A} â (A(â¢fâ£){X}) â commute {XfA} {âº} â ⣠â left (base case) {âº} {âµ) â ⢠â right (base case) {âµ} {A} â ((A)â£â£) â constant (unusual base case) {A} where: X, Y are array-valued expressions with either ⺠or âµ free. A is a constant array-valued expression, with neither ⺠nor âµ free. f is a function-valued expression, with neither ⺠nor âµ free. where: ⺠(resp âµ) is said to occur "free" in an expression if any occurrence of it is not enclosed in curly braces. For example, ⺠(but not âµ) is free in expression (âº+2{âº+âµ}3). Translation example: {(2+âº)ÃâµÃ·3} â rule {XfY}, à is principal (leftmost outer) fn ¯¯¯¯¯¯¯¯¯¯¯ â ({2+âº}Ã{âµÃ·3}) â .. {AfY} ¯¯¯¯¯ â ((2+{âº})Ã{âµÃ·3}) â .. {âº} ¯¯¯ â ((2+â£)Ã{âµÃ·3}) â .. {XfA} ¯¯¯¯¯ â ((2+â£)Ã{3(â¢Ã·â£)âµ}) â .. {AfY} ¯¯¯¯¯¯¯¯¯ â ((2+â£)Ã(3(â¢Ã·â£){âµ})) â .. {âµ} ¯¯¯ â ((2+â£)Ã(3(â¢Ã·â£)â¢)) â tacit form For vector (strand) syntax we need a further rule: X Y Z ... â ((âX),(âY),(âZ),...) (X Y) where X, Y, Z, ... are array-valued expressions. Square-bracket indexing should be replaced with the equivalent index function: X[Y] â ((âY)â·X) X[Y] and embedded assignments replaced with inner dfns: {n+nâ1+âµ} â {{âµ+âµ}1+âµ} (â) These rules are sufficient to translate single-line dfns into tacit form. How- ever, the resulting function train will typically be longer than necessary. For example: {(+â¿âµ)÷â¢âµ} â {XfY} "mean" (ignores left argument) ¯¯¯¯¯¯¯¯¯¯ â ({+â¿âµ}÷{â¢âµ}) â {fY} {fY} ¯¯¯¯¯ ¯¯¯¯ â (((+â¿){âµ})÷((â¢){âµ})) â {âµ} {âµ} ¯¯¯ ¯¯¯ â (((+â¿)â¢)÷((â¢)â¢)) â removing superflous parentheses (()) ¯ ¯ ¯ ¯ â ((+â¿â¢)÷(â¢â¢)) â final non-optimal form (see below) Optimisation ¯¯¯¯¯¯¯¯¯¯¯¯ (fâ¢)g(hâ¢) â (f g h)⢠â ⢠factoring (â¢gâ¢) (fâ¢)g ⢠â (f g â¢)⢠â ⢠factoring (â¢gâ¢) ⣠g ⢠â g â dyadic function application (â£gâ¢) (f(g h)) â ((f g)h) â association (f(gh)) leading to a shortening of the above example "mean": â ((+â¿â¢)÷(â¢â¢)) â (â¢gâ¢) (()) ¯¯¯¯¯¯¯¯¯¯ â (+â¿Ã·â¢)⢠â optimal form where the final ⢠is present only to ignore an unwanted left argument. More examples: {(âââµ)â·âµ} â {XfY} "sort" (Phil Last) ¯¯¯¯¯¯¯¯¯ â ({âââµ}â·{âµ}) â {fY} {âµ} ¯¯¯¯¯ ¯¯¯ â ((â{ââµ})â·â¢) â {fY} {âµ} ¯¯¯¯ â ((â(ââ¢))â·â¢) â (f(gh)) ¯¯¯¯¯¯¯ â (((ââ)â¢)â·â¢) â (â¢gâ¢) ¯ ¯ â ((ââ)â·â¢)⢠â (â¢gâ¢) {(ââ¬),âµ} â {AfY} {âµ} ¯¯¯¯¯¯¯¯ â ((ââ¬),â¢) â (see optimisation below) {âµ âµ} â (X Y) ¯¯¯ â {(ââµ),(ââµ)} â {XfY} ¯¯¯¯¯¯¯¯¯¯¯ â ({ââµ},{ââµ}) â {fY} {âµ} ¯¯¯¯ ¯¯¯¯ â ((ââ¢),(ââ¢)) â (â¢gâ¢) ¯¯¯¯¯¯¯¯¯ â (â,â)⢠{âµ[âº]} â X[Y] ¯¯¯¯ â {(ââº)â·âµ} â {XfY} {âµ} ¯¯¯¯¯¯¯¯ â ({ââº}â·â¢) â {fY} {âº} ¯¯¯¯¯¯ â ((ââ£)â·â¢) {32+âµÃ1.8} â {AfY} °C â °F ¯¯¯¯¯¯¯¯¯¯ â (32+{âµÃ1.8}) â {XfA} {âµ} ¯¯¯¯¯¯¯ â (32+(1.8(â¢Ãâ£)â¢)) â (â¢Ãâ£) â à (à is commutative) ¯¯¯¯¯ â (32+(1.8Ãâ¢)) The last example results in a form for which, unlike the original dfn coding, ⣠has an inverse: F â 32+(1.8Ãâ¢) â °C â °F F ¯273.15 ¯40 0 100 â Fahrenheit from Celsius ¯459.67 ¯40 32 212 C â Fâ£Â¯1 â °F â °C C ¯459.67 ¯40 32 212 â Celsius from Fahrenheit ¯273.15 ¯40 0 100 Restrictions and Extensions --------------------------- [1] The process cannot translate an expression that contains ⺠or âµ free in the operand of an operator: {(ââ£âµ)'Doh!'} ¯ [2] Nor will it transform a recursive call â. Although it seems likely (to JMS) that rules might be discovered for replacing some cases of recursion with the power operator â£. [3] For multi-line dfns, Phil Last has shown us how to transform a guard into a simple expression using /. See examples in âpowâ and âcondâ. {C:TâF} â {â{F}/(â³~C),{T}/(â³C),ââµ} â (:â) where C, T and F are expressions. Unfortunately, guard expression C is eval- uated twice in the transformed code. Note, however, that if neither T nor F makes reference to âº, then expression C may be evaluated just once and its result passed as left argument to an inner function: {C:TâF} â ((C){â{F}/(â³~âº),{T}/(â³âº),ââµ}â¢) â (:â) T,F "monadic" (muse: There was overwhelming cultural pressure, in the specification of primi- tive power operator â£, for the "repeat count" to be the right _operand_. Had the repeat count been assigned to the left _argument_ of a monadic operator, as in âpowâ, rule (â) could have been the slightly simpler: {C:TâF} â {(~C){F}⣠C{T}⣠âµ} â (:â) ¯ ¯ Oh, and the _monadic_ derived function could have been "fixpoint": (1+÷)⣠1 â 1+÷ 1+÷ ... 1 1.61803 ¯ ) There is plenty of scope for further optimisation, particularly by employing the compose (â) and commute (â¨) operators: (A g â¢) â Aâ(g) ⢠(f g)⢠â fâ(g) ⢠(â¢gâ£) â g⨠fâ¨â¨ â f fâ¨âA â Aâ(f) Aâ(fâ¨) â (fâA) ... On optimisation: "By what course of calculation can these results be arrived at by the machine in the shortest time?" - Passages from the Life of a Philosopher, Charles Babbage, 1864, p.137. Tacit programming in the large ------------------------------ It is possible to write substantial programs using predominatly tacit style. See Aaron Hsu's Co-dfns compiler for a high-performance parallel version of APL: https://github.com/arcfide/Co-dfns Source files c.cd, d.cd, e.cd and f.cd are good examples. Examples: F â 32+(1.8Ãâ¢) â F â 32+1.8âà ((ââ¬),â¢) â (ââ¬)â, See also: dft defs Back to: contents Back to: Workspaces
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4