Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I apply "or" to a list in elisp

Tags:

In elisp I can evaluate or as a function just like +.

(or nil 0 nil) ==> 0  (+ 1 0 1) ==> 2 

I can use apply to apply + to a list

(apply '+ '(1 0 1)) ==> 2 

So, I would think or would work the same way, but it doesn't.

(apply 'or '(nil 0 nil)) ==> error: (invalid-function or) 

I imagine this comes from some internal magic used to implement the short-circuit evaluation. How can I use apply to execute the or operation over a list?


P.S. my desired application is to find out whether any elements on the command line match a particular pattern, so the important part of what I am writing is:

(apply 'or (mapcar (lambda (x) (string-match-p "pattern" x)) command-line-args)) 

But it doesn't work

like image 246
Eponymous Avatar asked May 05 '11 19:05

Eponymous


People also ask

How do I make a list on Lisp?

The list function is rather used for creating lists in LISP. The list function can take any number of arguments and as it is a function, it evaluates its arguments. The first and rest functions give the first element and the rest part of a list.

What is Mapcar Lisp?

mapcar is a function that calls its first argument with each element of its second argument, in turn. The second argument must be a sequence. The ' map ' part of the name comes from the mathematical phrase, “mapping over a domain”, meaning to apply a function to each of the elements in a domain.

What does car do in Lisp?

The car and cdr functions are used for splitting lists and are considered fundamental to Lisp. Since they cannot split or gain access to the parts of an array, an array is considered an atom. Conversely, the other fundamental function, cons , can put together or construct a list, but not an array.


1 Answers

The problem is that or is a macro (which is the "internal magic" in question), and you're right that that's done so it can do short-circuiting. If or was a function, then calling it would need to follow the usual rules for evaluating a function call: all the arguments would need to get evaluated before the call is made.

See also this question -- it's about Scheme but it's the exact same issue.

As for a solution, you should probably use some, as in:

(some (lambda (x) (string-match-p "pattern" x)) command-line-args) 

Note: this uses common lisp that is not included in emacs by default. Just use (require 'cl)

like image 171
Eli Barzilay Avatar answered Sep 20 '22 01:09

Eli Barzilay