Seeking some advice

Discussion of Common Lisp
Tetrix
Posts: 5
Joined: Wed Sep 28, 2011 8:06 pm

Seeking some advice

Post by Tetrix » Wed Sep 28, 2011 8:14 pm

Hello LispForum,
I'm new here as you can see from this being my first post. I'm a college student and am currently taking a computational psychology course. We started covering the basics of Lisp and I felt pretty comfortable and knew my way around. However, I'm running into some difficulty here and there. I'm not sure if this post will be considered okay, but I'll give it a try.

Here are some of the functions I have to define as well as where I'm at. I might be going the wrong way.. but hopefully you guys can nudge me to the right direction.

1. Use mapcar and lambda to define (add-to-list x lst) which adds the number x to each of a list of numbers and returns the list of results in the same order.

Code: Select all

(defun add-to-list (x lst)
  "(x lst)
Adds the number x to each of a list of numbers and returns the list of results in the same order"
  (mapcar (lambda (a b) (+ a b)) '(x x x x x x x) '(lst)))
I think this is the right direction.. I'm just unaware if there is a function call that gives you a list filled with one variable (illustrated here by '(x x x x x)..).

2.Use do, if, oddp, and return to define (first-odd lst) which returns the first odd integer in a list of integers or ‘none if none are odd.

Code: Select all

(defun first-odd (lst)
  "(lst)
Returns the first odd integer in a list of integers or ‘none if none are odd."
  (if (do ((numbers lst (cdr numbers))
       (odd (first lst) (oddp (car numbers))))
      ((null numbers) odd)) odd 'none))
The do loop return either T or (nil), but I can't keep the value of odd. 'none works. I'm not sure if I'm merging the do loop with the if correctly here.

So yea, these are some of the problems I'm having some difficulty with. Any help would be immensely appreciated. And if this is an inappropriate post, I'm very sorry.
Last edited by nuntius on Sat Oct 01, 2011 10:48 pm, edited 1 time in total.
Reason: add code tag

ramarren
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland
Contact:

Re: Seeking some advice

Post by ramarren » Thu Sep 29, 2011 8:06 am

I have moved your post to the Common Lisp subforum. I assume that the language used is CL. Do not that Lisp is a family of fairly diverse languages, and you should know and specify which specific language is the one used. Also use code tags for including code.
Tetrix wrote:I think this is the right direction.. I'm just unaware if there is a function call that gives you a list filled with one variable (illustrated here by '(x x x x x)..).
You don't need the list of the number added. The purpose of this exercise is to demonstrate that an anonymous function created by LAMBDA can access variables of the enclosing scope, which means you can have an anonymous function of one argument, which will be the elements of the list you are adding to, and the number being added you can refer to just by referencing the variable in the named function.
Tetrix wrote:2.Use do, if, oddp, and return to define (first-odd lst) which returns the first odd integer in a list of integers or ‘none if none are odd.
I am not entirely sure here, because in practice DO is very rarely used directly, since other forms of iterations are easier to understand. And so is direct use of RETURN. Code created within those constraints is necessarily unidiomatic.

The way I see to approach it is to use IF in the end condition. You should first check if the list still has elements, then in the second IF check if the first number is ODDP, if it is, then RETURN. Also note that DO has a result-form, which will be returned if the iteration finished properly, which is one place to return NONE from.
Tetrix wrote:And if this is an inappropriate post, I'm very sorry.
It is quite appropriate to ask for help with homework and similar as long as you show attempt to understand it yourself, which you did. Hopefully I have helped, and if not, please ask further questions.

nuntius
Posts: 538
Joined: Sat Aug 09, 2008 10:44 am
Location: Newton, MA

Re: Seeking some advice

Post by nuntius » Sat Oct 01, 2011 10:54 pm

1) Try putting the value x directly in the lambda body.

2) There are a few ways to structure the do loop. Based on the functions you list, I'd expect a pattern like the following.

Code: Select all

(do bindings
   end-of-input-exit-test-and-return
   (if (oddp ...) (return ...))

Paul
Posts: 106
Joined: Tue Jun 02, 2009 6:00 am

Re: Seeking some advice

Post by Paul » Sun Oct 02, 2011 12:42 am

Tetrix wrote:

Code: Select all

(defun add-to-list (x lst)
  "(x lst)
Adds the number x to each of a list of numbers and returns the list of results in the same order"
  (mapcar (lambda (a b) (+ a b)) '(x x x x x x x) '(lst)))
I think this is the right direction.. I'm just unaware if there is a function call that gives you a list filled with one variable (illustrated here by '(x x x x x)..).
'(x x x x x x x) is a list of 7 copies of the symbol named "X", not seven copies of the value of the function parameter. This will cause a runtime error when you try to add symbols. You could use (list x x x x x x x), but of course you don't know how many copies you need. If you want to do this sort of thing, write

Code: Select all

