From: pereges
Subject: Help with a problem
Date: 
Message-ID: <2ab990b9-a11b-4f5b-9284-492d4c598d95@a12g2000yqm.googlegroups.com>
Hello I need help with the following problem:

 Define a function g that takes four parameters: a predicate funcp, a
function func, a number n, and a variable args (which is preceded by
the token &rest).   The function g returns the product of n and the
value of func on args if funcp on n is true, and otherwise g returns
the product of n+1 and the value of func on args.


Here's my attempt although I think I'm 100% wrong:

(defun g (funcp func n &rest args)

(if (apply funcp n)
(* n (apply func args))

(* (+ n 1) (apply func args))))

Can some one please help me ? I'm guessing that I'm doing the
predicate test in a wrong way.

From: Raffael Cavallaro
Subject: Re: Help with a problem
Date: 
Message-ID: <f01cc806-28c3-4060-aab6-be70809bc635@v15g2000yqn.googlegroups.com>
On Mar 20, 5:55 pm, pereges <·······@gmail.com> wrote:
> Hello I need help with the following problem:
>
>  Define a function g that takes four parameters: a predicate funcp, a
> function func, a number n, and a variable args (which is preceded by
> the token &rest).   The function g returns the product of n and the
> value of func on args if funcp on n is true, and otherwise g returns
> the product of n+1 and the value of func on args.
>
> Here's my attempt although I think I'm 100% wrong:
>
> (defun g (funcp func n &rest args)
>
> (if (apply funcp n)
> (* n (apply func args))
>
> (* (+ n 1) (apply func args))))
>
> Can some one please help me ? I'm guessing that I'm doing the
> predicate test in a wrong way.

apply takes a list. &rest creates a list. a naked arg like n is not a
list, so apply won't work. but funcall will. I think the rest of what
you have is right except for your:

(apply funcp n)

where you want

(funcall funcp n)

