/usr/share/common-lisp/source/curry-compose-reader-macros/curry-compose-reader-macros.lisp is in cl-curry-compose-reader-macros 20141217-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | ;;; 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 #\)))))
|