-
Notifications
You must be signed in to change notification settings - Fork 137
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add `-defun' #347
base: master
Are you sure you want to change the base?
Add `-defun' #347
Changes from 3 commits
f3f29e3
6add372
3a63e45
727df5c
379e48c
24850aa
2e989aa
03186e0
6a87bae
95462fc
c4ffe96
6f2626f
bcfd26a
fd53121
92e623f
23749b3
6afe446
376acdb
34d618b
79a71d6
30a0de5
e0fb5d5
2f9fc8c
148a833
83a3c12
bcc9763
caf7445
7895a2b
9ac1487
d8cab22
8ac91de
66f513e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1166,7 +1166,7 @@ new list." | |
(-let (a b) (list a b)) => '(nil nil) | ||
(-let ((a) (b)) (list a b)) => '(nil nil) | ||
;; auto-derived match forms for kv destructuring | ||
;;; test that we normalize all the supported kv stores | ||
;;; test that we normalize all the supported kv stores | ||
(-let (((&plist :foo :bar) (list :foo 1 :bar 2))) (list foo bar)) => '(1 2) | ||
(-let (((&alist :foo :bar) (list (cons :foo 1) (cons :bar 2)))) (list foo bar)) => '(1 2) | ||
(let ((hash (make-hash-table))) | ||
|
@@ -1181,7 +1181,7 @@ new list." | |
(-let (((&hash? 'a) (funcall fn ht))) | ||
a)) => '(3) | ||
(-let (((_ &keys :foo :bar) (list 'ignored :foo 1 :bar 2))) (list foo bar)) => '(1 2) | ||
;;; go over all the variations of match-form derivation | ||
;;; go over all the variations of match-form derivation | ||
(-let (((&plist :foo foo :bar) (list :foo 1 :bar 2))) (list foo bar)) => '(1 2) | ||
(-let (((&plist :foo foo :bar bar) (list :foo 1 :bar 2))) (list foo bar)) => '(1 2) | ||
(-let (((&plist :foo x :bar y) (list :foo 1 :bar 2))) (list x y)) => '(1 2) | ||
|
@@ -1259,6 +1259,17 @@ new list." | |
(funcall (-lambda (a b) (+ a b)) 1 2) => 3 | ||
(funcall (-lambda (a (b c)) (+ a b c)) 1 (list 2 3)) => 6) | ||
|
||
(defexamples -defun | ||
(progn (-defun example/cdr ((_ . tail)) tail) | ||
(example/cdr '(a . b))) => 'b | ||
(progn (-defun example/car ((cur)) cur) | ||
(example/car '(a . b))) => 'a | ||
(progn (-defun example/add-cons ((a . b)) | ||
"Add the `car' and `cdr' of INPUT0." | ||
(interactive (list (cons 1 2))) | ||
(+ a b)) | ||
(command-execute #'example/add-cons)) => 3) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Aren't examples limited to a single line? Have you tried regenerating the docs from this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I haven't yet tried regenerating the docs - I'll do that later. I see some two-line examples in |
||
|
||
(defexamples -setq | ||
(progn (-setq a 1) a) => 1 | ||
(progn (-setq (a b) (list 1 2)) (list a b)) => '(1 2) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note the
-let
: previously,-let*
was used instead, which might be more efficient as the latter is implemented in terms of the latter. Not doing that might also make my various symbol and &as optimizations for naught. What do you think?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think I can say something intelligent on this, as I have not yet looked at the code closely.
But re:
-let
being implemented in terms of-let*
- I think that's an implementation detail that we should not base other design decisions on, since-let
should ideally be implemented only in terms of itself.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to make sure that input arguments are evaluated in parallel, whether with
-let
or-let*
doesn't matter much.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That wouldn't really affect the design -
-let
and-let*
can both be used in this position. However, currently-let*
is more efficient (both in terms of macro-expansion and less bytecode)::Evaluating the arguments in parallel or not doesn't make a difference here, as all binder-expressions don't reference any previously defined variables.
The trade off here is slightly better readability vs efficiency -
-let
makes it obvious that this won't be referring to variables defined earlier, but-let*
is more efficient, currently.Perhaps
-let
should be optimized more instead?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You would need to construct some kind of graph of dependencies between the bindings. Which I suppose was too much work and I simply leveraged the built-in let to handle it for me. But yes this is a possible optimization. In practice probably insignificant :) But it could be intelectually stimulating :D
You're right about the lambda, there the parallel eval is handled by the runtime when the arguments are passed to the "wrapper lambda".