Skip to content

Instantly share code, notes, and snippets.

@y2q-actionman
Last active September 27, 2018 08:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save y2q-actionman/0c4d0c13659b23670ecdc76024f9428e to your computer and use it in GitHub Desktop.
Save y2q-actionman/0c4d0c13659b23670ecdc76024f9428e to your computer and use it in GitHub Desktop.
Common Lisp での Perl の $_ の適当実装
;;; 毎回 setf する (lambda と相性悪い)
(defmacro progn-$_ (&body forms)
`(let ($_)
,@(mapcar
(lambda (form)
`(setf $_ ,form))
forms)))
#|
CL-USER> (progn-$_ 1 2 3)
3
CL-USER> (macroexpand +)
(LET ($_) (SETF $_ 1) (SETF $_ 2) (SETF $_ 3))
T
CL-USER> (progn-$_ 1 (+ $_ 2) (+ $_ 3))
6
CL-USER> (macroexpand +)
(LET ($_) (SETF $_ 1) (SETF $_ (+ $_ 2)) (SETF $_ (+ $_ 3)))
T
|#
;;; let の nest に展開
(defmacro progn-$_ (&body forms)
(if (> (length forms) 1)
`(let (($_ ,(first forms)))
(progn-$_ ,@(rest forms)))
(first forms)))
#|
CL-USER> (progn-$_ 1 2 3)
3
CL-USER> (progn-$_ 1 (+ $_ 2) (+ $_ 3))
6
|#
;;; 素直にlet*に展開
(defmacro progn-$_ (&body forms)
`(let* ,(loop for form in (butlast forms)
collect `($_ ,form))
,@(last forms)))
#|
CL-USER> (progn-$_ 1 2 3)
3
CL-USER> (macroexpand +)
(LET* (($_ 1) ($_ 2)) 3)
T
CL-USER> (progn-$_ 1 (+ $_ 2) (+ $_ 3))
6
CL-USER> (macroexpand +)
(LET* (($_ 1) ($_ (+ $_ 2))) (+ $_ 3))
T
|#
;;; ここまでで (15 min)
;;; その場の package の $_ を使う(必要なら他でも可)
(defmacro progn-$_ ((&optional ($_ (intern "$_" *package*))) &body forms)
`(let* ,(loop for form in (butlast forms)
collect `(,$_ ,form))
,@(last forms)))
#|
CL-USER> (progn-$_ () 1 2 3)
3
CL-USER> (macroexpand +)
(LET* (($_ 1) ($_ 2)) 3)
T
CL-USER> (progn-$_ () 1 (+ $_ 2) (+ $_ 3))
6
CL-USER> (macroexpand +)
(LET* (($_ 1) ($_ (+ $_ 2))) (+ $_ 3))
T
CL-USER> (progn-$_ (*) 1 (+ * 2) (+ * 3))
6
CL-USER> (macroexpand +)
(LET* ((* 1) (* (+ * 2))) (+ * 3))
T
|#
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment