i'm new to common lisp and therefore my problem could be very easy, but i didn't find anything, maybe i used the wrong search terms.
i've got the following problem:
i have a function that does a special addition on an arbitrary number of parameters. the next step would be to apply that function to an arbitrary number of lists of same size, the result would be an list of that size.
it works if i call
(mapcar #'addition list1 list2 ...)
but if i have to define a function
(defun list-add (list &rest lists)
(mapcar #'addition list lists))
it won't work, because &rest lists now is a list of lists. the function addition needs to be called with all parameters as sequence, so a recursive call is not possible.
does anyone have a solution?
See APPLY.
Also note the value of CALL-ARGUMENTS-LIMIT.
The obvious solution would be:
(defun list-add (&rest lists)
(apply #'mapcar #'addition lists))
I'm not sure I got the question correctly but try
(defun list-add (list &rest lists)
(mapcar (lambda (l) (apply #'addition list l))
lists))
I'm not sure if this is necessarily better or worse than the answers already supplied, but here's what I came up with:
(defun list-add (first-required-list &rest other-lists)
(let ((all-lists (cons first-required-list
other-lists)))
(reduce (lambda (left-list right-list)
(mapcar #'addition left-list right-list))
all-lists)))
Related
I am trying to make a list of callback functions, which could look like this:
(("command1" . 'callback1)
("command2" . 'callback2)
etc)
I'd like it if I could could do something like:
(define-callback callback1 "command1" args
(whatever the function does))
Rather than
(defun callback1 (args)
(whatever the function does))
(add-to-list 'callback-info ("command1" . 'callback1))
Is there a convenient way of doing this, e.g., with macros?
This is a good example of a place where it's nice to use a two-layered approach, with an explicit function-based layer, and then a prettier macro layer on top of that.
Note the following assumes Common Lisp: it looks just possible from your question that you are asking about elisp, in which case something like this can be made to work but it's all much more painful.
First of all, we'll keep callbacks in an alist called *callbacks*:
(defvar *callbacks* '())
Here's a function which clears the alist of callbacks
(defun initialize-callbacks ()
(setf *callbacks* '())
(values)
Here is the function that installs a callback. It does this by searching the list to see if there is a callback with the given name, and if there is then replacing it, and otherwise installing a new one. Like all the functions in the functional layer lets us specify the test function which will let us know if two callback names are the same: by default this is #'eql which will work for symbols and numbers, but not for strings. Symbols are probably a better choice for the names of callbacks than strings, but we'll cope with that below.
(defun install-callback (name function &key (test #'eql))
(let ((found (assoc name *callbacks* :test test)))
(if found
(setf (cdr found) function)
(push (cons name function) *callbacks*)))
name)
Here is a function to find a callback, returning the function object, or nil if there is no callback with that name.
(defun find-callback (name &key (test #'eql))
(cdr (assoc name *callbacks* :test test)))
And a function to remove a named callback. This doesn't tell you if it did anything: perhaps it should.
(defun remove-callback (name &key (test #'eql))
(setf *callbacks* (delete name *callbacks* :key #'car :test test))
name)
Now comes the macro layer. The syntax of this is going to be (define-callback name arguments ...), so it looks a bit like a function definition.
There are three things to know about this macro.
It is a bit clever: because you can know at macro-expansion time what sort of thing the name of the callback is, you can decide then and there what test to use when installing the callback, and it does this. If the name is a symbol it also wraps a block named by the symbol around the body of the function definition, so it smells a bit more like a function defined by defun: in particular you can use return-from in the body. It does not do this if the name is not a symbol.
It is not quite clever enough: in particular it does not deal with docstrings in any useful way (it ought to pull them out of the block I think). I am not sure this matters.
The switch to decide the test uses expressions like '#'eql which reads as (quote (function eql)): that is to avoid wiring in functions into the expansion because functions are not externalisable objects in CL. However I am not sure I have got this right: I think what is there is safe but it may not be needed.
So, here it is
(defmacro define-callback (name arguments &body body)
`(install-callback ',name
,(if (symbolp name)
`(lambda ,arguments
(block ,name
,#body))
`(lambda ,arguments
,#body))
:test ,(typecase name
(string '#'string=)
(symbol '#'eql)
(number '#'=)
(t '#'equal))))
And finally here are two different callbacks being defined:
(define-callback "foo" (x)
(+ x 3))
(define-callback foo (x)
(return-from foo (+ x 1)))
These lists are called assoc lists in Lisp.
CL-USER 120 > (defvar *foo* '(("c1" . c1) ("c2" . c2)))
*FOO*
CL-USER 121 > (setf *foo* (acons "c0" `c1 *foo*))
(("c0" . C1) ("c1" . C1) ("c2" . C2))
CL-USER 122 > (assoc "c1" *foo* :test #'equal)
("c1" . C1)
You can write macros for that, but why? Macros are advanced Lisp and you might want to get the basics right, first.
Some issues with you example you might want to check out:
what are assoc lists?
what are useful key types in assoc lists?
why you don't need to quote symbols in data lists
variables are not quoted
data lists need to be quoted
You can just as easy create such lists for callbacks without macros. We can imagine a function create-callback, which would be used like this:
(create-callback 'callback1 "command1"
(lambda (arg)
(whatever the function does)))
Now, why would you use a macro instead of a plain function?
In the end, assisted by the responders above, I got it down to something like:
(defmacro mk-make-command (name &rest body)
(let ((func-sym (intern (format "mk-cmd-%s" name))))
(mk-register-command name func-sym)
`(defun ,func-sym (args &rest rest)
(progn
,#body))))
I'm learning LISP and I am trying to write a function that adds 1 to each element inside my list. I first test for if the first element is a number or not then add 1 to the first element in the list. I then recursively call the function on the rest of the list but I get an error. Any help? Here's the function:
(defun add-1-all (L)
(cond (not (numberp (first L)) nil)
(t (+1 (first L)) (add-1-all (rest L)))))
Here are more approaches:
When dealing with lists (see Joshua's comment), use ENDP, FIRST and REST, which are preferred over NULL, CAR and CDR. They convey the intent more clearly and in the case of ENDP, check that the argument is a proper-list. Imagine you pass a dotted-list built with (cons 'a 'b), what should happen? ENDP detects that the list is not proper and signals an error.
(defun add-1-all (list)
(unless (endp list)
(cons (1+ (first list))
(add-1-all (rest list)))))
I used UNLESS for its NIL value, which some people might not like. You may want to explicitely return NIL when reaching the end of your list. In that case, stick with COND or just use IF.
Loop.
(defun add-1-all (list)
(loop for e in list collect (1+ e)))
Make it work on arrays too, not just lists.
(defun add-1-all (sequence)
(map (type-of sequence) #'1+ sequence))
The easiest way to accomplish your goal would be to use map. Map applies a function to each element of a sequence. That way one does not have to take care of details like iterating through the sequence. In the code below I use mapcar which works only on lists.
(defun add-1 (list)
(mapcar #'1+ list))
To find out about other mapping functions that CL provides run (apropos "map") and use (describe ) to find out more. Or better yet use the clhs search engine or the extended CL documentation search engine
The solution you provided is attempting to solve the problem through recursion. The general idea is to traverse the list using first/rest while building a new one with the elements incremented by one. When the list reaches the end (You can use the functions null or endp to test that the end of the list has been reached) the new list should be returned. One of the problems with your solution is that it lacks an accumulator. Also your base-case (the condition that signals to stop the recursion) is wrong.
A couple of other pointers. Use an editor that formats your code as it is difficult to read. Also CL is not a Lisp-1 so you can use list as a variable name and it won't collide with the function list. They have separate namespaces. It is also helpful to post the error message and the explain what/how your solution is trying to do. You may also find this textbook useful for learning Lisp
You could write (+ 1 (first L)) or (1+ (first L)) but you didn't write that.
Also, you should use cons to tack the result on the first element to the result of the rest of them.
Also, did you really want to drop off all the elements after the first non-number? Or did you want to assume all elements were numbers, in which case you should learn about map or mapcar, which allows you to solve the problem in 15 characters.
First of all your code is wrong if you compile it you get several errors and warnings, is important a good lisp syntax and also knowing what you are writing. If you are learning lisp I reccomend you to get a confortable environment for that like slime and quicklisp
; SLIME 2015-06-01; compiling (DEFUN ADD-1-ALL ...)
; file: /tmp/file451NPJ
; in: DEFUN ADD-1-ALL
; (1 (FIRST L))
;
; caught ERROR:
; illegal function call
; (REST L)
; --> CDR
; ==>
; L
;
; note: deleting unreachable code
; (COND (NOT (NUMBERP (FIRST L)) NIL) (T (1 (FIRST L)) (ADD-1-ALL (REST L))))
; ==>
; (IF NOT
; (PROGN (NUMBERP (FIRST L)) NIL)
; (COND (T (1 (FIRST L)) (ADD-1-ALL (REST L)))))
;
; caught WARNING:
; undefined variable: NOT
;
; compilation unit finished
; Undefined variable:
; NOT
; caught 1 ERROR condition
; caught 1 WARNING condition
; printed 1 note
Then it is a good idea to use recursion for doing this task, for recursions is important to know when to stop and the base case of your algorithm
In you case you can also use if for this two path the function will be this:
(defun add-1-all (list)
(cond
((null list) nil)
(t (cons (1+ (car list))(add-1-all (cdr list))))))
I recommend you to try doing this using a tail recursive function for better perfomance and a great learning.
Also with lisp you can use more functional style, when time comes you will learn this, like using higher order functions in this case your function is as follows:
;; functional programming higher order functions
(defun add-1-all-ho (list)
(mapcar #'1+ list))
I am trying to figure out how to find duplicate atom in possibly nested lists. I have been trying to figure this out all day. If you could please give me the logic, that would be great because I really want to learn.
basically
(findDup '(a b b)) would return t
(findDup '(a c ((d (f a)) s))) would also return t
The easiest and most efficient way would be the following (pseudocode):
Create a data structure (such as Common Lisp's hash table) to remembering which atoms were seen
Create a recursive sub-function that does the actual traversing - walking the nested lists and adding all new atoms to the data structure, and if one is already there, returning true
If the list is sorted or can be sorted, this is a simple solution:
(defun find-duplicates (lst)
(let ((dup-list nil))
(sort lst)
(mapcon (lambda (l) (when (eq (car l) (cadr l)) (push (car l) dup-list))) lst)
dup-list ))
This should take care of the first case:
(defun find-duplicates (lst)
(let ((h (make-hash-table))
(dupes))
(mapcar #'(lambda (x)
(if (gethash x h)
(push x dupes)
(setf (gethash x h) t)))
lst)
dupes))
If the list is empty/without an atomic car however deeply you go (e.g. (car (car (car ...))) recursively), then the answer is false.
You want to find the first atom of the list, and see if that atom occurs anywhere else in the list. You can do that with a function like member-of?—something similar is discussed in The Little Schemer, but basically you just test all the atoms in the list, and recur on lists, against that atom.
Then if that atom is in the list, you can return true.
Else, you'll try again (recur on) with the cdr of the list.
I'd start with a wrapper function that creates a hash table and passes the hash table and the list to a second function (alternatively, use a &optional argument, if you're using Common Lisp).
Then, the following pseudo-code should be enough:
If we're looking at an empty list, there are no duplicates
If the head is a list, we can return the logical OR of "inspect the head" and "inspect the tail"
If the head is an atom, it's a duplicate if it's already in the hash table. If not, add it to the hash table and inspect the tail for duplicates.
I am working on a genetic programming hobby project.
I have a function/macro setup that, when evaluated in a setq/setf form, will generate a list that will look something like this.
(setq trees (make-trees 2))
==> (+ x (abs x))
Then it will get bound out to a lambda function #<FUNCTION :LAMBDA (X) ... > via strategic use of functions/macros
However, I want to get a bit more effective with this than manually assigning to variables, so I wrote something like this:
(setq sample
(let* ((trees (make-trees 2))
(tree-bindings (bind-trees trees))
(evaluated-trees (eval-fitness tree-bindings))))
(list (trees tree-bindings evaluated-trees)))
However, I get EVAL: trees has no value when I place this in a let form. My suspicion is that the macro expansions don't get fully performed in a LET as compared to a SETF, but that doesn't make sense to me.
What is the cause of this issue?
--- edit: yanked my code and put the whole file in a pastebin ---
Supposing that I decide that a setq isn't going to do it for me and I write a simple function to do it:
(defun generate-sample ()
(let ((twiggs (make-trees 2)))
(let ((tree-bindings (bind-trees twiggs)))
(let ((evaluated-trees (eval-fitness tree-bindings)))
(list twiggs tree-bindings evaluated-trees)))))
This yields an explosion of ...help file error messages (??!?)... and "eval: variable twiggs has no value", which stems from the bind-trees definition on SLIME inspection.
I am reasonably sure that I've completely hosed my macros. http://pastebin.org/673619
(Setq make-trees 2) sets the value of the variable make-trees to 2, then returns 2.
I do not see a reason for a macro in what you describe. Is it true that your make-trees creates a single random tree, which can be interpreted as a program? Just define this as a function with defun. I am thinking of something like this:
(defun make-tree (node-number)
(if (= node-number 1)
(make-leaf)
(cons (get-random-operator)
(mapcar #'make-tree
(random-partition (- node-number 1))))))
Let and setq do totally different things. Setq assigns a value to an existing variable, while let creates a new lexical scope with a number of lexical bindings.
I think that you should present more of your code; currently, your question does not make a lot of sense.
Update:
I will fix your snippet's indentation to make things clearer:
(setq sample
(let* ((trees (make-trees 2))
(tree-bindings (bind-trees trees))
(evaluated-trees (eval-fitness tree-bindings))))
(list (trees tree-bindings evaluated-trees)))
Now, as written before, let* establishes lexical bindings. These
are only in scope within its body:
(setq sample
(let* ((trees (make-trees 2))
(tree-bindings (bind-trees trees))
(evaluated-trees (eval-fitness tree-bindings)))
;; here trees, tree-bindings, and evaluated-trees are bound
) ; end of let* body
;; here trees, tree-bindings, and evaluated trees are not in scope anymore
(list (trees tree-bindings evaluated-trees)))
That last line is spurious, too. If those names were bound, it would
return a list of one element, which would be the result of evaluating
the function trees with tree-bindings and evaluated-trees as
arguments.
You might get what you want like this:
(setq sample
(let* ((trees (make-trees 2))
(tree-bindings (bind-trees trees))
(evaluated-trees (eval-fitness tree-bindings)))
(list trees tree-bindings evaluated-trees)))
Another update:
The purpose of macros is to eliminate repeated code when that elimination is not possible with functions. One frequent application is when dealing with places, and you also need them to define new control constructs. As long as you do not see that something cannot work as a function, do not use a macro for it.
Here is some code that might help you:
(defun make-tree-lambda (depth)
(list 'lambda '(x)
(new-tree depth)))
(defun make-tree-function (lambda-tree)
(eval lambda-tree))
(defun eval-fitness (lambda-form-list input-output-list)
"Determines how well the lambda forms approach the wanted function
by comparing their output with the wanted output in the supplied test
cases. Returns a list of mean quadratic error sums."
(mapcar (lambda (lambda-form)
(let* ((actual-results (mapcar (make-tree-function lambda-form)
(mapcar #'first input-output-list)))
(differences (mapcar #'-
actual-results
(mapcar #'second input-output-list)))
(squared-differences (mapcar #'square
differences)))
(/ (reduce #'+ squared-differences)
(length squared-differences))))
lambda-form-list))
(defun tree-fitness (tree-list input-output-list)
"Creates a list of lists, each inner list is (tree fitness). Input
is a list of trees, and a list of test cases."
(mapcar (lambda (tree fitness)
(list tree fitness))
tree-list
(eval-fitness (mapcar #'make-tree-lambda tree-list)
input-output-list)))
...just like packages do.
I use Emacs (maybe, it can offer some kind of solution).
For example (defun the-very-very-long-but-good-name () ...) is not to useful later in code. But the name like Fn-15 or the first letters abbreviation is not useful too.
Is it possible either to have an alias like for packages or to access the documentation string while trying to recall the function's name?
In other words, is it possible for functions to mix somehow self-documenting and short names?
You want defalias. (defalias 'newname 'oldname) will preserve documentation and even show "newname is an alias for `oldname'" when its documentation is requested.
You could use setf to assign the function to the function cell of another, for example:
(defmacro alias (new-name prev-name)
`(setf (symbol-function ,new-name) (symbol-function ,prev-name)))
from 《On Lisp》?Here is the code:
(defmacro alias (new-name prev-name)
`(defmacro ,new-name (&rest args)
`(,',prev-name ,#args)))
; use: (alias df defun)
(defun group (source n)
(if (zerop n) (error "zero length"))
(labels ((rec (source acc)
(let ((rest (nthcdr n source)))
(if (consp rest)
(rec rest (cons (subseq source 0 n) acc))
(nreverse (cons source acc))))))
(if source (rec source nil) nil)))
(defmacro aliasx (&rest names)
`(alias
,#(mapcar #'(lambda (pair)
`(alias ,#pair))
(group names 2))))
; use: (aliasx df1 defun
; df2 defun
; df3 defun)
If it's all the typing which makes continual use of long names undesirable, then yes, emacs can help. Check out abbrev-mode. Also well thought-of in this context is hippie-expand.
If it's a question of readability, that's harder.
If your problem is that you can't remember a very long function name, but you remember PART of the name, that's what "apropos" is for. In my Emacs, I have "C-h a" bound to "hyper-apropos". You enter a substring of the symbol you're looking for, and it lists all the matches.
I dont know Emacs, but wouldn't (define shortname longnamefunctionblahblah) work?
You could simply have a function that just calls another function.
you can use (defmacro ...) to alias a function