Need help with lambda function

Discussion of Common Lisp
Post Reply
Lispoman
Posts: 12
Joined: Mon Jun 01, 2009 6:09 pm

Need help with lambda function

Post by Lispoman » Mon Jun 01, 2009 7:07 pm

Hello. All

And again I need some help with lisp functions. I use common lisp (just clear lisp)
I have created a function which just check a sequence of the values called H n L. But instead of “test” in the mapcar function I should use a lambda function which includes “test” and then approve that the result will be (t nil nil).
Can somebody help me with?

The code of the H nL function

Code: Select all

(defun test(n) (greaterp high n low) )
       (setq l ‘(4 7 2))
       (setq high  7)
       (setq low 3)
       (mapcar ‘test l)
         (t nil nil)    {the result of the mapcar}

Harleqin
Posts: 71
Joined: Wed Dec 17, 2008 5:18 am
Location: Bonn, Germany

Re: Need help with lambda function

Post by Harleqin » Tue Jun 02, 2009 10:34 am

The way you formatted it, it looks like on function definition, but in fact, it is just 6 top level forms. Comments are made by semicolons, by the way.

Code: Select all

(defun test(n) (greaterp high n low))

(setq l ‘(4 7 2))

(setq high  7)

(setq low 3)

(mapcar ‘test l)

(t nil nil)    ; the result of the mapcar
If you execute these statements in this order on the REPL, the first DEFUN will fail, because HIGH and LOW are unbound at that point. However, since you want to put this explicit function declaration away anyway, let's just see how you would do it with an anonymous function.

First, make it a function. It should take the high and low values, and a list of values to check:

Code: Select all

(defun check-range (high low list)
  ;; ... here be code
  )
You want to be able to call it like this:

Code: Select all

(check-range 7 3 '(4 2 7))
A lambda function is just an anonymous function. Instead of first defining a function, binding it to a symbol, and finally calling it by that symbol,

Code: Select all

(defun foo (x)
  (bar x))

;;; later, somewhere
  (mapcar #'foo some-list)
you create a function "on the fly":

Code: Select all

;;; somewhere
  (mapcar (lambda (x)
            (bar x))
          some-list)
"Just throw more hardware at it" is the root of all evil.
Svante

Jasper
Posts: 209
Joined: Fri Oct 10, 2008 8:22 am
Location: Eindhoven, The Netherlands
Contact:

Re: Need help with lambda function

Post by Jasper » Tue Jun 02, 2009 11:48 am

Don't define create variables with setq or setf, for local variables use let, and macros like multiple-value-bind, destructuring-bind, and probably macros of your own. (with-slots makes symbol-macros with symbol-macrolet, which are not variables.)

If you want 'global' variables use defparameter or defvar it might be a good idea not to use them too often. They're good if they're variables in a program. They are not exactly global variables, as the have the very useful property that you can override them with let:

Code: Select all

(defparameter *x* 1 "the constant 1")

(let ((*x* 2)) *x*)
The latter results in the value 2. This way you can create functions to treat programs as objects with associated functions. Note that surrounding it with ** is good practice for clarity. PCL on these, PCL is a pretty good book to read. I failed to absorb lexical vs closures at first, as this thread shows.

Lispoman
Posts: 12
Joined: Mon Jun 01, 2009 6:09 pm

Re: Need help with lambda function

Post by Lispoman » Tue Jun 02, 2009 7:25 pm

I've tried to understand but have understood only a healf :?

I can't clearly understand a code.

Code: Select all

(defun test(n) (greaterp high n low)) //That's clear: a function test with parameter n but what (greaterp high n low) mean?

(setq l ‘(4 7 2)) //Here  creation of the list l (4 7 2)

(setq high  7) //Then asigning value to variable high

(setq low 3) //Then asigning value to variable low

(mapcar ‘test l) //Here a call of the test function

(t nil nil) //and result

So what should I do to make this code work accordingly to the task
Create a function which assigns values to high and low variables?

gugamilare
Posts: 406
Joined: Sat Mar 07, 2009 6:17 pm
Location: Brazil
Contact:

Re: Need help with lambda function

Post by gugamilare » Tue Jun 02, 2009 8:37 pm

Harleqin wrote:The way you formatted it, it looks like on function definition, but in fact, it is just 6 top level forms. Comments are made by semicolons, by the way.

Code: Select all

(defun test(n) (greaterp high n low))

(setq l ‘(4 7 2))

(setq high  7)

(setq low 3)

(mapcar ‘test l)

(t nil nil)    ; the result of the mapcar
If you execute these statements in this order on the REPL, the first DEFUN will fail, because HIGH and LOW are unbound at that point. However, since you want to put this explicit function declaration away anyway, let's just see how you would do it with an anonymous function.
Lispoman will correct me if I am wrong, but it seems that

Code: Select all

(setq l ‘(4 7 2))

(setq high 7)

(setq low 3)

(mapcar #‘test l) => (t nil nil)
is just an example of how whatever he wants to do is supposed to work. But clearly this is not the Lisp way to do it. It surely looks like some piece of code that some C programmer made in Lisp (no offense, but C and Lisp are quite different languages, and you must thing differently to work with both of them). Also, this:

Code: Select all

(defun test (n)
  (greaterp high n low))
does not look right because there is no function greaterp defined. Or maybe you have it there? If you have, your code probably does exactly what you said it must do.

I can only imagine that Lispoman misinterpreted some exercise his teacher gave him. Maybe his task is to create a "lambda function" that does this task in a clean, Lispy way, more or less like this:

Code: Select all

(mapcar (lambda (n) ... high ... low ...) '(4 7 2)) => (t nil nil)
Well, if this is the case, we can give you hints of how to do it. But I don't want to do your homework for you.

Jasper
Posts: 209
Joined: Fri Oct 10, 2008 8:22 am
Location: Eindhoven, The Netherlands
Contact:

Re: Need help with lambda function

Post by Jasper » Wed Jun 03, 2009 9:58 am

Functions ending with a 'p' are usually predicate functions, returning a truth. So greaterp is >. Lisp variables are not scoped, like C. (Other then variables being available within the bodies. (Macros doing scoping are possible, but i wouldn't go there yet. I concluded that i'd rather not use them.)

And instead of:

Code: Select all

(setq l ‘(4 7 2))
(setq high  7)
(setq low 3)
Do

Code: Select all

(let ((l '(4 7 2))
       (high 7) (low 3))
   ...do the things with the vars...)
Or alternatively

Code: Select all

(defun in-range (list &optional (low 0) (high 1))
  ...do the things with the vars...)
And then to use mapcar -run function with each element of a list, listing the result- and lambda -create an unnamed function- to do what you want to do. x between low and heigh is (< low x heigh) - low < x <heigh. (Usually works that way with binary functions.)

slobodan.blazeski
Posts: 9
Joined: Tue May 26, 2009 8:27 am

Re: Need help with lambda function

Post by slobodan.blazeski » Tue Jun 09, 2009 11:48 am

Do you need something like below?

(defun foo (l high low)
(mapcar #'(lambda (e) (and (> e low) (< e high))) l))
FOO

(foo '(4 7 2) 7 3)
(T NIL NIL)

gugamilare
Posts: 406
Joined: Sat Mar 07, 2009 6:17 pm
Location: Brazil
Contact:

Re: Need help with lambda function

Post by gugamilare » Tue Jun 09, 2009 2:24 pm

Clearing a little bit:

Code: Select all

(defun foo (l high low)
  (mapcar #'(lambda (e) (> high e low)) l))

Post Reply