? (apply #'+ (list 1 2))
3
? (apply #'+ 1 2)
> Error: Can't construct argument list from 2.
> While executing: APPLY, in process Listener(6).
> Type :POP to abort, :R for a list of available restarts.
> Type :? for other options.
1 > :pop

? (funcall #'+ 1 2)
3
?
From: Pascal J. Bourguignon
Subject: Re: Help with a problem
Date: 
Message-ID: <87ab7fn8rz.fsf@galatea.local>
Raffael Cavallaro <················@gmail.com> writes:
> ? (apply #'+ 1 2)
>> Error: Can't construct argument list from 2.

You can still use APPLY:

C/USER[103]> (apply (function +) 1 2 nil)
3
C/USER[104]> (apply (function +) 1 '(2))
3

-- 
__Pascal Bourguignon__
From: Raffael Cavallaro
Subject: Re: Help with a problem
Date: 
Message-ID: <609a79cb-432a-4f07-b9ba-699e0c940673@a39g2000yqc.googlegroups.com>
On Mar 20, 6:12 pm, ····@informatimago.com (Pascal J. Bourguignon)
wrote:
> Raffael Cavallaro <················@gmail.com> writes:
> > ? (apply #'+ 1 2)
> >> Error: Can't construct argument list from 2.
>
> You can still use APPLY:
>
> C/USER[103]> (apply (function +) 1 2 nil)
> 3
> C/USER[104]> (apply (function +) 1 '(2))
> 3
>
> --
> __Pascal Bourguignon__

we can always rely on you for idiomatic common lisp...

... not
From: pereges
Subject: Re: Help with a problem
Date: 
Message-ID: <0b7fe050-fbd3-4121-848a-7c27223fa792@13g2000yql.googlegroups.com>
thanks for the help...the function works now and I tried quite a few
examples:

[2]> (g #'evenp #'* 1 5 6)
60
[3]> (g #'oddp #'+ 1 1 2 3 4)
10
[4]> (g #'zerop #'/ 1 12 4 3)
2
[5]> (g #'integerp #'- 2.1 4 2)
6.2
From: William James
Subject: Re: Help with a problem
Date: 
Message-ID: <gq1c6g02vf2@enews2.newsguy.com>
Raffael Cavallaro wrote:

> On Mar 20, 6:12�pm, ····@informatimago.com (Pascal J. Bourguignon)
> wrote:
> > Raffael Cavallaro <················@gmail.com> writes:
> > > ? (apply #'+ 1 2)
> > >> Error: Can't construct argument list from 2.
> > 
> > You can still use APPLY:
> > 
> > C/USER[103]> (apply (function +) 1 2 nil)
> > 3
> > C/USER[104]> (apply (function +) 1 '(2))
> > 3
> > 
> > --
> > __Pascal Bourguignon__
> 
> we can always rely on you for idiomatic common lisp...

At first, I read that as "idiotic commune lisp".

> 
> ... not

Clojure:

user=> (apply + 2 3 nil)
5
user=> (apply + 2 3 [])
5
From: Barry Margolin
Subject: Re: Help with a problem
Date: 
Message-ID: <barmar-B4E078.11340521032009@mara100-84.onlink.net>
In article <··············@galatea.local>,
 ···@informatimago.com (Pascal J. Bourguignon) wrote:

> Raffael Cavallaro <················@gmail.com> writes:
> > ? (apply #'+ 1 2)
> >> Error: Can't construct argument list from 2.
> 
> You can still use APPLY:
> 
> C/USER[103]> (apply (function +) 1 2 nil)
> 3
> C/USER[104]> (apply (function +) 1 '(2))
> 3

You can, but why would you when FUNCALL is available?  Unless you're 
entering an obfuscated code contest, the extra argument or listification 
seems pointless.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Pascal J. Bourguignon
Subject: Re: Help with a problem
Date: 
Message-ID: <87ab7elt5v.fsf@galatea.local>
Barry Margolin <······@alum.mit.edu> writes:

> In article <··············@galatea.local>,
>  ···@informatimago.com (Pascal J. Bourguignon) wrote:
>
>> Raffael Cavallaro <················@gmail.com> writes:
>> > ? (apply #'+ 1 2)
>> >> Error: Can't construct argument list from 2.
>> 
>> You can still use APPLY:
>> 
>> C/USER[103]> (apply (function +) 1 2 nil)
>> 3
>> C/USER[104]> (apply (function +) 1 '(2))
>> 3
>
> You can, but why would you when FUNCALL is available?  Unless you're 
> entering an obfuscated code contest, the extra argument or listification 
> seems pointless.

I'm sorry, I didn't quote enough of Raffael's post.  He said that "you
could not use APPLY", I just wanted to show that you could.  Notice
that in my answer to the OP, I mentionned first FUNCALL.

-- 
__Pascal Bourguignon__
From: Pascal J. Bourguignon
Subject: Re: Help with a problem
Date: 
Message-ID: <87eiwrn8u3.fsf@galatea.local>
pereges <·······@gmail.com> writes:

> Hello I need help with the following problem:
>
>  Define a function g that takes four parameters: a predicate funcp, a
> function func, a number n, and a variable args (which is preceded by
> the token &rest).   The function g returns the product of n and the
> value of func on args if funcp on n is true, and otherwise g returns
> the product of n+1 and the value of func on args.
>
>
> Here's my attempt although I think I'm 100% wrong:
>
> (defun g (funcp func n &rest args)
>
> (if (apply funcp n)
> (* n (apply func args))
>
> (* (+ n 1) (apply func args))))
>
> Can some one please help me ? I'm guessing that I'm doing the
> predicate test in a wrong way.

Use FUNCALL instead of APPLY.

When you learn a language, you should read the reference page of each
operator that you use for a few first times, until you know it by
heart.  This means, also reading the "See Also:" references.

In the case of APPLY, you could see that APPLY takes several
arguments, of which the last is a list of further arguments for the
function. And in the "See also:" section, you'd have to read about
funcall and understand that it may be better to use in the case you
have a fixed arity for the function.

http://www.lispworks.com/documentation/HyperSpec/Body/f_apply.htm
http://www.lispworks.com/documentation/HyperSpec/Body/f_funcal.htm


So you could write either: 
   (funcall funcp n)      ; or:
   (apply funcp n '())    ; or:
   (apply funcp (list n))


Also, you should start using an editor helping you with your lisp
code.  Some editor that does parenthesis matching and automatic
indentation as a minimum.

(defun g (funcp func n &rest args)
  (if (funcall funcp n)
    (* n       (apply func args))
    (* (+ n 1) (apply func args))))


Note that you have a common subexpression.  It might be clearer
(easier to understand what G does) if you wrote:

(defun g (funcp func n &rest args)
  (* (if (apply funcp n)
       n
       (1+ n))
     (apply func args)))

or even:

(defun g (funcp func n &rest args)
  (* (+ n (if (apply funcp n) 0 1))
     (apply func args)))

"G multiplies the result of FUNC applied to ARGS by N, or N+1 when FUNCP of N."

-- 
__Pascal Bourguignon__
From: Kenneth Tilton
Subject: Re: Help with a problem
Date: 
Message-ID: <49c42c29$0$20287$607ed4bc@cv.net>
Pascal J. Bourguignon wrote:
> pereges <·······@gmail.com> writes:
> 
>> Hello I need help with the following problem:
>>
>>  Define a function g that takes four parameters: a predicate funcp, a
>> function func, a number n, and a variable args (which is preceded by
>> the token &rest).   The function g returns the product of n and the
>> value of func on args if funcp on n is true, and otherwise g returns
>> the product of n+1 and the value of func on args.
>>
>>
>> Here's my attempt although I think I'm 100% wrong:
>>
>> (defun g (funcp func n &rest args)
>>
>> (if (apply funcp n)
>> (* n (apply func args))
>>
>> (* (+ n 1) (apply func args))))
>>
>> Can some one please help me ? I'm guessing that I'm doing the
>> predicate test in a wrong way.
> 
> Use FUNCALL instead of APPLY.
> 
> When you learn a language, you should read the reference page of each
> operator that you use for a few first times, until you know it by
> heart.  This means, also reading the "See Also:" references.

Ewwwwwwww! I'd rather go shopping! It's more fun asking in a public 
forum and getting reamed by cranky old-timers.

kt
From: William James
Subject: Re: Help with a problem
Date: 
Message-ID: <gq1dm7030lm@enews2.newsguy.com>
Pascal J. Bourguignon wrote:

> pereges <·······@gmail.com> writes:
> 
> > Hello I need help with the following problem:
> > 
> >  Define a function g that takes four parameters: a predicate funcp,
> > a function func, a number n, and a variable args (which is preceded
> > by the token &rest).   The function g returns the product of n and
> > the value of func on args if funcp on n is true, and otherwise g
> > returns the product of n+1 and the value of func on args.
> > 
> > 
> > Here's my attempt although I think I'm 100% wrong:
> > 
> > (defun g (funcp func n &rest args)
> > 
> > (if (apply funcp n)
> > (* n (apply func args))
> > 
> > (* (+ n 1) (apply func args))))
> > 
> > Can some one please help me ? I'm guessing that I'm doing the
> > predicate test in a wrong way.
> 
> Use FUNCALL instead of APPLY.
> 
> When you learn a language, you should read the reference page of each
> operator that you use for a few first times, until you know it by
> heart.  This means, also reading the "See Also:" references.
> 
> In the case of APPLY, you could see that APPLY takes several
> arguments, of which the last is a list of further arguments for the
> function. And in the "See also:" section, you'd have to read about
> funcall and understand that it may be better to use in the case you
> have a fixed arity for the function.
> 
> http://www.lispworks.com/documentation/HyperSpec/Body/f_apply.htm
> http://www.lispworks.com/documentation/HyperSpec/Body/f_funcal.htm
> 
> 
> So you could write either: 
>    (funcall funcp n)      ; or:
>    (apply funcp n '())    ; or:
>    (apply funcp (list n))
> 
> 
> Also, you should start using an editor helping you with your lisp
> code.  Some editor that does parenthesis matching and automatic
> indentation as a minimum.
> 
> (defun g (funcp func n &rest args)
>   (if (funcall funcp n)
>     (* n       (apply func args))
>     (* (+ n 1) (apply func args))))
> 
> 
> Note that you have a common subexpression.  It might be clearer
> (easier to understand what G does) if you wrote:
> 
> (defun g (funcp func n &rest args)
>   (* (if (apply funcp n)
>        n
>        (1+ n))
>      (apply func args)))
> 
> or even:
> 
> (defun g (funcp func n &rest args)
>   (* (+ n (if (apply funcp n) 0 1))
>      (apply func args)))

You have mastered the art of the hideous.

Clojure:

(defn g [test func n & args]
  (* (if (test n) n (inc n)) (apply func args)))


user=> (g even? * 1 5 6)
60
user=> (g odd? + 1 1 2 3 4)
10
user=> (g zero? / 1 12 4 3)
2
user=> (g integer? - 2.1 4 2)
6.2
From: Raffael Cavallaro
Subject: Re: Help with a problem
Date: 
Message-ID: <71e61fde-71bb-4c1b-bf44-17e7c10ea7ae@j8g2000yql.googlegroups.com>
On Mar 20, 8:51 pm, "William James" <·········@yahoo.com> wrote:
> Clojure:
>
> (defn g [test func n & args]
>   (* (if (test n) n (inc n)) (apply func args)))

You want these parentheses, don't you? The lisp is swelling in you
now. Take your Jedi weapon. Use it. I am unarmed. Strike me down with
it. Give in to your anger. With each passing moment you make yourself
more my servant.


see also: <http://xkcd.com/297/>