pax_global_header00006660000000000000000000000064124416171600014514gustar00rootroot0000000000000052 comment=b110fe85555feb13743d7ab1eb390849db386f96 curry-compose-reader-macros-20141217-git/000077500000000000000000000000001244161716000200715ustar00rootroot00000000000000curry-compose-reader-macros-20141217-git/README.md000066400000000000000000000045631244161716000213600ustar00rootroot00000000000000# CURRY-COMPOSE-READER-MACROS Reader macros for concise expression of function partial application and composition. These reader macros expand into the `curry`, `rcurry` and `compose` functions from the Alexandria library. The contents of curly brackets are curried and the contents of square brackets are composed. The `_` symbol inside curly brackets changes the order of arguments with `rcurry`. The following examples demonstrate usage. ;; partial application `curry' (mapcar {+ 1} '(1 2 3 4)) ; => (2 3 4 5) ;; alternate order of arguments `rcurry' (mapcar {- _ 1} '(1 2 3 4)) ; => (0 1 2 3) ;; function composition (mapcar [#'list {* 2}] '(1 2 3 4)) ; => ((2) (4) (6) (8)) Additionally, if optional utf8 support is enabled, special brackets may be used to split arguments amongst a list of functions and collect the results. ;; function split and join (mapcar «{* 2} {* 3}» '(1 2 3 4)) ; => ((2 3) (4 6) (6 9) (8 12)) To use call `enable-curry-compose-reader-macros` from within `eval-when` to ensure that reader macros are defined for both compilation and execution. (eval-when (:compile-toplevel :load-toplevel :execute) (enable-curry-compose-reader-macros)) Or to load utf8 support as well (which is probably going too far). (eval-when (:compile-toplevel :load-toplevel :execute) (enable-curry-compose-reader-macros :include-utf8)) Emacs users may easily treat `{}`'s, `[]`'s and `«»`'s as parenthesis for paredit commands and SEXP movement with the following configuration. ;; Syntax table (modify-syntax-entry ?\[ "(]" lisp-mode-syntax-table) (modify-syntax-entry ?\] ")[" lisp-mode-syntax-table) (modify-syntax-entry ?\{ "(}" lisp-mode-syntax-table) (modify-syntax-entry ?\} "){" lisp-mode-syntax-table) ;; optional UTF8 characters (modify-syntax-entry ?\« "(»" lisp-mode-syntax-table) (modify-syntax-entry ?\» ")«" lisp-mode-syntax-table) ;; Paredit keys (eval-after-load "paredit" '(progn (define-key paredit-mode-map "[" 'paredit-open-parenthesis) (define-key paredit-mode-map "]" 'paredit-close-parenthesis) (define-key paredit-mode-map "(" 'paredit-open-bracket) (define-key paredit-mode-map ")" 'paredit-close-bracket) (define-key paredit-mode-map "{" 'paredit-open-curly) (define-key paredit-mode-map "}" 'paredit-close-curly))) curry-compose-reader-macros-20141217-git/curry-compose-reader-macros.asd000066400000000000000000000005341244161716000261150ustar00rootroot00000000000000(defsystem :curry-compose-reader-macros :description "reader macros for concise function partial application and composition" :author "Eric Schulte " :version "1.0.0" :licence "GPL V3" :depends-on (alexandria) :components ((:file "package") (:file "curry-compose-reader-macros" :depends-on ("package")))) curry-compose-reader-macros-20141217-git/curry-compose-reader-macros.lisp000066400000000000000000000106461244161716000263220ustar00rootroot00000000000000;;; curry-compose-reader-macros --- partial application and composition ;; Copyright (C) Eric Schulte 2013 ;; Licensed under the Gnu Public License Version 3 or later ;;; Commentary ;; Reader macros for concise expression of function partial ;; application and composition. ;; ;; These reader macros expand into the `curry', `rcurry' and `compose' ;; functions from the Alexandria library. The contents of curly ;; brackets are curried and the contents of square brackets are ;; composed. The `_' symbol inside curly brackets changes the order ;; of arguments with `rcurry'. ;; ;; The following examples demonstrate usage. ;; ;; ;; partial application `curry' ;; (mapcar {+ 1} '(1 2 3 4)) ; => (2 3 4 5) ;; ;; ;; alternate order of arguments `rcurry' ;; (mapcar {- _ 1} '(1 2 3 4)) ; => (0 1 2 3) ;; ;; ;; function composition ;; (mapcar [#'list {* 2}] '(1 2 3 4)) ; => ((2) (4) (6) (8)) ;; ;; ;; function split and join (with the `include-utf8' option) ;; (mapcar «{* 2} {* 3}» '(1 2 3 4)) ; => ((2 3) (4 6) (6 9) (8 12)) ;; ;; Call `enable-curry-compose-reader-macros' from within `eval-when' ;; to ensure that reader macros are defined for both compilation and ;; execution. ;; ;; (eval-when (:compile-toplevel :load-toplevel :execute) ;; (enable-curry-compose-reader-macros)) ;; ;; Or to load utf8 support as well (which is probably going too far). ;; ;; (eval-when (:compile-toplevel :load-toplevel :execute) ;; (enable-curry-compose-reader-macros :include-utf8)) ;; ;; Emacs users may easily treat {}'s, []'s and «»'s as parenthesis ;; for paredit commands and SEXP movement with the following ;; configuration. ;; ;; ;; Syntax table ;; (modify-syntax-entry ?\[ "(]" lisp-mode-syntax-table) ;; (modify-syntax-entry ?\] ")[" lisp-mode-syntax-table) ;; (modify-syntax-entry ?\{ "(}" lisp-mode-syntax-table) ;; (modify-syntax-entry ?\} "){" lisp-mode-syntax-table) ;; (modify-syntax-entry ?\« "(»" lisp-mode-syntax-table) ;; (modify-syntax-entry ?\» ")«" lisp-mode-syntax-table) ;; ;; ;; Paredit keys ;; (eval-after-load "paredit" ;; '(progn ;; (define-key paredit-mode-map "[" 'paredit-open-parenthesis) ;; (define-key paredit-mode-map "]" 'paredit-close-parenthesis) ;; (define-key paredit-mode-map "(" 'paredit-open-bracket) ;; (define-key paredit-mode-map ")" 'paredit-close-bracket) ;; (define-key paredit-mode-map "{" 'paredit-open-curly) ;; (define-key paredit-mode-map "}" 'paredit-close-curly))) ;;; Code: (in-package :curry-compose-reader-macros) (defun enable-curry-compose-reader-macros (&optional include-utf8) "Enable concise syntax for Alexandria's `curry', `rcurry' and `compose'. Calls to this function should be wrapped in `eval-when' as shown below to ensure evaluation during compilation. (eval-when (:compile-toplevel :load-toplevel :execute) (enable-curry-compose-reader-macros)) " ;; partial application with {} using Alexandria's `curry' and `rcurry' (set-syntax-from-char #\{ #\( ) (set-syntax-from-char #\} #\) ) (defun lcurly-brace-reader (stream inchar) (declare (ignore inchar)) (let ((spec (read-delimited-list #\} stream t))) (if (eq (cadr spec) '_) `(rcurry (function ,(car spec)) ,@(cddr spec)) `(curry (function ,(car spec)) ,@(cdr spec))))) (set-macro-character #\{ #'lcurly-brace-reader) (set-macro-character #\} (get-macro-character #\) )) ;; composition with [] using Alexandria's `compose' (set-syntax-from-char #\[ #\( ) (set-syntax-from-char #\] #\) ) (defun lsquare-brace-reader (stream inchar) (declare (ignore inchar)) (cons 'compose (read-delimited-list #\] stream t))) (set-macro-character #\[ #'lsquare-brace-reader) (set-macro-character #\] (get-macro-character #\) )) (when include-utf8 ;; inform lisp that source code is encoded in UTF-8 #+sbcl (setf sb-impl::*default-external-format* :UTF-8) ;; list split collection with «» (set-syntax-from-char #\« #\( ) (set-syntax-from-char #\» #\) ) (defun langle-quotation-reader (stream inchar) (declare (ignore inchar)) (let ((funcs (cons 'list (read-delimited-list #\» stream t)))) `(compose (curry #'mapcar #'funcall ,funcs) (curry #'make-list ,(length funcs) :initial-element)))) (set-macro-character #\« #'langle-quotation-reader) (set-macro-character #\» (get-macro-character #\))))) curry-compose-reader-macros-20141217-git/package.lisp000066400000000000000000000002001244161716000223450ustar00rootroot00000000000000(defpackage #:curry-compose-reader-macros (:use :common-lisp :alexandria) (:export :enable-curry-compose-reader-macros :_))