2

Is there something like apply-partially

(apply-partially FUN &rest ARGS)

Return a function that is a partial application of FUN to ARGS.
ARGS is a list of the first N arguments to pass to FUN.
The result is a new function which does the same as FUN, except that
the first N arguments are fixed at the values with with which this
function was called.

But with the "last N arguments are fixed"

Or "all arguments are fixed except wildcard" ie:

(defun foo (a b c))
(defalias 'fix-a-c-in-foo 'apply-partially-wildcard 'foo "a valuel" '_ "c value")

_ - random symbol that means "wildcard"

  • Is the fset-form in the following progn sufficient for your purpose? (progn (defun f(a1 a2) (+ a1 a2)) (let ((a2 2)) (fset #'f2 `(lambda (_) (f _ ,a2)))) (f2 1)) – Tobias Oct 23 '16 at 8:40
  • subr.el doesn't have one, but you could borrow one from here: github.com/magnars/dash.el#-rpartial-fn-rest-args – wvxvw Oct 23 '16 at 10:32
  • 1
    The latter sounds like -cut from dash.el – wasamasa Oct 23 '16 at 11:04
  • @wasamasa -cut looks promising. Thx! – JAre Oct 23 '16 at 18:10
3

You have everything you need in the emacs-lisp core language with fset, lambda expressions and backticks. The following source code is an extension of your second example. The comma expression allows you to easily substitute something in a back-tick quoted lambda expression and you can assign that expression to a symbol's function-cell with fset.

(defun foo (a b c d)
  (message "a=%s b=%s c=%s d=%s" a b c d))

(let ((fix-a "a-value"))
  (fset #'fix-a-c-in-foo `(lambda (_d _b) (foo ,fix-a _b "c-value" _d)))
  )

(fix-a-c-in-foo "new-d-value" "new-b-value")

I have added one more argument to foo to have at least two fix parameters and two "template" parameters. The template parameters _b and _d are swapped which would not be possible if you just had one symbol for all such parameters. Furthermore, I've wrapped the fset (corresponding to your defalias) in my version in a let to show that we can use the value of a local variable as fixed parameter in the template. The part of the above source code that solves your problem is just:

(fset #'fix-a-c-in-foo `(lambda (_d _b) (foo ,fix-a _b "c-value" _d)))
  • Thanks! Being surprised by let - passing settings by fset outside. – Andreas Röhler Oct 24 '16 at 8:33
4

apply-partially was most useful back when Emacs did not have lexical binding, since it let you build "closures". But for your example, you don't even need a closure:

(defalias 'fix-a-c-in-foo (lambda (b) (foo "a_value" b "c_value")))

for a more general case, OTOH you do need closures, so you'll want to add -*- lexical-binding:t -*- to the first line of your file and then you can do things like:

(defun whatever (a c)
  (lambda (b) (foo a b c)))

Also, note that (lambda (x y) (foo a x y)) is implemented more efficiently than (apply-partially #'foo a).

  • 1
    Why can't we use your function whatever with dynamic binding? For this special example I do not see a relevant difference between dynamic and lexical binding. Furthermore, Is something wrong with my answer? (I understand that I could/should use defalias instead of fset. But, beside of that...) – Tobias Oct 23 '16 at 16:28
  • Your answer is not wrong, but backquoting lambdas means you're generating source code at run-time, which prevents that code from being byte-compiled. – Stefan Oct 24 '16 at 0:29
  • Indeed, mapcar probably won't bind dynamically bind its own a or c so my example also worked in 99% of the cases with dynamic scoping. I've changed my example to really need lexical scoping. – Stefan Oct 24 '16 at 0:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.