From: ······@gmail.com
Subject: How to solve this
Date: 
Message-ID: <9bb6770e-7273-4f7f-b39b-adbfe7236ae4@p25g2000hsf.googlegroups.com>
I would like to create the following function

(defun foo (a b)
  (let a)
  (eval b)))

(foo '((a 2) (b 2) (c 3)) '(+ a b c))

Is there a way to do it?

I was able to solve a slightly different case of the problem, where I
simply substituted the values in the list to be evaluated, but I
wanted to see if there is  a more direct approach.

From: Ron Garret
Subject: Re: How to solve this
Date: 
Message-ID: <rNOSPAMon-2D2713.10285008042008@news.gha.chartermi.net>
In article 
<····································@p25g2000hsf.googlegroups.com>,
 ·······@gmail.com" <······@gmail.com> wrote:

> I would like to create the following function
> 
> (defun foo (a b)
>   (let a)
>   (eval b)))
> 
> (foo '((a 2) (b 2) (c 3)) '(+ a b c))
> 
> Is there a way to do it?
> 
> I was able to solve a slightly different case of the problem, where I
> simply substituted the values in the list to be evaluated, but I
> wanted to see if there is  a more direct approach.

Try using PROGV.

rg
From: Peter Hildebrandt
Subject: Re: How to solve this
Date: 
Message-ID: <47fba3e9$0$90275$14726298@news.sunsite.dk>
······@gmail.com wrote:
> I would like to create the following function
> 
> (defun foo (a b)
>   (let a)
>   (eval b)))
> 
> (foo '((a 2) (b 2) (c 3)) '(+ a b c))

If the parameters are known at compile-time (like in this example), you 
can write foo as a macro:

