Inserting mutable pairs into a mutable list - lisp

How can I push a mutable pair onto a stack such that i'm only creating one stack. I have some code that works but creates lists within lists within lists.... Here is what I believe should work but throws an error.
(define func (arg1 arg2 arg3) // Where arg3 is an empty list
(mappend (mcons arg1 arg2) arg3))
The above code complains and says: "mcar: expects argument of type ; given ...
Can anyone show me how I can get a result that looks like so,: (list (arg1 arg2)
(arg# arg#)
...)

(mcons (mcons arg1 arg2) arg3)
or (your question is not very clear)
(cons (list 'a 'b) '())
Also, the syntax in your question doesn't make any sense. It should be something like
(define func (lambda (arg1 arg2 arg3)
...body...))

I think the function you want is:
(define (f a b c)
(mlist (mlist a b) c))
This produces the following result:
> (f 3 4 (mlist 4 5))
{{3 4} {4 5}}

Related

Change variable defined in let function

Given the following let function:
(let ((foo (list a b c d)))
foo)
How can i modify the list foo?
(let ((foo (list a b c d)))
;some code
foo)
so the returned foo looks like eks: '(some new list) or (a b modified d)
i tried (set) but foo will still return as the original list.
You can use setf to modify a specific element in a list.
(let ((foo (list 'a 'b 'c 'd)))
(setf (third foo) 'modified)
foo)
This will return (a b modified d).
Or if you want to replace the whole variable, you can assign directly to it with setq:
(let ((foo (list 'a 'b 'c 'd)))
(setq foo (list 'some 'new 'list))
foo)
You can't use set with lexical variables, only special variables.

'('(LIST) 'NIL 'NIL) should be a lambda expression in (hanoi('('(list)'()'())))

I'm trying to implement the Towers of Hanoi.I'm not printing out anything between my recursive calls yet, but I keep getting an error saying
'('(LIST) 'NIL 'NIL) should be a lambda expression
I've read that the reason this happens is because of a problem with the parenthesis, however I cannot seem to find what my problem is. I think it's happening in the pass-list function when I am trying to call the hanoi function. My code:
(defun pass-list(list)
(hanoi('('(list)'()'())))
)
(defun hanoi ('('(1) '(2) '(3)))
(hanoi '('(cdr 1) '(cons(car 1) 2) '(3)))
(hanoi '('(cons(car 3)1) '(2)'(cdr 3)))
)
This code has many syntax problems; there are erroneous quotes all over the place, and it looks like you're trying to use numbers as variables, which will not work. The source of the particular error message that you mentioned comes from
(hanoi('('(list)'()'())))
First, understand that the quotes in 'x and '(a b c) are shorthand for the forms (quote x) and (quote (a b c)), and that (quote anything) is the syntax for getting anything, without anything being evaluated. So '(1 2 3) gives you the list (1 2 3), and '1 gives you 1. quote is just a symbol though, and can be present in other lists, so '('(list)'()'()) is the same as (quote ((quote (list)) (quote ()) (quote ()))) which evaluates to the list ((quote (list)) (quote ()) (quote ())). Since () can also be written nil (or NIL), this last is the same as ('(list) 'NIL 'NIL). In Common Lisp, function calls look like
(function arg1 arg2 ...)
where each argi is a form, and function is either a symbol (e.g., list, hanoi, car) or a list, in which case it must be a lambda expression, e.g., (lambda (x) (+ x x)). So, in your line
(hanoi('('(list)'()'())))
we have a function call. function is hanoi, and arg1 is ('('(list)'()'())). But how will this arg1 be evaluated? Well, it's a list, which means it's a function application. What's the function part? It's
'('(list)'()'())
which is the same as
'('(list 'NIL 'NIL))
But as I just said, the only kind of list that can be function is a lambda expression. This clearly isn't a lambda expression, so you get the error that you're seeing.
I can't be sure, but it looks like you were aiming for something like the following. The line marked with ** is sort of problematic, because you're calling hanoi with some arguments, and when it returns (if it ever returns; it seems to me like you'd recurse forever in this case), you don't do anything with the result. It's ignored, and then you go onto the third line.
(defun pass-list(list)
(hanoi (list list) '() '()))
(defun hanoi (a b c)
(hanoi (rest a) (cons (first a) b) c) ; **
(hanoi (cons (first c) a) b (rest c)))
If hanoi is supposed to take a single list as an argument, and that list is supposed to contain three lists (I'm not sure why you'd do it that way instead of having hanoi take just three arguments, but that's a different question, I suppose), it's easy enough to modify; just take an argument abc and extract the first, second, and third lists from it, and pass a single list to hanoi on the recursive call:
(defun hanoi (abc)
(let ((a (first abc))
(b (second abc))
(c (third abc)))
(hanoi (list (rest a) (cons (first a) b) c))
(hanoi (list (cons (first c) a) b (rest c)))))
I'd actually probably use destructuring-bind here to simplify getting a, b, and c out of abc:
(defun hanoi (abc)
(destructuring-bind (a b c) abc
(hanoi (list (rest a) (cons (first a) b) c))
(hanoi (list (cons (first c) a) b (rest c)))))

Apply and keyword arguments in lisp

I can use keyword parameters in LISP
(member 'a '(a b c) :test #'eq)
However, when I tried to use apply to invoke member method
(apply #'member 'a '(a b c) :test #'eq)
I have error message as follows:
MEMBER: keyword arguments in (:TEST) should occur pairwise
[Condition of type SYSTEM::SIMPLE-PROGRAM-ERROR]
The solution was
(apply #'member 'a '(a b c) '(:test eq))
Whereas without the keyword arguments
(apply #'member 'a '((a b c)))
What's the logic behind this? Why '(:test #'eq) raises an error?
ADDED
This is the reason why I asked this question.
I have code from ANSI Common Lispbook page 103.
(defun our-adjoin (obj lst &rest args)
(if (apply #'member obj lst args)
lst
(cons obj lst)))
When I tried (our-adjoin 'a '(a b c)) it returns the result (A B C), but the our-adjoin can't be translated as (apply #'member 'a '(a b c)), because it will raise an error (as is asked in Apply and keyword arguments in lisp).
What I can think about is that the value from &rest args is given to make something like (apply #member 'a '(a b c) '()) not to raise an error.
apply expects its final argument to be a list. That is,
(apply #'foo (list 1 2 3)) == (foo 1 2 3)
(apply #'member 'a '(a b c) :test #'eq) == ??? ; is an error - #'eq isn't a list
I don't know what apply is making of #'eq (a function) where a list is expected, but that's the problem.
You might be looking for funcall instead of apply:
(funcall #'foo 1 2 3) == (foo 1 2 3)
(funcall #'member 'a '(a b c) :test #'eq) == (member 'a '(a b c) :test #'eq)
Edit: (apply #'member 'a '(a b c))
This is the same as
(member 'a 'a 'b 'c)
which of course is nonsense. Think of apply as "expanding" its last argument.
Edit 2: The our-adjoin code
(our-adjoin 'a '(a b c) :test #'eq)
;; is equivalent to
(if (apply #'member 'a '(a b c) (list :test #'eq))
lst
(cons obj lst))
;; is equivalent to
(if (member 'a '(a b c) :test #'eq) ...)
(our-adjoin 'a '(a b c))
;; is equivalent to
(if (apply #'member 'a '(a b c) (list)) ...) ; (list) == nil
;; is equivalent to
(if (member 'a '(a b c)) ...)
So your hypothesis (that the equivalent was (apply #'member 'a '(a b c) '())) is correct. (FYI, there is no difference between nil, 'nil, (), '(), and (list).)
APPLY is provided so that we can call functions with a computed argument list.
APPLY has the following syntax:
apply function &rest args+ => result*
the first parameter is a function
then several arguments, at least one, where the last argument needs to be a list

Syntax error in scheme macro expansion

Just to understand how the Scheme macros work i'm trying to define a new command, sum that works exactly like the common operator + (i.e. also undefined number of parameters).
I wroter this code:
(define-syntax sum
(syntax-rules ()
((_ arg1 arg2 args...)
(sum (+ arg1 arg2) args...))
((_ arg1 arg2)
(+ arg1 arg2))
((_ arg1)
arg1)))
It works if i pass it 1, 2 or 3 arguments. But with 4 arguments i get this error:
sum: bad syntax in: (sum 1 2 3 4)
I tried to expand the macro step-by-step with DrRacket but it stops immediately.
Can someone explain me the cause of this error?
In Scheme, ... is just another identifier, so you need a space between args and the ellipses (...) in both places, like this:
(define-syntax sum
(syntax-rules ()
((_ arg1 arg2 args ...)
(sum (+ arg1 arg2) args ...))
___etc___))
BTW, you don't need to create macros in order to accept arbitrary numbers of arguments. You can also use "rest args":
(define (sum . args)
;; args is bound to a list of all the arguments
(foldl + 0 args))

Tacit programming in Lisp

Is it possible to use/implement tacit programming (also known as point-free programming) in Lisp? And in case the answer is yes, has it been done?
This style of programming is possible in CL in principle, but, being a Lisp-2, one has to add several #'s and funcalls. Also, in contrast to Haskell for example, functions are not curried in CL, and there is no implicit partial application. In general, I think that such a style would not be very idiomatic CL.
For example, you could define partial application and composition like this:
(defun partial (function &rest args)
(lambda (&rest args2) (apply function (append args args2))))
(defun comp (&rest functions)
(flet ((step (f g) (lambda (x) (funcall f (funcall g x)))))
(reduce #'step functions :initial-value #'identity)))
(Those are just quick examples I whipped up – they are not really tested or well thought-through for different use-cases.)
With those, something like map ((*2) . (+1)) xs in Haskell becomes:
CL-USER> (mapcar (comp (partial #'* 2) #'1+) '(1 2 3))
(4 6 8)
The sum example:
CL-USER> (defparameter *sum* (partial #'reduce #'+))
*SUM*
CL-USER> (funcall *sum* '(1 2 3))
6
(In this example, you could also set the function cell of a symbol instead of storing the function in the value cell, in order to get around the funcall.)
In Emacs Lisp, by the way, partial application is built-in as apply-partially.
In Qi/Shen, functions are curried, and implicit partial application (when functions are called with one argument) is supported:
(41-) (define comp F G -> (/. X (F (G X))))
comp
(42-) ((comp (* 2) (+ 1)) 1)
4
(43-) (map (comp (* 2) (+ 1)) [1 2 3])
[4 6 8]
There is also syntactic threading sugar in Clojure that gives a similar feeling of "pipelining":
user=> (-> 0 inc (* 2))
2
You could use something like (this is does a little more than -> in
Clojure):
(defmacro -> (obj &rest forms)
"Similar to the -> macro from clojure, but with a tweak: if there is
a $ symbol somewhere in the form, the object is not added as the
first argument to the form, but instead replaces the $ symbol."
(if forms
(if (consp (car forms))
(let* ((first-form (first forms))
(other-forms (rest forms))
(pos (position '$ first-form)))
(if pos
`(-> ,(append (subseq first-form 0 pos)
(list obj)
(subseq first-form (1+ pos)))
,#other-forms)
`(-> ,(list* (first first-form) obj (rest first-form))
,#other-forms)))
`(-> ,(list (car forms) obj)
,#(cdr forms)))
obj))
(you must be careful to also export the symbol $ from the package in
which you place -> - let's call that package tacit - and put
tacit in the use clause of any package where you plan to use ->, so -> and $ are inherited)
Examples of usage:
(-> "TEST"
string-downcase
reverse)
(-> "TEST"
reverse
(elt $ 1))
This is more like F#'s |> (and the shell pipe) than Haskell's ., but they
are pretty much the same thing (I prefer |>, but this is a matter of personal taste).
To see what -> is doing, just macroexpand the last example three times (in SLIME, this is accomplished by putting the cursor on the first ( in the example and typing C-c RET three times).
YES, it's possible and #danlei already explained very well. I am going to add up some examples from the book ANSI Common Lisp by Paul Graham, chapter 6.6 on function builders:
you can define a function builder like this:
(defun compose (&rest fns)
(destructuring-bind (fn1 . rest) (reverse fns)
#'(lambda (&rest args)
(reduce #'(lambda (v f) (funcall f v))
rest
:initial-value (apply fn1 args)))))
(defun curry (fn &rest args)
#'(lambda (&rest args2)
(apply fn (append args args2))))
and use it like this
(mapcar (compose #'list #'round #'sqrt)
'(4 9 16 25))
returns
((2) (3) (4) (5))
The compose function call:
(compose #'a #'b #'c)
is equlvalent to
#'(lambda (&rest args) (a (b (apply #'c args))))
This means compose can take any number of arguments, yeah.
Make a function which add 3 to argument:
(curry #'+ 3)
See more in the book.
Yes, this is possible in general with the right functions. For example, here is an example in Racket implementing sum from the Wikipedia page:
#lang racket
(define sum (curry foldr + 0))
Since procedures are not curried by default, it helps to use curry or write your functions in an explicitly curried style. You could abstract over this with a new define macro that uses currying.