Variable Not A Number Error in Lisp (Which is not true) - recursion

I have a code which takes a list and returns all possible permutations by the parameter result.
But when I compile I have an error which says *** - =: (1+ INDEX) is not a number.
Is this message true or I messed up the code generally?
I am new to lisp I can looking for a fix and also open to suggestions from fucntional programmers.
;; Creates permutatiions of a given list and returns it via parameter
(defun create-permuations (source)
(setf result (list))
(create-permuations-helper source 0 '() result)
result)
(defmacro create-permuations-helper (source index cur result)
(if (= (list-length cur) index)
(cons cur result)
(loop for i from 0 to (list-length cur) do
(create-permuations-helper source (1+ index)
(append cur (list (nth i source))) result))))

99% of times when a compiler reports an error you can trust it to be true. Here Index is the list (1+ index), literally the 1+ symbol followed by the index symbol. This is so because you are using a macro, and macros operate on code.
In your macro, you do not return a form to be evaluated, you execute code during macro-expansion that depends on itself. That alone is an undefined behaviour. For example:
(defmacro a (x)
(if (plusp x)
(a (- x 1))
nil))
In the body of a, you want to expand code using a recursive call to itself. But the macro is not yet fully known and cannot be until the whole macro is defined.
Maybe the particular lisp implementation binds a to the macro function in body of the macro, which is a strange thing to do, or you evaluated the definition twice. The first time the compiler assumes a is an unknown function, then binds a to a macro, and the second time it tries to expand the macro.
Anyway macro are not supposed to be recursive.
In the example, since the macro does not evaluate its argument, the nested call to the macro is given the literal expression (- x 1), and not its actual value, which cannot be known anyway since x is unknown. You are crossing a level of abstraction here by trying to evaluate things at macroexpansion time.
But, macros can expand into code that refers to themselves.
(defmacro a (x)
(if (plusp x)
`(b (a ,(- x 1)))
nil))
Now, (a 2) expands into (b (a 1)), which itself macroexpands into (b (b (a 0))), and finally reaches a fixpoint which is (b (b nil)).
The difference is that the macro produces a piece of code and returns, which the compiler macroexpands again, whereas in the first example, the macro must already be expanded in the body of its own definition.
Possible implementation
One way to solve your problem is to define a local function that has access to a variable defined in your main function. Then, the local function can set it, and you do not need to pass a variable by reference (which is not possible to do):
(defun permut (list)
(let (result)
(labels ((recurse (stack list)
(if list
(dolist (x list)
(recurse (cons x stack)
(remove x list :count 1)))
(push stack result))))
(recurse nil list))
result))
Alternatively, you can split the process in two; first, define permut-helper, which is a higher-order function that takes a callback function; it generates permutations and calls the callback for each one:
(defun permut-helper (stack list callback)
(if list
(dolist (x list)
(permut-helper (cons x stack)
(remove x list :count 1)
callback))
(funcall callback stack)))
You call it with a function that pushes results into a list of permutations:
(defun permut (list)
(let (result)
(flet ((add-result (permutation)
(push permutation result)))
(permut-helper nil list #'add-result))
result))

Related

Creating a function which takes any number of functions as arguments

I'm having trouble figuring out how to go about creating a function that can take a series of the same function as arguments with the last argument as an operand. For example:
(func sqrt sqrt sqrt 390625)
The call above should return 5 as (sqrt 390625) > (sqrt 625) > (sqrt 25) > 5
I'm having trouble figuring out the exact way I should write this as any way I have tried has given me errors or achieved an infinite loop.
This the code is have so far:
(define func
(lambda L
(cond ( (equal? (length L) 2) ((car L) (cadr L)) ) ;; If the list consists of only 2 elements, carry out the function (element 1) onto the operand (element 2)
( #t (apply (car L) (func (cdr L))) ) ;; otherwise, apply the function (1st element) onto the rest of the list
)
)
)
The first condition works, for example returning 5 if i call (func sqrt 25), however the recursive call is throwing errors.
I would appreciate any help with this.
The OP doesn't provide a definition for chain, so that part is unclear, but I think that a fundamental problem here is that there is no recursive call to func; further, apply isn't used in the right position.
Instead of using (equal (length L) 2) as a base case, it might be nicer to make recursive calls as long as the first element in the input is a procedure, or otherwise just return the element:
#lang racket
(define multi-call
(lambda args
(let ((arg (car args)))
(if (procedure? arg)
(arg (apply multi-call (cdr args)))
arg))))
Here, when arg is a procedure, then it is applied to the result of calling multi-call recursively on the remaining arguments. Note that multi-call takes an arbitrary number of arguments, wrapping them in the list args. The reduction step provides (cdr args), which is a list of the remaining arguments. This means that apply should be used to call multi-call on those remaining arguments because multi-call expects an arbitrary number of arguments, not a list of arguments.
multi-call.rkt> (multi-call sqrt sqrt sqrt 390625)
5

Check if lisp object ends in NIL

I am trying to write an fx in lisp to tell if an object ends in nil.
(setq isList (lambda (listOfValues)
(if (null listOfValues) t)
( funcall isList (cdr listOfValues) )
)
)
However, I am having trouble checking if its nil in all cases. In particular, cdr would fail at last elt if it is not a list. How can I resolve this?
Before we get closer to answer your actual question, a few things. First, use defun to define functions, not "set a variable to a lambda", it will make you happier down the line. Second, Common Lisp style would vale been one of values, list-of-values, or just list (that would indicate we knew it was a list, so I would probably just have gone with values here), not "listOfValues" (case is typically smashed, and neither "listofvalues" nor "LISTOFVALUES" are easy to read).
So, back to the code. A list is composed of cons cells, of either atoms or other cons cells. We have two test functions, either consp or atom that would be useful in this case. We know that if we're looking at a cons, we need to recurse on its cdr, otherwise we're at the last element and can just check if we're looking at nil.
(defun is-proper-list (values)
(if (consp values)
(is-proper-list (cdr values))
(null values))) ;; We could do this test as (eql nil) as well
It can be done faster with
(defun listp (l)
(tailp nil l))
(tailp nil ...) tests, whether nil is the end of a given object after cdr-ing to the end.
tailp is a very special function. So don't use it without understanding it.
(tailp '(b c) '(a b c)) is e.g. NOT T, because '(b c) is not the same object like the ( ... b c). But in this case, because NIL is '() and is unique in Lisp, any nil is object-identical. Therefore one can use tailp here for this specific test, whether a given list ends with NIL.
listp is a lisp-convention conform name for this.
(predicate functions returning booleans ending with p for predicate.
Since no - used in the name, attach p without - otherwise attach -p).
(tailp (cdr '(a b c)) '(a b c)) ;; NIL
;; because the two lists are not object-identical
(setq l '(a b c))
(tailp (cddr l) l) ;; T ;; object-identical

Evaluating a List of Variables to a List of Their Values in Common Lisp

I am wondering how one can achieve the following. Suppose I have a list of variables that are bound by some let above. I would like to turn this list into a list of the values to which those variables are bound.
That is, suppose we have
(define make-plist-from-variables (variables)
(let ((keys variables)
(values (mapcar #'identity variables)))
(if (eq (length keys) (length values))
(make-plist keys values)
nil))))
What can I use in place of #'identity to unpack those values properly?
At the moment, the following call produces the following output.
CL-USER> (let ((a 2) (b 3)) (make-plist-from-variables '(a b)))
(A A B B)
I would like it to be (A 2 B 3)
It needs to be a macro because there is no way to fetch a variable's lexical value based on its symbol.
(defmacro make-plist-from-variables (&rest variables)
(loop :for binding :in variables
:collect `',binding :into result
:collect binding :into result
:finally (return `(list ,#result))))
(macroexpand-1 '(make-plist-from-variables a b))
; ==> (list 'a a 'b b)
(let ((a 2) (b 3))
(make-plist-from-variables a b))
; ==> (a 2 b 3)
EDIT
Implementation without loop using mapcan:
(defmacro make-plist-from-variables (&rest variables)
`(list ,#(mapcan (lambda (v) `(',v ,v)) variables))
Functions don't have access to the lexical environment of their callers.
More precisely, during evaluation you cannot access the values of lexical variables knowing only their symbols. Only macros have access to environment objects.
Special variables
You can use dynamic binding:
(defun foo ()
(declare (special a))
(symbol-value 'a))
(let ((a 3))
(declare (special a))
(foo))
=> 3
In your case, you would collect the symbol along its value, by using SYMBOL-vaLUE on all your symbols.
Related to your question is how to dynamically bind variables to values where the variable names and/or values are known at evaluation time; see special operator PROGV.
Macros
You could obtain e.g. an association list by writing the following code:
(acons 'a a (acons 'b b nil))
Depending on the use case behind your question, you may want to have a macro that expands into such code, that references the variables you want to evaluate.

avoiding side effects implementing OR macro function in lisp

I'm trying to implement the macro-function OR in Lisp
My attempt:
(defmacro or2 (test &rest args)
`(if ,test ,test (if (list ,#args) (or2 ,#args) nil)) )
However, if I test with something like this:
(or2 (print 1) 2 )
1
1
1
Whereas with the default OR:
(or (print 1) 2)
1
1
I understand that this is because of my two ,test at the beginning of my if clause, but I don't see how i could avoid it. How could I avoid applying twice the test effects ?
How would you solve the problem of side-effects if you had to code it by hand?
(or2 (print 1) 2)
Intermediate variable
Most probably, you would do this:
(let ((value (print 1)))
(if value value 2))
You need to define a local variable which holds the value of the first expression, so that later you can reference the variable instead of re-evaluating the same expression more than once.
But what if you already have a variable named value in the lexical context where you expand the code? What if, instead of 2, you were referencing that other value? This problem is named variable capture.
Gensym
In Common Lisp, you introduce a fresh symbol, that is guaranteed to not be already bound to anything, using GENSYM.
(let ((symbol (gensym)))
`(let ((,symbol ,test))
(if ,symbol ,symbol ...)))
Recursive expansion
(list ,#args)
The above is the same as writing directly ,args.
But you are confusing macroexpansion and execution times. If you inject args directly in the code, it will be evaluated (most likely, this is going to fail as a bad function call). What you want instead is to test if args is non-null during macroexpansion.
Besides, you should probably first test if your list of expression contains more than one element, in order to simplify the generated code.
Roughly speaking, you have to take into account the following cases:
(or2) is nil
(or2 exp) is the same as exp
(or2 exp &rest args) is the same as the following, where var is a fresh symbol:
`(let ((,var ,exp))
(if ,var ,var (or2 ,#args)))
Please make use of macroexpand-1:
(macroexpand-1 '(or2 (print 1) 2))
; ==> (if (print 1) (print 1) (if (list 2) (or2 2) nil)) ;
; ==> t
With macros you wish the order of evaluation to be expected and you wish expressions to only be evaluated once. Thus the expansion should have been something like this:
(let ((tmp (print 1)))
(if tmp
tmp
(or2 2)))
And tmp should be a symbol generated by gensym. Also when args is nil you should expand or2 to only test:
(defmacro or2 (test &rest args)
(if (endp args)
test
(let ((tmp (gensym "tmp")))
`(let ((,tmp ,test))
(if ,tmp
,tmp
(or2 ,#args))))))
you can make use of macros to simplify this:
(defmacro or2 (test &rest args)
(if (endp args)
test
(once-only (test)
`(if ,test
,test
(or2 ,#args)))))

Why are this list's contents retained between function calls? [duplicate]

Could someone explain to me what's going on in this very simple code snippet?
(defun test-a ()
(let ((x '(nil)))
(setcar x (cons 1 (car x)))
x))
Upon a calling (test-a) for the first time, I get the expected result: ((1)).
But to my surprise, calling it once more, I get ((1 1)), ((1 1 1)) and so on.
Why is this happening? Am I wrong to expect (test-a) to always return ((1))?
Also note that after re-evaluating the definition of test-a, the return result resets.
Also consider that this function works as I expect:
(defun test-b ()
(let ((x '(nil)))
(setq x (cons (cons 1 (car x))
(cdr x)))))
(test-b) always returns ((1)).
Why aren't test-a and test-b equivalent?
The Bad
test-a is self-modifying code. This is extremely dangerous. While the variable x disappears at the end of the let form, its initial value persists in the function object, and that is the value you are modifying. Remember that in Lisp a function is a first class object, which can be passed around (just like a number or a list), and, sometimes, modified. This is exactly what you are doing here: the initial value for x is a part of the function object and you are modifying it.
Let us actually see what is happening:
(symbol-function 'test-a)
=> (lambda nil (let ((x (quote (nil)))) (setcar x (cons 1 (car x))) x))
(test-a)
=> ((1))
(symbol-function 'test-a)
=> (lambda nil (let ((x (quote ((1))))) (setcar x (cons 1 (car x))) x))
(test-a)
=> ((1 1))
(symbol-function 'test-a)
=> (lambda nil (let ((x (quote ((1 1))))) (setcar x (cons 1 (car x))) x))
(test-a)
=> ((1 1 1))
(symbol-function 'test-a)
=> (lambda nil (let ((x (quote ((1 1 1))))) (setcar x (cons 1 (car x))) x))
The Good
test-b returns a fresh cons cell and thus is safe. The initial value of x is never modified. The difference between (setcar x ...) and (setq x ...) is that the former modifies the object already stored in the variable x while the latter stores a new object in x. The difference is similar to x.setField(42) vs. x = new MyObject(42) in C++.
The Bottom Line
In general, it is best to treat quoted data like '(1) as constants - do not modify them:
quote returns the argument, without evaluating it. (quote x) yields x.
Warning: quote does not construct its return value, but just returns
the value that was pre-constructed by the Lisp reader (see info node
Printed Representation). This means that (a . b) is not
identical to (cons 'a 'b): the former does not cons. Quoting should
be reserved for constants that will never be modified by side-effects,
unless you like self-modifying code. See the common pitfall in info
node Rearrangement for an example of unexpected results when
a quoted object is modified.
If you need to modify a list, create it with list or cons or copy-list instead of quote.
See more examples.
PS1. This has been duplicated on Emacs.
PS2. See also Why does this function return a different value every time? for an identical Common Lisp issue.
PS3. See also Issue CONSTANT-MODIFICATION.
I found the culprit is indeed 'quote. Here's its doc-string:
Return the argument, without evaluating it.
...
Warning: `quote' does not construct its return value, but just returns
the value that was pre-constructed by the Lisp reader
...
Quoting should be reserved for constants that will
never be modified by side-effects, unless you like self-modifying code.
I also rewrote for convenience
(setq test-a
(lambda () ((lambda (x) (setcar x (cons 1 (car x))) x) (quote (nil)))))
and then used
(funcall test-a)
to see how 'test-a was changing.
It looks like the '(nil) in your (let) is only evaluated once. When you (setcar), each call is modifying the same list in-place. You can make (test-a) work if you replace the '(nil) with (list (list)), although I presume there's a more elegant way to do it.
(test-b) constructs a totally new list from cons cells each time, which is why it works differently.

Resources