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.
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
······@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.
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
······@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
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
> 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
·······@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__
·······@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)))
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..
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..
??>> 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?
"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__
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.
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.
·······@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.
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?
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/
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. :)
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__