Re: Does macros evaluates its arguments before?
Dear Michal, You and others explain me how Clojure (or Common Lisp) handles my code. Very detailed and thoroughly. I want to draw attention to another point: The documentation says that the macro function is called with the arguments unevaluated. So I write code for that function on that assumption. And when I run this code the arguments being evaluated. It does not matter why or how and when! They mustn't evaluated never in that case in accordance with the documentation! That is the question! Because the unevaluated arguments is an important feature that allows you to expand the language using macros. On 28 сен, 00:35, Michał Marczyk michal.marc...@gmail.com wrote: Hi Ru, let's input your macro definition at the REPL: user (defmacro infix [e] `(let [[x# f# y#] ~e] (f# x# y#))) #'user/infix So far so good. Now let's try use it in a function: user (defn foo [] (infix (5 + 4))) #'user/foo Well now -- it compiled! So, there's no exception being thrown when the macro is expanded at compile time; otherwise foo would not have compiled. How about calling foo? user (foo) ; Evaluation aborted. user *e #ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn There's your exception: at runtime. By this time there is no trace of your macro in the running code (you could undefine it -- by saying (ns-unmap 'user 'infix) -- and this would have no effect on foo). Once again: (5 + 4) *is not evaluated when the macro is expanded*. It is only evaluated at runtime -- and only then does it explode, as expected. The key point is that a macro is just a function called upon by the compiler to transform your program prior to it being compiled into JVM bytecode (in the case of Clojure, or perhaps native code in the case of some Common Lisp implementations and execution by the interpreter in interpreted Lisps); if it generates erroneous code (like this version of infix!), that erroneous code will be compiled by the compiler and eventually explode when you run it -- an unpleasant occurrence completely distinct from a macro-expansion-time exception. Sincerely, Michał -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
On Wed, Sep 28, 2011 at 2:27 PM, ru soro...@oogis.ru wrote: The documentation says that the macro function is called with the arguments unevaluated. So I write code for that function on that assumption. And when I run this code the arguments being evaluated. It does not matter why or how and when! They mustn't evaluated never in that case in accordance with the documentation! That is the question! Because the unevaluated arguments is an important feature that allows you to expand the language using macros. Let's put it this way - you misunderstood the documentation. What the documentation says is correct and defmacro behaves as advertised. The arguments are _never_ evaluated when they are _passed_ to the macro, but that doesn't mean they can never be evaluated inside the macro no matter what you do. In case of macros, the developer is (that is, you are) in charge of _when_ do evaluate the arguments; and you did that when you typed in ~e inside the `let` binding. It was your choice and none can do anything about it. Regards, BG -- Baishampayan Ghose b.ghose at gmail.com -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
If the macro arguments are evaluated, the macro does not need to expand the language. All you can do with functions: (eval-some-code '(.. some code here ..)) Even VisualBasic can do this: eval_some_code .. some code here .. On 28 сен, 12:57, ru soro...@oogis.ru wrote: Dear Michal, You and others explain me how Clojure (or Common Lisp) handles my code. Very detailed and thoroughly. I want to draw attention to another point: The documentation says that the macro function is called with the arguments unevaluated. So I write code for that function on that assumption. And when I run this code the arguments being evaluated. It does not matter why or how and when! They mustn't evaluated never in that case in accordance with the documentation! That is the question! Because the unevaluated arguments is an important feature that allows you to expand the language using macros. On 28 сен, 00:35, Michał Marczyk michal.marc...@gmail.com wrote: Hi Ru, let's input your macro definition at the REPL: user (defmacro infix [e] `(let [[x# f# y#] ~e] (f# x# y#))) #'user/infix So far so good. Now let's try use it in a function: user (defn foo [] (infix (5 + 4))) #'user/foo Well now -- it compiled! So, there's no exception being thrown when the macro is expanded at compile time; otherwise foo would not have compiled. How about calling foo? user (foo) ; Evaluation aborted. user *e #ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn There's your exception: at runtime. By this time there is no trace of your macro in the running code (you could undefine it -- by saying (ns-unmap 'user 'infix) -- and this would have no effect on foo). Once again: (5 + 4) *is not evaluated when the macro is expanded*. It is only evaluated at runtime -- and only then does it explode, as expected. The key point is that a macro is just a function called upon by the compiler to transform your program prior to it being compiled into JVM bytecode (in the case of Clojure, or perhaps native code in the case of some Common Lisp implementations and execution by the interpreter in interpreted Lisps); if it generates erroneous code (like this version of infix!), that erroneous code will be compiled by the compiler and eventually explode when you run it -- an unpleasant occurrence completely distinct from a macro-expansion-time exception. Sincerely, Michał -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
On Wed, Sep 28, 2011 at 2:39 PM, ru soro...@oogis.ru wrote: If the macro arguments are evaluated, the macro does not need to expand the language. All you can do with functions: (eval-some-code '(.. some code here ..)) Even VisualBasic can do this: eval_some_code .. some code here .. Try writing an `or` and `if` statement in Visual Basic / your favourite language and share it with us :-) Regards, BG -- Baishampayan Ghose b.ghose at gmail.com -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
You know, in many Lisps let is a macro too. In Clojure it expands to the special form let* (an implementation detail); a Scheme implementation might implement it as ((lambda (binding-symbol ...) expr . exprs) binding-val ...). Now, would you expect the following to return (inc x) -- a list of two symbols -- or 2? (let [x 1] (inc x)) There's no promise arguments passed to macros will *never* be evaluated, that would make no sense at all. They're just not being evaluated at compile time. Sincerely, Michał -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
Baishampayan! Thank you very much! Your explanation is best. At last I understand my gap in understanding of the situation. Sincerely, Ru On 28 сен, 13:06, Baishampayan Ghose b.gh...@gmail.com wrote: On Wed, Sep 28, 2011 at 2:27 PM, ru soro...@oogis.ru wrote: The documentation says that the macro function is called with the arguments unevaluated. So I write code for that function on that assumption. And when I run this code the arguments being evaluated. It does not matter why or how and when! They mustn't evaluated never in that case in accordance with the documentation! That is the question! Because the unevaluated arguments is an important feature that allows you to expand the language using macros. Let's put it this way - you misunderstood the documentation. What the documentation says is correct and defmacro behaves as advertised. The arguments are _never_ evaluated when they are _passed_ to the macro, but that doesn't mean they can never be evaluated inside the macro no matter what you do. In case of macros, the developer is (that is, you are) in charge of _when_ do evaluate the arguments; and you did that when you typed in ~e inside the `let` binding. It was your choice and none can do anything about it. Regards, BG -- Baishampayan Ghose b.ghose at gmail.com -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
2011/9/28 ru soro...@oogis.ru: Thank you very much! Your explanation is best. At last I understand my gap in understanding of the situation. Extremely happy to to have helped you, Ru. Please don't hesitate to email us if you have more questions. Regards, BG -- Baishampayan Ghose b.ghose at gmail.com -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
On 28 сен, 13:13, Michał Marczyk michal.marc...@gmail.com wrote: You know, in many Lisps let is a macro too. In Clojure it expands to the special form let* (an implementation detail); a Scheme implementation might implement it as ((lambda (binding-symbol ...) expr . exprs) binding-val ...). Now, would you expect the following to return (inc x) -- a list of two symbols -- or 2? (let [x 1] (inc x)) There's no promise arguments passed to macros will *never* be evaluated, that would make no sense at all. They're just not being evaluated at compile time. Only Baishampayan explained me at last that evaluation done under MY control :) Sincerely, Michał -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
You are right, Alan! And in this case Closure compiler behave itself also unpredictably and quite the contrary: Where it must evaluate a symbol (like in this case), it doesn't. Where it mustn't evaluate a symbol (argument of macro), it does. So, need to have comprehensive and profound knowledge about its behavior, including subtleties, even in very simple use cases. Your explanation show this quite clearly. On 27 сен, 02:42, Alan Malloy a...@malloys.org wrote: I suspect your repl was stale, since this doesn't work at all. By an amusing coincidence, though, it doesn't break, just returns the wrong answer: user= (defmacro infix [e] `(let [[x# f# y#] '~e] (f# x# y#))) #'user/infix user= (infix (5 + 4)) 4 That is, the *symbol* +, not the function +, is called as a function. Symbols act like keywords in that they look themselves up in maps. The map 5 does not contain the symbol '+, so the not-found value of 4 is returned. On Sep 26, 10:22 am, ru soro...@oogis.ru wrote: Thanks to all! With your help I have found the solution that coincide with Bronsa's (my special respect to Bronsa): user= (defmacro infix [e] `(let [[x# f# y#] '~e] (f# x# y#))) #'user/infix user= (infix (5 + 4)) 9 But, this solution seems to me awkward and showing that Clojure compiler does not handling quite strictly language specification requirements. I.e., this single quote compiler should substitute itself to fulfill requirement of unevaluation arguments of macro. Sincerely, Ru -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
And in this case Closure compiler behave itself also unpredictably and quite the contrary: Where it must evaluate a symbol (like in this case), it doesn't. Symbols need to be namespace resolved in order to be evaluated properly. This is something you need to be aware of, but it is not unpredictable or contrary to any documentation. And again, in this case, the evaluation of the plus symbol does not happen at macro expansion, it happens at run time. The behavior here is the same inside of and outside of a macro: user= (def e '(5 + 2)) #'user/e user= (eval `((nth '~e 1) (nth e 0) (nth e 2))) 2 user= (eval `((nth (list ~@e) 1) (nth e 0) (nth e 2))) 7 Where it mustn't evaluate a symbol (argument of macro), it does. This has already been shown in several responses, the argument is not being evaluated in macro expansion, it is being evaluated at runtime. Using macroexpand will help you to see what the expanded forms look like and what namespace symbols are resolved to. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
On 27 сен, 16:45, Mark Rathwell mark.rathw...@gmail.com wrote: And in this case Closure compiler behave itself also unpredictably and quite the contrary: Where it must evaluate a symbol (like in this case), it doesn't. Symbols need to be namespace resolved in order to be evaluated properly. This is something you need to be aware of, but it is not unpredictable or contrary to any documentation. And again, in this case, the evaluation of the plus symbol does not happen at macro expansion, it happens at run time. The behavior here is the same inside of and outside of a macro: user= (def e '(5 + 2)) #'user/e user= (eval `((nth '~e 1) (nth e 0) (nth e 2))) 2 user= (eval `((nth (list ~@e) 1) (nth e 0) (nth e 2))) 7 Where it mustn't evaluate a symbol (argument of macro), it does. This has already been shown in several responses, the argument is not being evaluated in macro expansion, it is being evaluated at runtime. In this point I want to cite Clojure doc, that say nothing about expansion and runtime, once more: ..If the operator of a call is a symbol that names a global var that is a macro function, that macro function is called and is passed the /unevaluated/ operand forms. So, when I write the macro function body, I expect that operands are unevaluated when my body is executed to get an expanded form (finally expanded), that will be executed afterward to get a result (at runtime, as you say). But this is not the case in the very first example: user= (defmacro infix [e] `(let [[x# f# y#] ~e] (f# x# y#))) #'user/infix user= (infix (5 + 4)) java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn (NO_SOURCE_FILE:0) I insist that expansion is not quite correct. Am I right? Using macroexpand will help you to see what the expanded forms look like and what namespace symbols are resolved to. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
2011/9/27 ru soro...@oogis.ru All, I give up! :) You're macro will still be incorrect in CLISP, SBCL, CMUCL, Clozure MCL, ABCL, MIT Scheme, Gambit Scheme, Chicken, Ikarus, Racket etc. ;) David -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
It seems you are enjoying spewing accusations at Clojure, but if your goal is to actually get something done, you would get a lot more out of this discussion if your attitude were Huh, I expected x but see y! Is that a bug or am I wrong? Oh I see, it's not a bug? I still don't understand, please explain. You are behaving like OMG this is such a bug how come nobody but me sees this obvious error in Clojure? when respected and experienced members of the community try to help you, an apparent novice, with an interesting topic. This does nothing to advance your knowledge, and frustrates the people who would otherwise be eager to help. On Sep 27, 2:13 am, ru soro...@oogis.ru wrote: You are right, Alan! And in this case Closure compiler behave itself also unpredictably and quite the contrary: Where it must evaluate a symbol (like in this case), it doesn't. Where it mustn't evaluate a symbol (argument of macro), it does. So, need to have comprehensive and profound knowledge about its behavior, including subtleties, even in very simple use cases. Your explanation show this quite clearly. On 27 сен, 02:42, Alan Malloy a...@malloys.org wrote: I suspect your repl was stale, since this doesn't work at all. By an amusing coincidence, though, it doesn't break, just returns the wrong answer: user= (defmacro infix [e] `(let [[x# f# y#] '~e] (f# x# y#))) #'user/infix user= (infix (5 + 4)) 4 That is, the *symbol* +, not the function +, is called as a function. Symbols act like keywords in that they look themselves up in maps. The map 5 does not contain the symbol '+, so the not-found value of 4 is returned. On Sep 26, 10:22 am, ru soro...@oogis.ru wrote: Thanks to all! With your help I have found the solution that coincide with Bronsa's (my special respect to Bronsa): user= (defmacro infix [e] `(let [[x# f# y#] '~e] (f# x# y#))) #'user/infix user= (infix (5 + 4)) 9 But, this solution seems to me awkward and showing that Clojure compiler does not handling quite strictly language specification requirements. I.e., this single quote compiler should substitute itself to fulfill requirement of unevaluation arguments of macro. Sincerely, Ru -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
Alan, Please forgive me. I am very sorry. May be my English is not so good. Simply, I stupidly kept the idea that macro differs from the function in that is evaluated twice, the first time with the unevaluated arguments. When I saw that even in Lisp it is not the case, I gave up : ( Sincerely, Ru On 27 сен, 23:23, Alan Malloy a...@malloys.org wrote: It seems you are enjoying spewing accusations at Clojure, but if your goal is to actually get something done, you would get a lot more out of this discussion if your attitude were Huh, I expected x but see y! Is that a bug or am I wrong? Oh I see, it's not a bug? I still don't understand, please explain. You are behaving like OMG this is such a bug how come nobody but me sees this obvious error in Clojure? when respected and experienced members of the community try to help you, an apparent novice, with an interesting topic. This does nothing to advance your knowledge, and frustrates the people who would otherwise be eager to help. On Sep 27, 2:13 am, ru soro...@oogis.ru wrote: You are right, Alan! And in this case Closure compiler behave itself also unpredictably and quite the contrary: Where it must evaluate a symbol (like in this case), it doesn't. Where it mustn't evaluate a symbol (argument of macro), it does. So, need to have comprehensive and profound knowledge about its behavior, including subtleties, even in very simple use cases. Your explanation show this quite clearly. On 27 сен, 02:42, Alan Malloy a...@malloys.org wrote: I suspect your repl was stale, since this doesn't work at all. By an amusing coincidence, though, it doesn't break, just returns the wrong answer: user= (defmacro infix [e] `(let [[x# f# y#] '~e] (f# x# y#))) #'user/infix user= (infix (5 + 4)) 4 That is, the *symbol* +, not the function +, is called as a function. Symbols act like keywords in that they look themselves up in maps. The map 5 does not contain the symbol '+, so the not-found value of 4 is returned. On Sep 26, 10:22 am, ru soro...@oogis.ru wrote: Thanks to all! With your help I have found the solution that coincide with Bronsa's (my special respect to Bronsa): user= (defmacro infix [e] `(let [[x# f# y#] '~e] (f# x# y#))) #'user/infix user= (infix (5 + 4)) 9 But, this solution seems to me awkward and showing that Clojure compiler does not handling quite strictly language specification requirements. I.e., this single quote compiler should substitute itself to fulfill requirement of unevaluation arguments of macro. Sincerely, Ru -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
Hi Ru, let's input your macro definition at the REPL: user (defmacro infix [e] `(let [[x# f# y#] ~e] (f# x# y#))) #'user/infix So far so good. Now let's try use it in a function: user (defn foo [] (infix (5 + 4))) #'user/foo Well now -- it compiled! So, there's no exception being thrown when the macro is expanded at compile time; otherwise foo would not have compiled. How about calling foo? user (foo) ; Evaluation aborted. user *e #ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn There's your exception: at runtime. By this time there is no trace of your macro in the running code (you could undefine it -- by saying (ns-unmap 'user 'infix) -- and this would have no effect on foo). Once again: (5 + 4) *is not evaluated when the macro is expanded*. It is only evaluated at runtime -- and only then does it explode, as expected. The key point is that a macro is just a function called upon by the compiler to transform your program prior to it being compiled into JVM bytecode (in the case of Clojure, or perhaps native code in the case of some Common Lisp implementations and execution by the interpreter in interpreted Lisps); if it generates erroneous code (like this version of infix!), that erroneous code will be compiled by the compiler and eventually explode when you run it -- an unpleasant occurrence completely distinct from a macro-expansion-time exception. Sincerely, Michał -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
This is quite amusing since the first reply to the original post already provided the correct answer :) On Sep 28, 2011 6:05 AM, Michał Marczyk michal.marc...@gmail.com wrote: Hi Ru, let's input your macro definition at the REPL: user (defmacro infix [e] `(let [[x# f# y#] ~e] (f# x# y#))) #'user/infix So far so good. Now let's try use it in a function: user (defn foo [] (infix (5 + 4))) #'user/foo Well now -- it compiled! So, there's no exception being thrown when the macro is expanded at compile time; otherwise foo would not have compiled. How about calling foo? user (foo) ; Evaluation aborted. user *e #ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn There's your exception: at runtime. By this time there is no trace of your macro in the running code (you could undefine it -- by saying (ns-unmap 'user 'infix) -- and this would have no effect on foo). Once again: (5 + 4) *is not evaluated when the macro is expanded*. It is only evaluated at runtime -- and only then does it explode, as expected. The key point is that a macro is just a function called upon by the compiler to transform your program prior to it being compiled into JVM bytecode (in the case of Clojure, or perhaps native code in the case of some Common Lisp implementations and execution by the interpreter in interpreted Lisps); if it generates erroneous code (like this version of infix!), that erroneous code will be compiled by the compiler and eventually explode when you run it -- an unpleasant occurrence completely distinct from a macro-expansion-time exception. Sincerely, Michał -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Does macros evaluates its arguments before?
Hi dear clojurians! From Clojure documentation (http://clojure.org/evaluation): ..If the operator of a call is a symbol that names a global var that is a macro function, that macro function is called and is passed the /unevaluated/ operand forms. But: ru@ru-desktop ~/clojure/clojure-1.2.1 $ java -cp clojure.jar clojure.main Clojure 1.2.1 user= (defmacro infix [e] `(let [[x# f# y#] ~e] (f# x# y#))) #'user/infix user= (infix [5 + 4]) 9 user= (infix (5 + 4)) java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn (NO_SOURCE_FILE:0) user= So, it is tried to evaluate the form (5 + 4). Is not it? As I remember from Lisp, UNevaluation of arguments is one of the main properties of macros. Am I right? Thank you in advance for the any explanations. Sincerely, Ru -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
Try: (defmacro infix [[x f y]] `(~f ~x ~y))) On Mon, Sep 26, 2011 at 9:57 AM, Ruslan Sorokin soro...@oogis.ru wrote: ** Hi dear clojurians! From Clojure documentation (http://clojure.org/evaluation): ..If the operator of a call is a symbol that names a global var that is a macro function, that macro function is called and is passed the * unevaluated* operand forms. But: ru@ru-desktop ~/clojure/clojure-1.2.1 $ java -cp clojure.jar clojure.main Clojure 1.2.1 user= (defmacro infix [e] `(let [[x# f# y#] ~e] (f# x# y#))) #'user/infix user= (infix [5 + 4]) 9 user= (infix (5 + 4)) java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn (NO_SOURCE_FILE:0) user= So, it is tried to evaluate the form (5 + 4). Is not it? As I remember from Lisp, UNevaluation of arguments is one of the main properties of macros. Am I right? Thank you in advance for the any explanations. Sincerely, Ru -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
user= (defmacro infix [[x f y]] `(~f ~x ~y)) #'user/infix user= (infix (5 + 4)) 9 Ok, this is working! But, what's the difference? -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
ru soro...@oogis.ru writes: user= (defmacro infix [[x f y]] `(~f ~x ~y)) #'user/infix user= (infix (5 + 4)) 9 Ok, this is working! But, what's the difference? Your code: user= (defmacro infix [e] `(let [[x# f# y#] ~e] (f# x# y#))) The ~e evaluates the given form, which looks like a function but is not. Bye, Tassilo -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
One very important difference is that your original version creates three variables on-the-fly. It then copies the input into these variables, just to perform a simple addition. This could have a fairly severe performance penalty in a inner loop. David's version doesn't suffer from this. The performance hit is a onetime compile cost, from there it will run just as fast as prefix notation. As to the actual macro syntax errors you had, I haven't a clue... Timothy On Mon, Sep 26, 2011 at 9:11 AM, ru soro...@oogis.ru wrote: user= (defmacro infix [[x f y]] `(~f ~x ~y)) #'user/infix user= (infix (5 + 4)) 9 Ok, this is working! But, what's the difference? -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- “One of the main causes of the fall of the Roman Empire was that–lacking zero–they had no way to indicate successful termination of their C programs.” (Robert Firth) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
Timothy! Thank you for the explanation. I understand quite well about performance. I do'nt understand why it evaluates argument (5 + 4) during expansion in my case? Ru -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
Well, Tassilo. That's exactly means evaluation of argument that's contradict to mentioned above documentation! On 26 сен, 18:18, Tassilo Horn tass...@member.fsf.org wrote: ru soro...@oogis.ru writes: user= (defmacro infix [[x f y]] `(~f ~x ~y)) #'user/infix user= (infix (5 + 4)) 9 Ok, this is working! But, what's the difference? Your code: user= (defmacro infix [e] `(let [[x# f# y#] ~e] (f# x# y#))) The ~e evaluates the given form, which looks like a function but is not. Bye, Tassilo -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
The argument isn't being evaluated during macro expansion, it's being evaluated when the expanded form is evaluated by the repl: user= (macroexpand '(infix (5 + 4))) (let* [vec__590 (5 + 4) x__574__auto__ (clojure.core/nth vec__590 0 nil) f__575__auto__ (clojure.core/nth vec__590 1 nil) y__576__auto__ (clojure.core/nth vec__590 2 nil)] (f__575__auto__ x__574__auto__ y__576__auto__)) user= (let* [vec__590 (5 + 4) x__574__auto__ (clojure.core/nth vec__590 0 nil) f__575__auto__ (clojure.core/nth vec__590 1 nil) y__576__auto__ (clojure.core/nth vec__590 2 nil)] (f__575__auto__ x__574__auto__ y__576__auto__)) java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn (NO_SOURCE_FILE:0) Make sense? Dave On Mon, Sep 26, 2011 at 10:26 AM, ru soro...@oogis.ru wrote: Timothy! Thank you for the explanation. I understand quite well about performance. I do'nt understand why it evaluates argument (5 + 4) during expansion in my case? Ru -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
2011/9/26 ru soro...@oogis.ru That's exactly means evaluation of argument that's contradict to mentioned above documentation! On 26 сен, 18:18, Tassilo Horn tass...@member.fsf.org wrote: Ok, this is working! But, what's the difference? Your code: user= (defmacro infix [e] `(let [[x# f# y#] ~e] (f# x# y#))) The ~e evaluates the given form, which looks like a function but is not. In other words, your version of infix expands to approximately: (let [x_1 f_2 y_3] (5 + 4)] (f_2 x_1 y_3)) and the destructuring in let is what causes the problem at runtime. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
Use macroexpand-1 to expand a call to this macro, and it should be clear what is going on. The expanded code tries to call 5 as a function. What you are probably trying to do here is make (5 + 2) a list, not a function call. ;; (note the unquote splicing of e) (defmacro infix [e] `(let [[x# f# y#] (list ~@e)] (f# x# y#))) 2011/9/26 Aaron Cohen aa...@assonance.org: 2011/9/26 ru soro...@oogis.ru That's exactly means evaluation of argument that's contradict to mentioned above documentation! On 26 сен, 18:18, Tassilo Horn tass...@member.fsf.org wrote: Ok, this is working! But, what's the difference? Your code: user= (defmacro infix [e] `(let [[x# f# y#] ~e] (f# x# y#))) The ~e evaluates the given form, which looks like a function but is not. In other words, your version of infix expands to approximately: (let [x_1 f_2 y_3] (5 + 4)] (f_2 x_1 y_3)) and the destructuring in let is what causes the problem at runtime. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
or simply replace ~e with '~e -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
Noo, then you can't do, for example, (let [x 1] (infix (x + 1))). On Sep 26, 8:34 am, Bronsa brobro...@gmail.com wrote: or simply replace ~e with '~e -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
Thanks to all! With your help I have found the solution that coincide with Bronsa's (my special respect to Bronsa): user= (defmacro infix [e] `(let [[x# f# y#] '~e] (f# x# y#))) #'user/infix user= (infix (5 + 4)) 9 But, this solution seems to me awkward and showing that Clojure compiler does not handling quite strictly language specification requirements. I.e., this single quote compiler should substitute itself to fulfill requirement of unevaluation arguments of macro. Sincerely, Ru -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
ru soro...@oogis.ru writes: Hi Ru, With your help I have found the solution that coincide with Bronsa's (my special respect to Bronsa): user= (defmacro infix [e] `(let [[x# f# y#] '~e] (f# x# y#))) #'user/infix user= (infix (5 + 4)) 9 Alan already told you that this solution is not really good. It works only if the operands are number literals. But, this solution seems to me awkward and showing that Clojure compiler does not handling quite strictly language specification requirements. I.e., this single quote compiler should substitute itself to fulfill requirement of unevaluation arguments of macro. The macro doesn't evaluate its arguments, but it creates an expansion that looks roughly like (let [[x op y] (5 + 6)] ...). In this macro-generated code, (5 + 4) is evaluated at runtime, and then the exception is thrown. So its not that defmacro evals its args, but your macro creates code that blows up at runtime. Bye, Tassilo -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
Hi again, just for the fun of doing it, here's a recursive version of infix: --8---cut here---start-8--- (defmacro infix [x] (if (sequential? x) `(~(second x) (infix ~(first x)) (infix ~(nth x 2))) x)) --8---cut here---end---8--- That works fine no matter if you use vectors or lists, because I simply pick the operator and the 2 args manually. I think it's educational to follow a complete macroexpansion process. Here's an example: --8---cut here---start-8--- (let [a 3, b 2, c 3] (infix ((a * b) + [c * c]))) Expands to: (let* [a 3 b 2 c 3] (+ (infix (a * b)) (infix [c * c]))) Expands to: (let* [a 3 b 2 c 3] (+ (* (infix a) (infix b)) (infix [c * c]))) Expands to: (let* [a 3 b 2 c 3] (+ (* a (infix b)) (infix [c * c]))) Expands to: (let* [a 3 b 2 c 3] (+ (* a b) (infix [c * c]))) Expands to: (let* [a 3 b 2 c 3] (+ (* a b) (* (infix c) (infix c Expands to: (let* [a 3 b 2 c 3] (+ (* a b) (* c (infix c Finally, expands to: (let* [a 3 b 2 c 3] (+ (* a b) (* c c))) --8---cut here---end---8--- HTH, Tassilo -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
Tassilo! Thank you very much, really grand job! By the way, I was preparing this example for students. So, you've done all the work for me! :) Best regards, Ru On 26 сен, 22:31, Tassilo Horn tass...@member.fsf.org wrote: Hi again, just for the fun of doing it, here's a recursive version of infix: --8---cut here---start-8--- (defmacro infix [x] (if (sequential? x) `(~(second x) (infix ~(first x)) (infix ~(nth x 2))) x)) --8---cut here---end---8--- That works fine no matter if you use vectors or lists, because I simply pick the operator and the 2 args manually. I think it's educational to follow a complete macroexpansion process. Here's an example: --8---cut here---start-8--- (let [a 3, b 2, c 3] (infix ((a * b) + [c * c]))) Expands to: (let* [a 3 b 2 c 3] (+ (infix (a * b)) (infix [c * c]))) Expands to: (let* [a 3 b 2 c 3] (+ (* (infix a) (infix b)) (infix [c * c]))) Expands to: (let* [a 3 b 2 c 3] (+ (* a (infix b)) (infix [c * c]))) Expands to: (let* [a 3 b 2 c 3] (+ (* a b) (infix [c * c]))) Expands to: (let* [a 3 b 2 c 3] (+ (* a b) (* (infix c) (infix c Expands to: (let* [a 3 b 2 c 3] (+ (* a b) (* c (infix c Finally, expands to: (let* [a 3 b 2 c 3] (+ (* a b) (* c c))) --8---cut here---end---8--- HTH, Tassilo -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
ru soro...@oogis.ru writes: Hi Ru, Thank you very much, really grand job! I'm glad to have helped. By the way, I was preparing this example for students. So, you've done all the work for me! :) The bill will arrive anytime soon. :-) Bye, Tassilo -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
oh, that's right 2011/9/26 Alan Malloy a...@malloys.org Noo, then you can't do, for example, (let [x 1] (infix (x + 1))). On Sep 26, 8:34 am, Bronsa brobro...@gmail.com wrote: or simply replace ~e with '~e -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Does macros evaluates its arguments before?
I suspect your repl was stale, since this doesn't work at all. By an amusing coincidence, though, it doesn't break, just returns the wrong answer: user= (defmacro infix [e] `(let [[x# f# y#] '~e] (f# x# y#))) #'user/infix user= (infix (5 + 4)) 4 That is, the *symbol* +, not the function +, is called as a function. Symbols act like keywords in that they look themselves up in maps. The map 5 does not contain the symbol '+, so the not-found value of 4 is returned. On Sep 26, 10:22 am, ru soro...@oogis.ru wrote: Thanks to all! With your help I have found the solution that coincide with Bronsa's (my special respect to Bronsa): user= (defmacro infix [e] `(let [[x# f# y#] '~e] (f# x# y#))) #'user/infix user= (infix (5 + 4)) 9 But, this solution seems to me awkward and showing that Clojure compiler does not handling quite strictly language specification requirements. I.e., this single quote compiler should substitute itself to fulfill requirement of unevaluation arguments of macro. Sincerely, Ru -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en