Filter function in Elisp - emacs

Is there equivalent of higher-order function filter in Emacs Lisp? Like function from python or Javascript.
(filter-equivalent (lambda (n) (= (% n 2) 0)) '(1 2 3 4 5 6 7 8))
==> (2 4 6 8)

It's cl-remove-if-not. A bit of a mouthful, but it works.
To elaborate a bit, you need
(require 'cl-lib)
to get this function. There's an alias for it, called remove-if-not, but
I prefer not to use it, since it may look like I'm using remove-if-not from cl.
It's a good practice to include the prefix, not doing using namespace std in C++,
but saying std::cout each time.

The third-party dash.el library provides a -filter function as an alternative to cl-remove-if-not.
(-filter 'evenp '(1 2 3 4 5 6 7 8))
;; => (2 4 6 8)

Related

Is there a way to get information about a module at read time?

I've since this summer played around with making a toy language in Racket. Every form has a fixed arity and by default applies so parentheses are not needed. eg. + has arity 2 so + 3 + 4 5 is (+ 3 (+ 4 5)) and + + 3 4 5 is (+ (+ 3 4) 5).
To do this I'm storing in the main module the symbols and their arity. The reader doesn't care if it's a special form or procedure, but is there a better way to do this using features from racket? Thus I can import a module metadata and query that instead during parsing?
Here is one way to go from symbol to arity.
#lang racket
(define base-ns (make-base-namespace))
(define (symbol->arity s)
(parameterize ([current-namespace base-ns])
(procedure-arity (namespace-variable-value s))))
(symbol->arity 'cons)

Unlist a list - common lisp [duplicate]

This question already has answers here:
How do I splice into a list outside of a macro in Common Lisp?
(2 answers)
Closed 7 years ago.
I have a function that returns something like this:
'(1 4 2 8)
and I want to apply the following type of functions to it:
(name &rest)
for example:
(max '(1 4 2 8))
produces an error, but:
(max 1 4 2 8)
does not.
so I have to "unlist" that list. How may I go about doing that?
The form apply is the traditional way:
(apply 'max '(1 2 3 4))
; => 4

push does not work as I would expect it - why?

I am experiencing a behavior of the push function that I don't get. Maybe someone could explain to me why Lisp behaves this way.
Supposed I define a list as a global variable, and then try to push a new value to it using the following code:
(defparameter *primes* '(3 5 7 11))
(push 2 *primes*)
Then *primes* is now (2 3 5 7 11). So far, so good.
Now I try to do the same thing, but without the *primes* variable, i.e.:
(push 2 '(3 5 7 11))
The result is an error message:
EVAL: 3 is not a function name; try using a symbol instead
Now I have two questions:
Why does this not work? I would expect that push returns the list (2 3 5 7 11), why does this not happen? Where am I wrong?
Apart from that, I don't get the error message. What is Lisp trying to tell me with 3 is not a function name? Of course, 3 is not a function name, but I don't try to call a function named 3 anywhere, do I?
Any help is appreciated :-)
If you read the CL Hyperspec for PUSH, you will read that push expects a place.
A place is something like a variable, a structure slot, a class slot, an array access, or similar. Since Lisp uses linked cons cells for lists, it does not make sense to push something in front of a cons cell, without a reference for that.
So above is simple: we can't push to a direct list.
Why this error message?
This gets a bit complicated...
(push 2 '(3 5 7 11))
Is actually:
(push 2 (quote (3 5 7 11))
A function can be a place, it then needs a corresponding setter function. Here the setter is thought to be (setf quote) - that's right, Common Lisp can sometimes have lists as function names, not only symbols.
If we look at the macroexpansion of above:
? (pprint (macroexpand '(push 2 (quote (3 5 7 11)))))
(LET* ((#:G328 2) (#:G327 (3 5 7 11)) (#:G326 (CONS #:G328 '#:G327)))
#:G327
#:G326
(FUNCALL #'(SETF QUOTE) #:G326 #:G327))
You can see that it tries to call the setter. But it also thinks that (3 5 7 11) is a Lisp form.
I give you an example, where it actually works, but we don't use quote, but a real accessor function:
CL-USER 40 > (let ((v (vector (list (list 'a 'b 'c) (list 'd 'e 'f))
(list (list 1 2 3) (list 4 5 6)))))
(print v)
(push 42 (first (aref v 1)))
(print v)
(values))
#(((A B C) (D E F)) ((1 2 3) (4 5 6)))
#(((A B C) (D E F)) ((42 1 2 3) (4 5 6)))
In above first is the getter and CL knows the corresponding setter. The form (aref v 1) is the call and returns the index 1 element of the vector. We are then pushing to the first list of the element.
Your call has a similar structure and (3 5 7 11) is at a similar position as (aref v 1). The Lisp system says that in (3 4 7 11) then number 3 is not a valid function. Which is correct. But the real error was about the push operation. Since the macro could not detect the error, the error gets later detected in the macro expanded code.
I have found only the emacs lisp manual push, but I guess it behaves similar for Common Lisp
— Macro: push element listname
This macro creates a new list whose car is element and whose cdr is the list specified by listname, and saves that list in listname.
So it seems push is modifying its argument listname, which isn't possible with a literal list. To do what you have in mind, one would use cons instead.
To the second part 3 is not a function name, I would say push, or some function inside it, tries to evaluate the literal list. Evaluating (3 5 7 11) means, call the function 3 with arguments 5 7 11. Hence the error message.
Again from emacs, Ctrl-h f push
push is a Lisp macro in `cl.el'.
(push X PLACE)
Insert X at the head of the list stored in PLACE.
Analogous to (setf PLACE (cons X PLACE)), though more careful about
evaluating each argument only once and in the right order. PLACE may
be a symbol, or any generalized variable allowed by `setf'.
setf in turn allows place to be a
symbolic references such as (car x) or (aref x i)
which explains, why push evaluates the second argument.
I think you need CONS in second case:
(cons 2 '(3 5 7 11)) => (2 3 5 7 11)

Using lists with Common LISP

I'm just starting out with LISP, as in, just opened the book, I'm two pages into it. I'm trying to understand what is and what is not an acceptable fn call. Every time I try to execute
(1 2 3 4)
I get an illegal fn call error
same goes for
(cdr (1 2 3 4))
(first (1 2 3 4))
(a b c d)
Are CL programs unable to return lists? How would I go about using these functions or printing a list? I'm using the SLIME implementation if it matters. LISP is very different than anything I've worked with before and I want to be sure I'm getting it conceptually.
You need to quote lists if you are using them as constants. Otherwise, the system will try to call the function 1 on the arguments 2 3 4, which will not work (note that function calls have the same syntax as lists). Your examples should be:
'(1 2 3 4)
(cdr '(1 2 3 4))
(first '(1 2 3 4))
'(a b c d)
Hooo boy.
Look up Practical Common Lisp by Seibel. He's such a nice guy, he put it online for free reading. It's very useful.
Part of the definition of Lisp is this rule:
When a list is seen: Using the first element of the list, apply it to the rest of the list.
But wait: How do you actually enter lists then? There are two functions to do this: QUOTE and LIST.
As an example, let's print a list to the screen on standard out:
(format *standard-output* "~a" '(1 2 3 4))
For format, *standard-output* is aliased to t (well, at least in SBCL!), so usually we see (format t ....

What is WITH-STANDARD-IO-SYNTAX macro for?

The Practical Common Lisp page 25, explains the WITH-STANDARD-IO-SYNTAX as follows. "It ensures that certain variables that affect the behavior of PRINT are set to their standard values".
The usage is as follows.
(with-open-file (...)
(with-standard-io-syntax
(print ...
Should (print) be used in this macro? If not, what would happen?
Various dynamic variables affect the output produced by print. with-standard-io-syntax ensures those variables are set to the default values.
For example:
(let ((list '(1 2 3 4 5 6 7 8 9 10))
(*print-length* 5))
(print list)
(with-standard-io-syntax
(print list)))
Prints:
(1 2 3 4 5 ...)
(1 2 3 4 5 6 7 8 9 10)
It's particularly important if you're printing things with the intention of being able to read them later (like with prin1).