(defun circular-list (&rest args)
  (let ((list (copy-list args)))
    (nconc list list))))
and use (circular-list x) to make an infinite list of values. But you don't need that for this.

'(lst) suffers from the same problem. You want just lst (better: rename it "list"), which is already a list.

Code: Select all

(defun add-to-list (x list)
  (mapcar (lambda (y) (+ x y)) list))

Tetrix
Posts: 5
Joined: Wed Sep 28, 2011 8:06 pm

Re: Seeking some advice

Post by Tetrix » Sun Oct 02, 2011 5:54 pm

Thanks so much for the help guys! I've been super busy with other courses lately. But I'll be sure to digest all the feedback and try making this work! I'll post back in 3 days with what I can figure out by then.
Quick edit: Number 2 works out now! I guess I didn't grasp the way mapcar mapped functions properly, but now it appears more intuitive then it did at first!
Final solution:
(defun add-to-list (x lst)
"(x lst)
Adds the number x to each of a list of numbers and returns the list of results in the same order"
(mapcar (lambda (y) (+ x y)) lst))

Edit #2: I'm so close to getting number 3 done!

(defun first-odd (lst)
"(lst)
Returns the first odd integer in a list of integers or ‘none if none are odd."
(do ((numbers lst (cdr numbers))
(odd (first lst) (if (oddp (car numbers)) (first numbers))))
((null numbers) odd)))

This gives me the first odd number like I need it. But I'm simply unsure of where to use the Return function to give 'none when there is no odd number in the list.

ramarren
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland
Contact:

Re: Seeking some advice

Post by ramarren » Sun Oct 02, 2011 11:14 pm

Tetrix wrote:This gives me the first odd number like I need it.
It actually doesn't, it gives you the final number if it is odd and NIL otherwise, because the implicit false clause of the IF is overwriting your odd number storage variable. Not to mention so does the true branch, which means it would return the last odd number anyway. The point of using RETURN in this exercise is to break the DO iteration before the list runs out. Since you have to return only the first odd number, there is no point in iterating over all the remaining numbers.

Tetrix
Posts: 5
Joined: Wed Sep 28, 2011 8:06 pm

Re: Seeking some advice

Post by Tetrix » Mon Oct 03, 2011 9:25 am

Ramarren is right haha.. oups.. Could someone just hint me as to where the return fits in all of this? It's the one function in this exercise I don't know.

ramarren
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland
Contact:

Re: Seeking some advice

Post by ramarren » Mon Oct 03, 2011 9:38 am

RETURN is not actually a function, but a macro over a special operator RETURN-FROM. That special operator can be used to return from a named block of code. RETURN is a short form which returns from a block named NIL, which is established implicitly by many forms, including DO.

In short, RETURN does what is says: it immediately returns its argument from a computation. Using it explicitly is fairly rare in idiomatic Lisp code. Normally you would just check if the current number is odd in the termination test, but since the exercise includes RETURN explicitly I guess you are supposed to use it to return the odd number once the iteration finds one.

Tetrix
Posts: 5
Joined: Wed Sep 28, 2011 8:06 pm

Re: Seeking some advice

Post by Tetrix » Mon Oct 03, 2011 9:48 am

I figured it out!
(defun first-odd (lst)
"(lst)
Returns the first odd integer in a list of integers or ‘none if none are odd."
(do ((numbers lst (cdr numbers)))
((null numbers) 'none)
(if (oddp (car numbers))
(return (car numbers)))))
Thanks for the help, I have 2 more problems to do for this assignment and one of them simply .. confuses me. I'll give you a preview of the numbers before I start trying to figure them out over the next 3 days:

4. Use cond and exp to define (activation type sum) which returns the activation value
of a connectionist unit given a sum of products of input activations x corresponding
connection weights. Include both ‘sigmoid and ‘asigmoid types of activation
functions, and return ‘unknown-type if some other type is used as input.

5. Use do, if, and funcall to define (satisfy proc lst) which returns a list of the items in a
list that satisfy a procedure. An item satisfies a procedure if the procedure returns true
when that item is used as the procedure's argument.

Tetrix
Posts: 5
Joined: Wed Sep 28, 2011 8:06 pm

Re: Seeking some advice

Post by Tetrix » Tue Oct 04, 2011 3:59 pm

Okay so I have no clue what exactly is being asked of me in question 4, but I gave number 5 a shot.

I first got stuck with how to use the function funcall since this wasn't covered in class. Here's what I have so far, but it's returning errors. Am I going to the right way?

(defun satisfy (proc lst)
"(proc lst)
Returns a list of the items in a list that satisfy a procedure."
(do ((item lst (cdr item))
(good nil (if (proc item) (cons item)))
((null item) good))))

(I attempted to do (if (funcall proc item) (cons item)) as well. But in both cases, they seem to try to use the proc (e.g. oddp numberp) as a variable (unbound one))

Thanks in advance for the tips

Post Reply