Re: [julia-users] Macros generating Functions

2015-06-02 Thread Tom Lee
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

2015-06-01 Thread Josh Langsfeld
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

2015-05-31 Thread Yichao Yu
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

2015-05-31 Thread Tom Lee
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

2015-05-31 Thread Kevin Squire
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

2015-05-31 Thread Tom Lee
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

2015-05-30 Thread Jameson Nash
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

2015-05-30 Thread David P. Sanders


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

2015-05-30 Thread David Gold
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

2015-05-29 Thread Tom Lee
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

2015-05-28 Thread Mauro
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?