Concatenative language/Concatenation is compositionA fundamental property of stack languages is that the concatenation of two programs For example, in Factor we can filter a sequence by a predicate using the ( scratchpad ) { 1 2 3 4 5 6 7 8 } [ even? ] filter . { 2 4 6 8 } If we want to remove elements matching the predicate instead, we can compose the predicate with the ( scratchpad ) { 1 2 3 4 5 6 7 8 } [ even? not ] filter . { 1 3 5 7 } Partial application works out very nicely too: write a quotation which pushes some of the parameters before calling a word: ( scratchpad ) { 1 2 3 4 5 6 7 8 } [ 4 > ] filter . { 5 6 7 8 } Compare these three quotations, [ even? ] [ even? not ] [ 4 > ] This is shorter than the equivalent in an applicative language, because we have to name the input argument, that is only used once. In Common Lisp for instance, (function evenp) (lambda (x) (not (evenp x))) (lambda (x) (> x 4)) Since concatenative languages do not have named parameters (let's ignore Factor's In Factor, quotations look like a sequence of objects; for example, Suppose we have the quotation Another fundamental operation on quotations is composition: suppose we take the quotation These two fundamental operations -- Examples of ( scratchpad ) 5 [ + ] curry . [ 5 + ] Compare with the applicative version; note the closure does not print readably: * (let ((x 5)) (lambda (y) (+ x y))) #<FUNCTION (LAMBDA (Y)) {11682335}> Examples of ( scratchpad ) [ 3 = ] [ not ] compose . [ 3 = not ] Applicative version: * (let ((f (lambda (x) (= x 3)))) (lambda (y) (not (funcall f y)))) #<FUNCTION (LAMBDA (Y)) {11680B3D}> As you can see, function composition and partial application feels a lot more natural in stack languages, because of the duality between composition and concatenation. This revision created on Wed, 31 Dec 2008 09:32:01 by mnestic (formatting) |
|
|
All content is © 2008-2010 by its respective authors. By adding content to this wiki, you agree to release it under the BSD license. |
|