-
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
Prefer n-ary over unary combinators where possible #308
Conversation
I have marked this PR as a draft because I have not yet got around to auditing relevant docs and tests. I have also benchmarked |
Indeed I am now of the opinion that generality in these combinators is a more desirable trait than maintaining identical performance with their previous versions; see below. Here are some benchmarks inspired by #72 that use ;;; on.el --- benchmarks for -on -*- lexical-binding: t -*-
(defun on-binary (op trans)
(lambda (x y)
(funcall op (funcall trans x) (funcall trans y))))
(defun on-biniadic (op trans)
(lambda (x y &rest args)
(if args
(apply op (funcall trans x) (funcall trans y)
(mapcar trans args))
(funcall op (funcall trans x) (funcall trans y)))))
(defun on-binariadic (op trans)
(lambda (x y &rest args)
(apply op (mapcar trans `(,x ,y ,@args)))))
(defun on-variadic (op trans)
(lambda (&rest args)
(apply op (mapcar trans args))))
(dolist (on '(on-binary on-binary on-biniadic on-binariadic on-variadic))
(let ((list (mapcar #'number-to-string (number-sequence 0 10000)))
(cmp (funcall on #'> #'string-to-number)))
(garbage-collect)
(apply #'message "%-14s %9.6f %2d %.3f" on
(benchmark-run 100
(sort list cmp)))))
;;; on.el ends here Running them in the following Emacs version:
Gives the following results:
The extra consing involved in the variadic implementations clearly slows down the returned function. One solution would be to go with the implementation of My argument, however, is that we ought to go with
WDYT? |
I intend to mark this PR as ready to review after the issues that PR #309 addresses are fixed, so that this branch can be rebased. |
I have spent the past few weeks learning txr lisp which has it's own (n-ary) versions of these combinators which I found useful. I wrote some txr code for comparing function runtimes and simple code complexity measures (maxdepth, number of symbols, etc), and was thinking that these measures might also be useful for elsa. In principle there ought to be some empirical way of determining the best trade off between runtime & complexity under different situations, e.g. by doing some data analysis on large amounts of lisp code pulled from github, but as it stands I agree with the prognosis of @basil-conto |
I have now adapted the docs and tests, and have rebased the branch on PR #309 so that the tests can pass on all Emacs versions. Ideally if that PR is merged I will then mark this PR as ready to review. |
Of course, it's possible to optimise I think I'll wait until after #356 is addressed to implement that, though. |
README.md
Outdated
(-filter (-not (-partial '< 4)) '(1 2 3 4 5 6 7 8)) ;; => '(1 2 3 4) | ||
(funcall (-not #'even?) 5) ;; => t | ||
(-filter (-not (-partial #'< 4)) '(1 2 3 4 5 6 7 8)) ;; => '(1 2 3 4) | ||
(funcall (-not #'>) 1 2) ;; => t |
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 just tried something like this yesterday and was sad it doesn't work with a binary predicate. Definitely a welcome change.
I agree completely that the performance here is secondary. First come the users and then we can optimize what is reported to be slow. This has so far always turned out to be the correct way forward. |
This is a rewrite and extension of PR #72 to address issue #306. For discussion, especially wrt performance, see PRs #72 and #308. * dash.el (-on, -flip, -not, -orfn, -andfn): Return a variadic function. Declare as pure and side-effect-free. (-rotate-args): New combinator suggested by @vapniks in PR #72. (-const): Declare as pure and side-effect-free. * NEWS.md (2.19.0): Announce -rotate-args and variadic combinators. * dev/examples.el (-partition-after-pred): Fix oddp bug waiting to happen with negative dividends. (-cons*): Check that &rest args are safe to mutate. (-on, -flip, -const, -not, -orfn, -andfn): Extend tests. (-rotate-args): New test. * README.md: * dash.texi: Regenerate docs.
This is a more focused and efficient rewrite of PR #72 in order to address issue #306.
Cc: @vapniks