(defmacro foo (a b)
	  `(let ,a
	     ,b))
(foo ((a 2) (b 2) (c 3)) (+ a b c))
==> 7
(Note that you must not quote the parameters in this case)

For a better answer, you should tell us what this is for.

Peter


> 
> Is there a way to do it?
> 
> I was able to solve a slightly different case of the problem, where I
> simply substituted the values in the list to be evaluated, but I
> wanted to see if there is  a more direct approach.
From: ······@gmail.com
Subject: Re: How to solve this
Date: 
Message-ID: <80a1fc6c-c88d-4c4e-9fd8-e34c29fbb0b6@u69g2000hse.googlegroups.com>
On Apr 8, 6:57 pm, Peter Hildebrandt <·················@gmail.com>
wrote:
> If the parameters are known at compile-time (like in this example), you
> can write foo as a macro:
>
> (defmacro foo (a b)
>           `(let ,a
>              ,b))
> (foo ((a 2) (b 2) (c 3)) (+ a b c))
> ==> 7
Can you explain why parameters should be known at compile-time,it
doesn't make sense to me.
Best,Milan
From: Peter Hildebrandt
Subject: Re: How to solve this
Date: 
Message-ID: <47fca932$0$90272$14726298@news.sunsite.dk>
······@gmail.com wrote:
> On Apr 8, 6:57 pm, Peter Hildebrandt <·················@gmail.com>
> wrote:
>> If the parameters are known at compile-time (like in this example), you
>> can write foo as a macro:
>>
>> (defmacro foo (a b)
>>           `(let ,a
>>              ,b))
>> (foo ((a 2) (b 2) (c 3)) (+ a b c))
>> ==> 7
> Can you explain why parameters should be known at compile-time,it
> doesn't make sense to me.
> Best,Milan

First of all, this was a somewhat silly example to show how one could 
(mis)understand your question easily.  Others have pointed you to eval, 
which seems to be what you need if you *really* have to establish those 
lexical bindings (the let) at runtime -- since what you are doing there 
is pretty much like writing an interpreter.

My solution was the easy way out here:  The macro creates an expression 
at compile time which does the right thing in this case.  Since a is put 
into place at compile time, it is necessary that it has the form ((var1 
val1) (var2 val2) ...) at compile time (that is, when the macro foo is 
expanded).

To make things more clear:

(foo ((a (+ 1 2)) (* a 2))

would work as expected.

(foo (if (something) ((a 1)) ((a 2))) (1+ a))

would not even compile, because here the value for parameter a, (if 
...), is not know when foo is expanded.  Hence foo expands into:

(let (if (something) ((a 1)) ((a 2)))
    (1+ a))

which is obviously not a legal let form and thus does not compile.

If all that does not make sense to you right now, read up on macros and 
functions (PCL or the like), play a couple hours with the repl, and the 
reread the examples.

Without a deeper understanding of what this is all about, the right 
thing to do would (probably) be to define things a little better, such as

- vars is a list of three expressions to be assigned to the variables a, 
b, and c
- expr is an expression using a, b, and c

Then you can write foo as a function:

(defun foo (vars expr)
   (let ((a (first vars)) (b (second vars)) (c (third vars)))
      (apply (car expr) (cdr expr))))


And do

(foo (list (1+ 1) (1+ 2) (1+ 3)) '(* a b c))

Note that

(foo '((1+ 1) (1+ 2) (1+ 3)) '(* a b c))

won't work ...

Have fun figuring it all out :-)

Peter
From: ······@gmail.com
Subject: Re: How to solve this
Date: 
Message-ID: <b4502509-832b-4218-bda5-446801a7b134@b5g2000pri.googlegroups.com>
On Apr 9, 1:32 pm, Peter Hildebrandt <·················@gmail.com>
wrote:
> ······@gmail.com wrote:
> > On Apr 8, 6:57 pm, Peter Hildebrandt <·················@gmail.com>
> > wrote:
> >> If the parameters are known at compile-time (like in this example), you
> >> can write foo as a macro:
>
> >> (defmacro foo (a b)
> >>           `(let ,a
> >>              ,b))
> >> (foo ((a 2) (b 2) (c 3)) (+ a b c))
> >> ==> 7
> > Can you explain why parameters should be known at compile-time,it
> > doesn't make sense to me.
> > Best,Milan
>
> First of all, this was a somewhat silly example to show how one could
> (mis)understand your question easily.  Others have pointed you to eval,
> which seems to be what you need if you *really* have to establish those
> lexical bindings (the let) at runtime -- since what you are doing there
> is pretty much like writing an interpreter.
>
> My solution was the easy way out here:  The macro creates an expression
> at compile time which does the right thing in this case.  Since a is put
> into place at compile time, it is necessary that it has the form ((var1
> val1) (var2 val2) ...) at compile time (that is, when the macro foo is
> expanded).
>
> To make things more clear:
>
> (foo ((a (+ 1 2)) (* a 2))
>
> would work as expected.
>
> (foo (if (something) ((a 1)) ((a 2))) (1+ a))
>
> would not even compile, because here the value for parameter a, (if
> ...), is not know when foo is expanded.  Hence foo expands into:
>
> (let (if (something) ((a 1)) ((a 2)))
>     (1+ a))
>
> which is obviously not a legal let form and thus does not compile.
>
> If all that does not make sense to you right now, read up on macros and
> functions (PCL or the like), play a couple hours with the repl, and the
> reread the examples.
>
> Without a deeper understanding of what this is all about, the right
> thing to do would (probably) be to define things a little better, such as
>
> - vars is a list of three expressions to be assigned to the variables a,
> b, and c
> - expr is an expression using a, b, and c
>
> Then you can write foo as a function:
>
> (defun foo (vars expr)
>    (let ((a (first vars)) (b (second vars)) (c (third vars)))
>       (apply (car expr) (cdr expr))))
>
> And do
>
> (foo (list (1+ 1) (1+ 2) (1+ 3)) '(* a b c))
>
> Note that
>
> (foo '((1+ 1) (1+ 2) (1+ 3)) '(* a b c))
>
> won't work ...
>
> Have fun figuring it all out :-)
>
> Peter

I understand that, sure you need to have valid let form so it can
compile .. i understand that you cant do something like this:
(foo ((c (if (= (read) 5) 1 2)) (d 0)) (+ c d))

my fault probably, i'm still new here ... thanks anyway
best,milan
From: ······@gmail.com
Subject: Re: How to solve this
Date: 
Message-ID: <54159519-563e-4606-a334-4da2d8f70f19@s39g2000prd.googlegroups.com>
> compile .. i understand that you cant do something like this:
> (foo ((c (if (= (read) 5) 1 2)) (d 0)) (+ c d))
someone will misunderstand this
i thought that you are saying in your first post that this cant be
done, that is why i send my first response
thanks,milan
From: Pascal J. Bourguignon
Subject: Re: How to solve this
Date: 
Message-ID: <7clk3n6wa2.fsf@pbourguignon.anevia.com>
·······@gmail.com" <······@gmail.com> writes:

> On Apr 8, 6:57 pm, Peter Hildebrandt <·················@gmail.com>
> wrote:
>> If the parameters are known at compile-time (like in this example), you
>> can write foo as a macro:
>>
>> (defmacro foo (a b)
>>           `(let ,a
>>              ,b))
>> (foo ((a 2) (b 2) (c 3)) (+ a b c))
>> ==> 7
> Can you explain why parameters should be known at compile-time,it
> doesn't make sense to me.

Use macroexpand to understand:

 (macroexpand '(foo (list (list a x) (list b (f y)))  (+ a b)))


-- 
__Pascal Bourguignon__
From: Kent M Pitman
Subject: Re: How to solve this
Date: 
Message-ID: <u7if80wzh.fsf@nhplace.com>
·······@gmail.com" <······@gmail.com> writes:

> I would like to create the following function
> 
> (defun foo (a b)
>   (let a)
>   (eval b)))
> 
> (foo '((a 2) (b 2) (c 3)) '(+ a b c))
> 
> Is there a way to do it?
> 
> I was able to solve a slightly different case of the problem, where I
> simply substituted the values in the list to be evaluated, but I
> wanted to see if there is  a more direct approach.

(defun foo (bindings form)
  (progv (mapcar #'first  bindings)
         (mapcar #'second bindings)
    (eval form)))
From: Alex Mizrahi
Subject: Re: How to solve this
Date: 
Message-ID: <47fc7d02$0$90274$14726298@news.sunsite.dk>
 KMP> (defun foo (bindings form)
 KMP>   (progv (mapcar #'first  bindings)
 KMP>          (mapcar #'second bindings)
 KMP>     (eval form)))

is it OK to use variables as special without declaring them being special?
PROGV does nothing more than setting symbol-values, and I remember you've 
said it's not specified if this should work (it works in all sane CL 
implementations, though).
if this works, than we can have non-special global variables.. 
From: Thomas F. Burdick
Subject: Re: How to solve this
Date: 
Message-ID: <672847e4-dd4d-4d69-b242-349d748bd7be@c19g2000prf.googlegroups.com>
On Apr 9, 10:23 am, "Alex Mizrahi" <········@users.sourceforge.net>
wrote:
>  KMP> (defun foo (bindings form)
>  KMP>   (progv (mapcar #'first  bindings)
>  KMP>          (mapcar #'second bindings)
>  KMP>     (eval form)))
>
> is it OK to use variables as special without declaring them being special?
> PROGV does nothing more than setting symbol-values,

This is incorrect.  Please read the spec before trying to get language
lawyery, rather than just pulling things out of your ass.

> and I remember you've
> said it's not specified if this should work (it works in all sane CL
> implementations, though).
> if this works, than we can have non-special global variables..
From: Alex Mizrahi
Subject: Re: How to solve this
Date: 
Message-ID: <47fca98a$0$90273$14726298@news.sunsite.dk>
 ??>> is it OK to use variables as special without declaring them being
 ??>> special? PROGV does nothing more than setting symbol-values,

 TFB> This is incorrect.  Please read the spec before trying to get language
 TFB> lawyery, rather than just pulling things out of your ass.

i find spec being quite vague on this:
----
If a form is a symbol that is not a symbol macro, then it is the name of a 
variable, and the value of that variable is returned.
There are three kinds of variables: lexical variables, dynamic variables, 
and constant variables.
----
A variable is a dynamic variable if one of the following conditions hold:
It is locally declared or globally proclaimed special.
It occurs textually within a form that creates a dynamic binding for a 
variable of the same name, and the binding is not shadowed[2] by a form that 
creates a lexical binding of the same variable name.
----

if we are doing stuff like this:

(defvar *code* '(+ a b))
(progv '(a b) '(3 4) (eval *code*))

do variables a and b in *code* occur textually withing progv? it seems they 
don't.
how can we interpret section "3.1.2.1.1.2 Dynamic Variables" to explain how 
progv/eval combo works? 
From: Pascal J. Bourguignon
Subject: Re: How to solve this
Date: 
Message-ID: <7cprsz75ry.fsf@pbourguignon.anevia.com>
"Alex Mizrahi" <········@users.sourceforge.net> writes:

>  KMP> (defun foo (bindings form)
>  KMP>   (progv (mapcar #'first  bindings)
>  KMP>          (mapcar #'second bindings)
>  KMP>     (eval form)))
>
> is it OK to use variables as special without declaring them being special?
> PROGV does nothing more than setting symbol-values, and I remember you've 
> said it's not specified if this should work (it works in all sane CL 
> implementations, though).
> if this works, than we can have non-special global variables.. 

Yes, we can have non-special global variables, but they're not
provided by CL, you have to implement them yourself (eg. with a symbol
macro).  But not using SYMBOL-VALUE, since precisely, SYMBOL-VALUE
accesses the binding of the special variable.

-- 
__Pascal Bourguignon__
From: Alex Mizrahi
Subject: Re: How to solve this
Date: 
Message-ID: <47fcaae2$0$90270$14726298@news.sunsite.dk>
 PJB> Yes, we can have non-special global variables, but they're not
 PJB> provided by CL, you have to implement them yourself (eg. with a symbol
 PJB> macro).  But not using SYMBOL-VALUE, since precisely, SYMBOL-VALUE
 PJB> accesses the binding of the special variable.

last time i've checked symbol-value "Accesses the symbol's value cell.", 
it's not defined in terms of variables.
but of course setting does not create variable, so implementation might 
complain about undefined variable.
From: Alex Mizrahi
Subject: Re: How to solve this
Date: 
Message-ID: <47fba799$0$90273$14726298@news.sunsite.dk>
 r> I would like to create the following function

 r> (defun foo (a b)
 r>   (let a)
 r>   (eval b)))

 r> (foo '((a 2) (b 2) (c 3)) '(+ a b c))

 r> Is there a way to do it?

you mean expression '(+ a b c) is only know in run-time (i.e. input from 
user) and you need to find it's value for certain values of variables?
there are several ways of doing this..

if you prefer let and eval:

(defun eval-expr (vars expr)
   (eval `(let ,vars ,expr)))

