curly
2012-04-07
Reader macros for easy function currying and composition.
Upstream URL
Author
License
1Description
Curly is set of two reader macros for easy function currying andcomposition. It was inspired by Arc's syntax for currying, usingsquare brackets. Curly creates anonymous functions (lambdas) withliteral function composition instead of trying smarter approach(like using (REDUCE #'FUNCALL ...)) so that the compiler is able todo more optimizations.ASDF system definition is included in curly.asd file.
Latest version of Curly can be obtained on its GitHub page: https://github.com/mpasternacki/curly
1.1Square bracket macro
Square bracket macro does simple currying::CURLY> '[foo] :(LAMBDA (#:G2705) (FOO #:G2705)) :CURLY> '[foo bar] :(LAMBDA (#:G2706) (FOO BAR #:G2706)) :CURLY> '[foo bar baz] :(LAMBDA (#:G2707) (FOO BAR BAZ #:G2707))
By using symbol configured by CURLY:*BLANK-ARGUMENT* user can put anonymous function's parameter in desired place, not necessarily at end of argument list. By default, blank argument is a single star, but it can be set e.g. to underscore to better match Arc:
:CURLY> '[foo bar * baz] :(LAMBDA (#:G2709) (FOO BAR #:G2709 BAZ)) :CURLY> '[foo * bar baz] :(LAMBDA (#:G2710) (FOO #:G2710 BAR BAZ))
Curly interpretes blank argument only in argument position; blank argument in functional position is left untouched:
:CURLY> '[* foo bar baz] :(LAMBDA (#:G2711) (* FOO BAR BAZ #:G2711)) :CURLY> '[* foo * baz] :(LAMBDA (#:G2712) (* FOO #:G2712 BAZ))
1.2Curly bracket macro
Curly bracket does function composition, which may be coupled withcurrying. Let's start from simple composition::CURLY> '{foo bar} :(LAMBDA (#:G2714) (FOO (BAR #:G2714))) :CURLY> '{foo bar baz} :(LAMBDA (#:G2715) (FOO (BAR (BAZ #:G2715)))) :CURLY> '{foo bar baz quux} :(LAMBDA (#:G2716) (FOO (BAR (BAZ (QUUX #:G2716)))))
And so on, and so on. When instead of a function name there is a list within the braces, this means currying:
:CURLY> '{foo (bar 23) baz quux} :(LAMBDA (#:G2721) (FOO (BAR 23 (BAZ (QUUX #:G2721))))) :CURLY> '{foo (bar 16) (baz 23 42) quux} :(LAMBDA (#:G2723) (FOO (BAR 16 (BAZ 23 42 (QUUX #:G2723)))))
Of course, when currying within braces, blank argument can be used as well:
:CURLY> '{foo (bar 16) (baz 23 * 42) quux} :(LAMBDA (#:G2724) (FOO (BAR 16 (BAZ 23 (QUUX #:G2724) 42)))) :CURLY> '{foo (bar 16) (baz * 23 42) quux} :(LAMBDA (#:G2725) (FOO (BAR 16 (BAZ (QUUX #:G2725) 23 42)))
2Reference
All Curly functions, macros and variables are exported from packageCURLY.2.1BLANK-ARGUMENT
Variable: specifies symbol that is used to indicate blank argumentfor currying. Default value is '*.2.2CURLY-READER stream character
Function: reader macro function for curly braces (composition).2.3SQUARE-READER stream character
Function: reader macro function for square braces (currying).2.4MAKE-CURLY-READTABLE &optional (original-readtable readtable)
Function: returns modified copy of ORIGINAL-READTABLE that hasCurly reader macros turned on.2.5ENABLE-CURLY-SYNTAX
Macro: enable curly syntax for current file.2.6DISABLE-CURLY-SYNTAX
Macro: disable curly syntax for current file.Warning: Calling DISABLE-CURLY-SYNTAX when curly syntax is not enabled can give funny results. Also, reading multiple files using ENABLE-CURLY-SYNTAX and DISABLE-CURLY-SYNTAX in different threads can invoke a disaster. ENABLE-CURLY-SYNTAX itself is safe.
3Testing
Unit tests are included in tests.lisp file. To run test, you needFiveAM testing framework along with required Arnesi library fromhttp://common-lisp.net/project/bese/.To run the tests, simply load curly with ASDF, and then type into REPL:
(asdf:operate 'asdf:test-op :curly)