3

In Common Lisp, there is constantly function, which creates new function without side-effects that takes any number of arguments and always returns specified value.

For some reason cl-lib doesn't provide cl-constantly, so I guess it should exist in pure Emacs Lisp under different name. Do you know that name?


Please don't post answers showing how to achieve effect of constantly manually (and how to define such function), since it's absolutely trivial. This question about name of already existing function. If there is no such function, a comment about the fact will do. I've sent a bug report asking to add the function.

Drew
  • 75,699
  • 9
  • 109
  • 225
Mark Karpov
  • 4,893
  • 1
  • 24
  • 53

3 Answers3

7

There is no constantly equivalent in Emacs (except ignore is like (constantly nil)), but dash provides one called -const as part of the dash-functional package.

-const (c)

Return a function that returns c ignoring any additional arguments.

In types: a -> b -> a

(funcall (-const 2) 1 3 "foo") ;; => 2
(-map (-const 1) '("a" "b" "c" "d")) ;; => '(1 1 1 1) 
(-sum (-map (-const 1) '("a" "b" "c" "d"))) ;; => 4
npostavs
  • 9,033
  • 1
  • 21
  • 53
1

There is no predefined Emacs-Lisp function for this, as far as I know.

Here is a definition - the same as is shown in the Common Lisp standard:

(defun constantly (object)
  (lambda (&rest arguments) object))

You need to have lexical-binding turned on (non-nil) for that definition. If you have it turned off (nil) then you can use this definition instead:

(defun constantly (object)
  `(lambda (&rest arguments) ',object))
Drew
  • 75,699
  • 9
  • 109
  • 225
  • So, why there is no `cl-constantly` then? – Mark Karpov Sep 29 '15 at 16:35
  • 1
    Emacs Lisp does not attempt to emulate all of Common Lisp. Ask `emacs-devel@gnu.org` or `M-x report-emacs-bug`, if you want to request that some Common-Lisp feature be added. – Drew Sep 29 '15 at 16:40
  • As far as quoting the lambda is concerned, please see http://emacs.stackexchange.com/a/3598/2223 . – jch Sep 29 '15 at 18:14
  • @jch, I think that should go in the comments to other answer, but of course you can type extra `#'` every time without any benefit increasing visual noise. In additional to my previous comment `constantly` is a conceptual tool and part of vocabulary, it does not matter what is shorter, `constantly` is embodiment of a certain idea. I can imagine if there were no such thing as `identity` you would say that `(lambda (x) x)` will do. – Mark Karpov Sep 29 '15 at 19:03
  • 1
    @jch: That lambda form is **not** quoted (and believe me, I'm well aware of the question of quoting lambdas). It is **backquoted**. And for a reason: the resulting function has no free variable, `object`. The **value** of `object` at the time function `constantly` is called is substituted for the variable itself. And yes, this means that the function is a *list*: a lambda form, and does not get compiled, for example. – Drew Sep 29 '15 at 22:49
0

You can usually avoid the use of constantly by writing the equivalent lambda-term inline. For example, in Common Lisp you could generate a list of 42s of the same length as a given list with

(mapcar (constantly 42) '(1 2 3))

In Emacs Lisp, you can do just the same with an explicit lambda-term:

(mapcar #'(lambda (_) 42) '(1 2 3))

Barely longer, and much clearer in my opinion.

jch
  • 5,680
  • 22
  • 39
  • 2
    Well, you can do the same in Common Lisp without any problems. And by the way you don't need to quote lambda form since `lambda` is already a macro in modern lisps that expands exactly to `#'(lambda (...) ...)`. Please don't show me how to do it manually, since it's trivial. This question about name of already existing function. If there is no such function, a comment about the fact will do. I've already sent a bug report asking to add `cl-constantly`. – Mark Karpov Sep 29 '15 at 18:07
  • 3
    Also you solution is not the same as `constantly`, since real `constantly` can take any number of arguments. – Mark Karpov Sep 29 '15 at 18:08