for '((a 2) (b 2) (c 3)) '(+ a b c)) it will create list (let ((a 2) (b 2) 
(c 3)) (+ a b c)) and evaluate it.
From: Pascal Bourguignon
Subject: Re: How to solve this
Date: 
Message-ID: <87d4p0hrub.fsf@thalassa.informatimago.com>
·······@gmail.com" <······@gmail.com> writes:

> I would like to create the following function
>
> (defun foo (a b)
>   (let a)
>   (eval b)))
>
> (foo '((a 2) (b 2) (c 3)) '(+ a b c))
>
> Is there a way to do it?
>
> I was able to solve a slightly different case of the problem, where I
> simply substituted the values in the list to be evaluated, but I
> wanted to see if there is  a more direct approach.


(defun foo (bindings expression)
  (funcall (compile nil `(lambda () (let ,bindings ,expression)))))

(foo '((a 2) (b 2) (c 3)) '(+ a b c))
--> 7

Using PROGV might be problematic, if the expression calls a function
that uses a dynamic variable masked by PROGV  unintendedly (unprobable
since dynamic variables should be named with the *star* convention,
but still possible).

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

COMPONENT EQUIVALENCY NOTICE: The subatomic particles (electrons,
protons, etc.) comprising this product are exactly the same in every
measurable respect as those used in the products of other
manufacturers, and no claim to the contrary may legitimately be
expressed or implied.
From: Kent M Pitman
Subject: Re: How to solve this
Date: 
Message-ID: <uabk3vhw7.fsf@nhplace.com>
Pascal Bourguignon <···@informatimago.com> writes:

> (defun foo (bindings expression)
>   (funcall (compile nil `(lambda () (let ,bindings ,expression)))))
> 
> (foo '((a 2) (b 2) (c 3)) '(+ a b c))
> --> 7
> 
> Using PROGV might be problematic, if the expression calls a function
> that uses a dynamic variable masked by PROGV  unintendedly (unprobable
> since dynamic variables should be named with the *star* convention,
> but still possible).

