Page 1 of 2

### more newbie help...

Posted: Mon Mar 30, 2009 5:21 pm
Hello,

I am trying to make a suffix function, that takes a variable amount of args and prints out the last 'x'.

For example, if I said (suffix 3 '(a b c d e f))

I would get

D E F

back...

But I can't get this to work. Here is what I have so far...

HELP!

Thanks.

Code: Select all

``````
(defun suffix (x &rest args)
setq f 0

(loop for l in args

for y from 1

if (>= f x)
do((print l))
(setq f (+ f 1))

)

)                                                                                                                             ``````

### Re: more newbie help...

Posted: Tue Mar 31, 2009 9:29 am
A few questions:

1. Is this homework?
2. Do you have to use LOOP? Recursion might be your friend here.
3. What is the desired behavior of when the length of the list is less than 'x'? In other words, what does (suffix 3 '(a b)) return? Just (a b)?
4. Also, you say that you want the function to take a variable number of arguments, but you show it taking a list. A list counts as a single argument, whatever its length. In other words a list of any length is bound to a single argument in the function call. If you want it to take a list and not an unlimited number of arguments, you don't need &rest.

If you don't have to use LOOP, I suggest looking up the behavior of COND and IF, LENGTH, and CDR, arranging them appropriately, and mixing in a bit of recursion.

### Re: more newbie help...

Posted: Tue Mar 31, 2009 10:05 am
I think subseq is the function you are looking for. (subseq does require the indices you give to be within bounds though.)

Further, your code snippet seems to look like you haven't fully understood s-expressions yet. Note that the LOOP macro has a weird little language of its own there. You might want to stay away from it until you understand how to do things without loop. (There are alternatives to LOOP that are much better imo, but i guess loop is acceptable.)

It is usual and natural not to put ending parentheses on a new line, like C(++, whatever) curly hooks {}.

If you want to make a variable, 99% of the cases you use LET, almost never DEFVAR, and SETQ, SETF are for setting variables/things. (I never use SETQ, i don't get it, lol, nah think it is only for setting variables.) A good directly readable online book to get started. (Look under variables to see how LET works. Basically you have an area where the variable creation/setting go and where the body of the code goes. (Although one can make macros that makes C-like scopes, but for me not using them pushes me -me at least- to make better code.)

Making a version of subseq is good practice, i suggest doing it with DO, LET or recursively. If you want UNTIL: (WHILE is easy from this, of course.)

Code: Select all

``````(defmacro until (cond &body body) `(do () (,cond (values)) ,@body))

(let ((i 0))
(until (> i 10)
(print i)
(setf i (+ i 1))))``````
(This is a pretty crude way to program lisp though.)
Btw, do not use L as a variable, 'l' looks like 1.

### Re: more newbie help...

Posted: Tue Mar 31, 2009 12:26 pm
You shouldn't do like this:

Code: Select all

``````(defun suffix (x &rest args)
(setf f 0)
...)
``````
First, you want to pass only 2 arguments to the function suffix. In you example, (suffix 3 '(a b c d e f)), the first argument is 3 and the second is '(a b c d e f). In this case, you don't need the &rest directive.

Second, you can't just assign some value to f without declaring it, otherwise you may be creating a global variable instead of a local one. You need to use let to declare a variable.

With these changes, this is how your code should be:

Code: Select all

``````(defun suffix (x args)
(let ((f 0))
...))
``````
After changing those things, go on and test your function. You'll see that the algorithm itself is wrong, but at least it will work - it will not just compute some meaningless value.

P.S.: A very good book to learn Common Lisp http://www.gigamonkeys.com/book/.

### Re: more newbie help...

Posted: Tue Mar 31, 2009 6:30 pm
It seems that you are exactly "reinventing" the NTHCDR function.

### Re: more newbie help...

Posted: Tue Mar 31, 2009 6:52 pm
Harleqin wrote:It seems that you are exactly "reinventing" the NTHCDR function.
On the other hand, by his description, he wants to create a function that like butlast, but with reversed order of arguments.

### Re: more newbie help...

Posted: Tue Mar 31, 2009 7:11 pm
Harleqin wrote:It seems that you are exactly "reinventing" the NTHCDR function.
Very close, but not quite, as described. You could write this using NTHCDR and LENGTH, however. In fact, that was what I immediately thought of when I read the description.

### Re: more newbie help...

Posted: Tue Mar 31, 2009 8:01 pm
I really need to read more carefully late at night. I am sorry.

I also recommend "Practical Common Lisp", but I would also recommend to forget LOOP, at least at first. LOOP will stand in the way of your understanding of Lisp. You don't need it.

### Re: more newbie help...

Posted: Tue Mar 31, 2009 9:20 pm
gugamilare wrote:
Harleqin wrote:It seems that you are exactly "reinventing" the NTHCDR function.
On the other hand, by his description, he wants to create a function that like butlast, but with reversed order of arguments.
I think you mean LAST there.

### Re: more newbie help...

Posted: Wed Apr 01, 2009 12:10 am
We're tumbling over each other to support a newbie. Lisp looking desperate

This forum is a little silent. Post a little more about your favorite project/lisp experience/thing you learned about programming/algorithm? Don't be afraid to be wrong. (Or point me to older threads that are interesting.)