This repository has been archived by the owner on Oct 15, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 21
/
Copy pathdollar.el
101 lines (78 loc) · 2.96 KB
/
dollar.el
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
;;; dollar.el --- Shorthand lambda notation -*- lexical-binding: t; -*-
;; Copyright (C) 2018, 2019, 2023 Göktuğ Kayaalp
;; Author: Göktuğ Kayaalp <self@gkayaalp.com>
;; Keywords: lisp
;; Version: 0.2
;; URL: https://dev.gkayaalp.com/elisp/index.html#dollar-el
;; Package-Requires: ((emacs "25"))
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;; This package provides a macro named $ where in its body symbols in
;; the form $N where N is a positive integer are to stand for
;; positional arguments to the generated lambda.
;; If the car of the body is a vector though, that vector becomes the
;; argument list of the new lambda.
;;; Code:
(require 'seq)
(require 'dash)
;; Exclude quoted expressions from search.
;; cf. https://github.com/cadadr/elisp/issues/43
(defun $--eliminate-quoted (expr)
(cond
((and (consp expr)
(eq (car expr) 'quote))
nil)
((consp expr)
(cons ($--eliminate-quoted (car expr))
($--eliminate-quoted (cdr expr))))
(t
expr)))
(defun $--find-args (seq)
(seq-sort
(lambda (sym1 sym2)
(< (string-to-number (substring (symbol-name sym1) 1))
(string-to-number (substring (symbol-name sym2) 1))))
(seq-filter
(lambda (x)
(and (symbolp x)
(equal 0 (string-match "\\$[0-9]+" (symbol-name x)))))
(seq-uniq
(-flatten
($--eliminate-quoted seq))))))
(defmacro $ (&rest body)
"Shortcut for lambdas.
Inside this form symbols in the form $N where N is a positive
integer are to stand for positional arguments to the generated
lambda.
If the car of the BODY is a vector though, that vector becomes
the argument list of the new lambda.
Within the body, $_ stands for arguments not used within the
body, i.e. the argument list is the N args used within the body
plus \"&rest $_\"; $* contains the entire argument list,
including what $_ matches, as a cons cell whose car is a vector
of positional arguments and whose cdr is the value of $_."
(let ((head (car body))
(tail (cdr body))
args the-body)
(if (vectorp head)
;; Convert it to a list.
(setf args (seq-into head 'list)
the-body tail)
(setf args ($--find-args body)
the-body body))
`(lambda
(,@args &rest $_)
(let (($* (cons (vector ,@args) $_)))
,@the-body))))
;;; Footer:
(provide 'dollar)
;;; dollar.el ends here