That would sound like a bug in PROGV.  Is there any reason to suppose
PROGV binds other than the list of variables one gives it?
From: Aaron Brown
Subject: Re: How to solve this
Date: 
Message-ID: <694b2c86-2d91-4324-97be-582fb4830171@l64g2000hse.googlegroups.com>
Kent M Pitman wrote:

> Pascal Bourguignon <····@informatimago.com> writes:

>> Using PROGV might be problematic, if the expression calls
>> a function that uses a dynamic variable masked by PROGV
>> unintendedly (unprobable since dynamic variables should
>> be named with the *star* convention, but still possible).
>
> That would sound like a bug in PROGV.  Is there any reason
> to suppose PROGV binds other than the list of variables
> one gives it?

I think he just means that the caller of PROGV needs to take
care not to use a variable name used (dynamically) by one of
the functions called during PROGV.

--
Aaron
http://arundelo.com/
From: Kent M Pitman
Subject: Re: How to solve this
Date: 
Message-ID: <uwsn7d45e.fsf@nhplace.com>
Aaron Brown <········@hotmail.com> writes:

> Kent M Pitman wrote:
> 
> > Pascal Bourguignon <····@informatimago.com> writes:
> 
> >> Using PROGV might be problematic, if the expression calls
> >> a function that uses a dynamic variable masked by PROGV
> >> unintendedly (unprobable since dynamic variables should
> >> be named with the *star* convention, but still possible).
> >
> > That would sound like a bug in PROGV.  Is there any reason
> > to suppose PROGV binds other than the list of variables
> > one gives it?
> 
> I think he just means that the caller of PROGV needs to take
> care not to use a variable name used (dynamically) by one of
> the functions called during PROGV.

