Re: [julia-users] Macros generating Functions
I think I was channeling this line from the Style Guide section of the manual when I made my earlier comment on preferring functions: Don’t overuse macros Be aware of when a macro could really be a function instead. [then a sensible warning about not using @eval inside a macro] But I suppose this does not mean you should always use the function alternative, only that you should consider the options. I agree that macros are an amazing tool and should not be shied away from. In this particular case I initially thought a function would be more suited, but now I think it might go either way depending on the intended use. Tom On Tuesday, 2 June 2015 02:43:12 UTC+10, Josh Langsfeld wrote: You're right, and the manual even talks about the using eval to prevent code reuse. I guess it also depends on whether you are creating a bunch of functions in a one-time shot, or exposing a function creation interface that will be called as needed. Your example seems to be a case of the former, whereas I think macros are a better option for the latter (provided there is no run-time data needed for function creation). As an example there's @enum ( https://github.com/JuliaLang/julia/blob/master/base/Enums.jl#L26), which generates multiple functions, but is only called by users. But I still want to emphasize that I think the advice to always use functions over macros is not correct. Macros are valuable tools for pure code manipulation / generation and are also safer than functions because they don't use runtime data. I don't think people should be told to shy away from them. Thanks, Josh On Sunday, May 31, 2015 at 8:49:09 PM UTC-4, Tom Lee wrote: I'll concede that if you know the function name at runtime, Mauro's solution may be a little cleaner, especially if it will be called a lot. There are plenty of examples in Base of @eval being used to define functions, such as lines 11-18 here: https://github.com/JuliaLang/julia/blob/861f02712eb4b41c08fed3f21c5a4206b8d669bc/base/int.jl I've copied this pattern in my own code and found it extremely convenient. I can't think of any examples of macros in Base which define functions. Cheers, Tom On Monday, 1 June 2015 02:35:28 UTC+10, Josh Langsfeld wrote: I don't think this is correct actually. With Julia's metaprogramming abilities, all macros could be handled by runtime functions. The rule I follow is that macros should be used when some processing needs to be done at compile time / source-processing time. Usually, that's exactly when you want to programmatically generate code for a function. In particular, I thought it was widely regarded that calling on 'eval' was a sign you should consider using macros for your problem if possible. So I think the first reply from Mauro is the most Julian solution. Unless there's something really weird like the function name isn't known until runtime, in which case no macro can work. On Sunday, May 31, 2015 at 5:48:41 AM UTC-7, Tom Lee wrote: ... Also, I should clarify that when I wrote My understanding is that you should never use a macro if you can easily write an equivalent function I meant you should not create a new macro to do something that can just as easily be done by a function - not that existing macros like @eval should be avoided.
Re: [julia-users] Macros generating Functions
You're right, and the manual even talks about the using eval to prevent code reuse. I guess it also depends on whether you are creating a bunch of functions in a one-time shot, or exposing a function creation interface that will be called as needed. Your example seems to be a case of the former, whereas I think macros are a better option for the latter (provided there is no run-time data needed for function creation). As an example there's @enum (https://github.com/JuliaLang/julia/blob/master/base/Enums.jl#L26), which generates multiple functions, but is only called by users. But I still want to emphasize that I think the advice to always use functions over macros is not correct. Macros are valuable tools for pure code manipulation / generation and are also safer than functions because they don't use runtime data. I don't think people should be told to shy away from them. Thanks, Josh On Sunday, May 31, 2015 at 8:49:09 PM UTC-4, Tom Lee wrote: I'll concede that if you know the function name at runtime, Mauro's solution may be a little cleaner, especially if it will be called a lot. There are plenty of examples in Base of @eval being used to define functions, such as lines 11-18 here: https://github.com/JuliaLang/julia/blob/861f02712eb4b41c08fed3f21c5a4206b8d669bc/base/int.jl I've copied this pattern in my own code and found it extremely convenient. I can't think of any examples of macros in Base which define functions. Cheers, Tom On Monday, 1 June 2015 02:35:28 UTC+10, Josh Langsfeld wrote: I don't think this is correct actually. With Julia's metaprogramming abilities, all macros could be handled by runtime functions. The rule I follow is that macros should be used when some processing needs to be done at compile time / source-processing time. Usually, that's exactly when you want to programmatically generate code for a function. In particular, I thought it was widely regarded that calling on 'eval' was a sign you should consider using macros for your problem if possible. So I think the first reply from Mauro is the most Julian solution. Unless there's something really weird like the function name isn't known until runtime, in which case no macro can work. On Sunday, May 31, 2015 at 5:48:41 AM UTC-7, Tom Lee wrote: ... Also, I should clarify that when I wrote My understanding is that you should never use a macro if you can easily write an equivalent function I meant you should not create a new macro to do something that can just as easily be done by a function - not that existing macros like @eval should be avoided.
Re: [julia-users] Macros generating Functions
On Sun, May 31, 2015 at 8:48 AM, Tom Lee m...@tomlee.id.au wrote: No, in that example you create an anonymous function. I'm not certain on the semantics, but n effectively points to this nameless function. Anonymous functions are not as fast as generic ones (at least in 0.3, at least sometimes) and you cannot add new methods to them for multiple dispatch (as far as I know). Also, I should clarify that when I wrote My understanding is that you should never use a macro if you can easily write an equivalent function I meant you should not create a new macro to do something that can just as easily be done by a function - not that existing macros like @eval should be avoided. On Sunday, 31 May 2015 21:45:46 UTC+10, Kevin Squire wrote: Actually, it's name is n: julia function getfn() return function(); 1; end end getfn (generic function with 1 method) julia const n = getfn() (anonymous function) Well, it's anonymous as shown here. If you just want to give that function a name (i.e. make it a generic function). ```julia julia function getfn() f() = 1 end getfn (generic function with 1 method) julia getfn() f (generic function with 1 method) ``` This function is defined in the `getfn()` local scope and is not extending a global function with the same name nor is it bound to a global function for extending. Unless you want to define a closure, @eval is probably want you want. julia n() 1 On Sat, May 30, 2015 at 5:09 PM, David P. Sanders dpsa...@gmail.com wrote: El domingo, 31 de mayo de 2015, 0:37:45 (UTC+2), Jameson escribió: But @eval is still a macro, so it is even better to rewrite this without that: function getfn() return function(); 1; end end const n = getfn() This does not give quite the same answer, though, since the function does not have a name. Is there a way to specify the name of a generated function like this? On Sat, May 30, 2015 at 2:30 PM David Gold david@gmail.com wrote: Something to note about Tom's method is that the name function must be passed to gf as a symbol, unlike in the case of a macro. However, in most cases this slight difference probably will not warrant a macro. On Friday, May 29, 2015 at 8:58:56 PM UTC-4, Tom Lee wrote: You don't need to use a macro, a function can do this: julia function gf(n::Symbol = gensym()) @eval function $(n)() 1 end end I've also made the n argument optional, with gensym creating a unique name by default - the newly defined function is returned by gf, so you don't necessarily need to know its name. And of course if you give gf additional arguments you can programatically construct expressions based those and easily $ them into the @eval block. It's all very awesome. But the point is a macro probably isn't appropriate for this type of thing. My understanding is that you should never use a macro if you can easily write an equivalent function. Cheers, Tom On Thursday, 28 May 2015 23:26:39 UTC+10, Mauro wrote: Like this: julia macro gf(n) quote function $(esc(n))() 1 end end end julia @gf foo foo (generic function with 1 method) julia foo() 1 On Thu, 2015-05-28 at 12:06, Vasudha Khandelwal vasudhakh...@gmail.com wrote: Can I use macros to generate functions with names passed as argument to the macro?
Re: [julia-users] Macros generating Functions
I'll concede that if you know the function name at runtime, Mauro's solution may be a little cleaner, especially if it will be called a lot. There are plenty of examples in Base of @eval being used to define functions, such as lines 11-18 here: https://github.com/JuliaLang/julia/blob/861f02712eb4b41c08fed3f21c5a4206b8d669bc/base/int.jl I've copied this pattern in my own code and found it extremely convenient. I can't think of any examples of macros in Base which define functions. Cheers, Tom On Monday, 1 June 2015 02:35:28 UTC+10, Josh Langsfeld wrote: I don't think this is correct actually. With Julia's metaprogramming abilities, all macros could be handled by runtime functions. The rule I follow is that macros should be used when some processing needs to be done at compile time / source-processing time. Usually, that's exactly when you want to programmatically generate code for a function. In particular, I thought it was widely regarded that calling on 'eval' was a sign you should consider using macros for your problem if possible. So I think the first reply from Mauro is the most Julian solution. Unless there's something really weird like the function name isn't known until runtime, in which case no macro can work. On Sunday, May 31, 2015 at 5:48:41 AM UTC-7, Tom Lee wrote: ... Also, I should clarify that when I wrote My understanding is that you should never use a macro if you can easily write an equivalent function I meant you should not create a new macro to do something that can just as easily be done by a function - not that existing macros like @eval should be avoided.
Re: [julia-users] Macros generating Functions
Actually, it's name is n: julia function getfn() return function(); 1; end end getfn (generic function with 1 method) julia const n = getfn() (anonymous function) julia n() 1 On Sat, May 30, 2015 at 5:09 PM, David P. Sanders dpsand...@gmail.com wrote: El domingo, 31 de mayo de 2015, 0:37:45 (UTC+2), Jameson escribió: But @eval is still a macro, so it is even better to rewrite this without that: function getfn() return function(); 1; end end const n = getfn() This does not give quite the same answer, though, since the function does not have a name. Is there a way to specify the name of a generated function like this? On Sat, May 30, 2015 at 2:30 PM David Gold david@gmail.com wrote: Something to note about Tom's method is that the name function must be passed to gf as a symbol, unlike in the case of a macro. However, in most cases this slight difference probably will not warrant a macro. On Friday, May 29, 2015 at 8:58:56 PM UTC-4, Tom Lee wrote: You don't need to use a macro, a function can do this: julia function gf(n::Symbol = gensym()) @eval function $(n)() 1 end end I've also made the n argument optional, with gensym creating a unique name by default - the newly defined function is returned by gf, so you don't necessarily need to know its name. And of course if you give gf additional arguments you can programatically construct expressions based those and easily $ them into the @eval block. It's all very awesome. But the point is a macro probably isn't appropriate for this type of thing. My understanding is that you should never use a macro if you can easily write an equivalent function. Cheers, Tom On Thursday, 28 May 2015 23:26:39 UTC+10, Mauro wrote: Like this: julia macro gf(n) quote function $(esc(n))() 1 end end end julia @gf foo foo (generic function with 1 method) julia foo() 1 On Thu, 2015-05-28 at 12:06, Vasudha Khandelwal vasudhakh...@gmail.com wrote: Can I use macros to generate functions with names passed as argument to the macro?
Re: [julia-users] Macros generating Functions
No, in that example you create an anonymous function. I'm not certain on the semantics, but n effectively points to this nameless function. Anonymous functions are not as fast as generic ones (at least in 0.3, at least sometimes) and you cannot add new methods to them for multiple dispatch (as far as I know). Also, I should clarify that when I wrote My understanding is that you should never use a macro if you can easily write an equivalent function I meant you should not create a new macro to do something that can just as easily be done by a function - not that existing macros like @eval should be avoided. On Sunday, 31 May 2015 21:45:46 UTC+10, Kevin Squire wrote: Actually, it's name is n: julia function getfn() return function(); 1; end end getfn (generic function with 1 method) julia const n = getfn() (anonymous function) julia n() 1 On Sat, May 30, 2015 at 5:09 PM, David P. Sanders dpsa...@gmail.com javascript: wrote: El domingo, 31 de mayo de 2015, 0:37:45 (UTC+2), Jameson escribió: But @eval is still a macro, so it is even better to rewrite this without that: function getfn() return function(); 1; end end const n = getfn() This does not give quite the same answer, though, since the function does not have a name. Is there a way to specify the name of a generated function like this? On Sat, May 30, 2015 at 2:30 PM David Gold david@gmail.com wrote: Something to note about Tom's method is that the name function must be passed to gf as a symbol, unlike in the case of a macro. However, in most cases this slight difference probably will not warrant a macro. On Friday, May 29, 2015 at 8:58:56 PM UTC-4, Tom Lee wrote: You don't need to use a macro, a function can do this: julia function gf(n::Symbol = gensym()) @eval function $(n)() 1 end end I've also made the n argument optional, with gensym creating a unique name by default - the newly defined function is returned by gf, so you don't necessarily need to know its name. And of course if you give gf additional arguments you can programatically construct expressions based those and easily $ them into the @eval block. It's all very awesome. But the point is a macro probably isn't appropriate for this type of thing. My understanding is that you should never use a macro if you can easily write an equivalent function. Cheers, Tom On Thursday, 28 May 2015 23:26:39 UTC+10, Mauro wrote: Like this: julia macro gf(n) quote function $(esc(n))() 1 end end end julia @gf foo foo (generic function with 1 method) julia foo() 1 On Thu, 2015-05-28 at 12:06, Vasudha Khandelwal vasudhakh...@gmail.com wrote: Can I use macros to generate functions with names passed as argument to the macro?
Re: [julia-users] Macros generating Functions
But @eval is still a macro, so it is even better to rewrite this without that: function getfn() return function(); 1; end end const n = getfn() On Sat, May 30, 2015 at 2:30 PM David Gold david.gol...@gmail.com wrote: Something to note about Tom's method is that the name function must be passed to gf as a symbol, unlike in the case of a macro. However, in most cases this slight difference probably will not warrant a macro. On Friday, May 29, 2015 at 8:58:56 PM UTC-4, Tom Lee wrote: You don't need to use a macro, a function can do this: julia function gf(n::Symbol = gensym()) @eval function $(n)() 1 end end I've also made the n argument optional, with gensym creating a unique name by default - the newly defined function is returned by gf, so you don't necessarily need to know its name. And of course if you give gf additional arguments you can programatically construct expressions based those and easily $ them into the @eval block. It's all very awesome. But the point is a macro probably isn't appropriate for this type of thing. My understanding is that you should never use a macro if you can easily write an equivalent function. Cheers, Tom On Thursday, 28 May 2015 23:26:39 UTC+10, Mauro wrote: Like this: julia macro gf(n) quote function $(esc(n))() 1 end end end julia @gf foo foo (generic function with 1 method) julia foo() 1 On Thu, 2015-05-28 at 12:06, Vasudha Khandelwal vasudhakh...@gmail.com wrote: Can I use macros to generate functions with names passed as argument to the macro?
Re: [julia-users] Macros generating Functions
El domingo, 31 de mayo de 2015, 0:37:45 (UTC+2), Jameson escribió: But @eval is still a macro, so it is even better to rewrite this without that: function getfn() return function(); 1; end end const n = getfn() This does not give quite the same answer, though, since the function does not have a name. Is there a way to specify the name of a generated function like this? On Sat, May 30, 2015 at 2:30 PM David Gold david@gmail.com javascript: wrote: Something to note about Tom's method is that the name function must be passed to gf as a symbol, unlike in the case of a macro. However, in most cases this slight difference probably will not warrant a macro. On Friday, May 29, 2015 at 8:58:56 PM UTC-4, Tom Lee wrote: You don't need to use a macro, a function can do this: julia function gf(n::Symbol = gensym()) @eval function $(n)() 1 end end I've also made the n argument optional, with gensym creating a unique name by default - the newly defined function is returned by gf, so you don't necessarily need to know its name. And of course if you give gf additional arguments you can programatically construct expressions based those and easily $ them into the @eval block. It's all very awesome. But the point is a macro probably isn't appropriate for this type of thing. My understanding is that you should never use a macro if you can easily write an equivalent function. Cheers, Tom On Thursday, 28 May 2015 23:26:39 UTC+10, Mauro wrote: Like this: julia macro gf(n) quote function $(esc(n))() 1 end end end julia @gf foo foo (generic function with 1 method) julia foo() 1 On Thu, 2015-05-28 at 12:06, Vasudha Khandelwal vasudhakh...@gmail.com wrote: Can I use macros to generate functions with names passed as argument to the macro?
Re: [julia-users] Macros generating Functions
Something to note about Tom's method is that the name function must be passed to gf as a symbol, unlike in the case of a macro. However, in most cases this slight difference probably will not warrant a macro. On Friday, May 29, 2015 at 8:58:56 PM UTC-4, Tom Lee wrote: You don't need to use a macro, a function can do this: julia function gf(n::Symbol = gensym()) @eval function $(n)() 1 end end I've also made the n argument optional, with gensym creating a unique name by default - the newly defined function is returned by gf, so you don't necessarily need to know its name. And of course if you give gf additional arguments you can programatically construct expressions based those and easily $ them into the @eval block. It's all very awesome. But the point is a macro probably isn't appropriate for this type of thing. My understanding is that you should never use a macro if you can easily write an equivalent function. Cheers, Tom On Thursday, 28 May 2015 23:26:39 UTC+10, Mauro wrote: Like this: julia macro gf(n) quote function $(esc(n))() 1 end end end julia @gf foo foo (generic function with 1 method) julia foo() 1 On Thu, 2015-05-28 at 12:06, Vasudha Khandelwal vasudhakh...@gmail.com wrote: Can I use macros to generate functions with names passed as argument to the macro?
Re: [julia-users] Macros generating Functions
You don't need to use a macro, a function can do this: julia function gf(n::Symbol = gensym()) @eval function $(n)() 1 end end I've also made the n argument optional, with gensym creating a unique name by default - the newly defined function is returned by gf, so you don't necessarily need to know its name. And of course if you give gf additional arguments you can programatically construct expressions based those and easily $ them into the @eval block. It's all very awesome. But the point is a macro probably isn't appropriate for this type of thing. My understanding is that you should never use a macro if you can easily write an equivalent function. Cheers, Tom On Thursday, 28 May 2015 23:26:39 UTC+10, Mauro wrote: Like this: julia macro gf(n) quote function $(esc(n))() 1 end end end julia @gf foo foo (generic function with 1 method) julia foo() 1 On Thu, 2015-05-28 at 12:06, Vasudha Khandelwal vasudhakh...@gmail.com javascript: wrote: Can I use macros to generate functions with names passed as argument to the macro?
Re: [julia-users] Macros generating Functions
Like this: julia macro gf(n) quote function $(esc(n))() 1 end end end julia @gf foo foo (generic function with 1 method) julia foo() 1 On Thu, 2015-05-28 at 12:06, Vasudha Khandelwal vasudhakhandelw...@gmail.com wrote: Can I use macros to generate functions with names passed as argument to the macro?