Well, in that case, you mean "unless it's appropriate to do that."

(defun foo (bindings form)
  (with-output-to-string (*standard-output*)
    (progv (mapcar #'first  bindings)
           (mapcar #'second bindings)
      (eval form))))

(let ((*print-circle* t))
  (foo '((*print-length* 3))
       '(prin1 '(#1=(a . #1#) b c d))))
=> "(#1=(A . #1#) B C ...)"

Here the result relies [I allege correctly] on special values from 
the given arguments, the FOO function, and FOO's caller.

Then again, it's correct because it does what I intended.  Special
variables are like that--they are correct when bound at appropriate
times and incorrect when bound at the wrong times. :)
From: Pascal J. Bourguignon
Subject: Re: How to solve this
Date: 
Message-ID: <7cy77n77k6.fsf@pbourguignon.anevia.com>
Kent M Pitman <······@nhplace.com> writes:

> Aaron Brown <········@hotmail.com> writes:
>
>> Kent M Pitman wrote:
>> 
>> > Pascal Bourguignon <····@informatimago.com> writes:
>> 
>> >> Using PROGV might be problematic, if the expression calls
>> >> a function that uses a dynamic variable masked by PROGV
>> >> unintendedly (unprobable since dynamic variables should
>> >> be named with the *star* convention, but still possible).
>> >
>> > That would sound like a bug in PROGV.  Is there any reason
>> > to suppose PROGV binds other than the list of variables
>> > one gives it?
>> 
>> I think he just means that the caller of PROGV needs to take
>> care not to use a variable name used (dynamically) by one of
>> the functions called during PROGV.

That's what I meant, yes.  


> Well, in that case, you mean "unless it's appropriate to do that."
>
> (defun foo (bindings form)
>   (with-output-to-string (*standard-output*)
>     (progv (mapcar #'first  bindings)
>            (mapcar #'second bindings)
>       (eval form))))
>
> (let ((*print-circle* t))
>   (foo '((*print-length* 3))
>        '(prin1 '(#1=(a . #1#) b c d))))
> => "(#1=(A . #1#) B C ...)"
>
> Here the result relies [I allege correctly] on special values from 
> the given arguments, the FOO function, and FOO's caller.
>
> Then again, it's correct because it does what I intended.  Special
> variables are like that--they are correct when bound at appropriate
> times and incorrect when bound at the wrong times. :)


Yes, it's a question of specification of FOO, shall it bind lexically
or dynamically the given variables?  

-- 
__Pascal Bourguignon__