[julia-users] Macros inside functions

2014-04-17 Thread Ben Ward
Hi Is it possible to use macros inside o functions in Julia if they are 
expanded at compile time as the manual says? I've been playing with a toy 
type:

type MeltingTemperature
  value::Int
end




myvar = MeltingTemperature(56)


and say I want to make a function that write it out as an XML string: 
"56

Now I want to make a function that constructs that string by 1). Adding the 
open tag 2). Checking the temperature is not nothing and if it is not, 
including it in the string. 3). add the closing tag.

I figured step 2 would be a good candidate for a macro for a larger type as 
checking each value is not nothing would be tedious. So:

macro INN(string, value)
  value != nothing ? "$string$value" : "$string"
end


function writePhyXML(x::MeltingTemperature)
  outstring = ""
  outstring = @INN outstring x.value;
  outstring = "$(outstring)"
  outstring
end


I figured the macro would be expanded and the function definition would 
become:

function writePhyXML(x::MeltingTemperature)
  outstring = ""
  outstring = x.value != nothing ? "$outstring$x.value" : "$outstring"
  outstring = "$(outstring)"
  outstring
end


But results in "outstringx.value"

Is it possible to do this with macro's? I had presumed it is.

(I know it's possible by just using a sub function, but I wanted to see how 
to try and use macros to generate code for function definitions if 
possible.)

Thanks,
Ben.


Re: [julia-users] Macros inside functions

2014-04-17 Thread Jameson Nash
disclaimer: I would use a function, not a macro for this purpose:
INN( outstring, value ) = value !== nothing ? "$outstring$value" : outstring
INN(outstring, x.value)

it is simpler, and gives up nothing in exchange for actually being
readable and versatile

but assuming you had a more interesting use case: when you expand the
macro as written, the result is:
"$string$value", with string=:outstring and value=:(x.value), exactly
as you specified: "outstringx.value"

but you want the string before interpolation (note that I'm switching
to the functional form of string interpolation because it is easier to
read in macro form), so we need this complicated thing to make a macro
that is actually just a function:
macro INN(str, val)
  :( v = $(esc(val)); s = $(esc(str)); v != nothing ? string(v, s) : s )
end

but the better way to write that is:
INN( outstring, value ) = value !== nothing ? "$outstring$value" : outstring
macro INN(str, val)
  :( INN($(esc(str)), $(esc(val))) )
end

why is this better? it's easier to read, write, and debug (also,
because it makes it obvious that you should not be using a macro for
this)

finally, there's the even cleaner options:
  outstring = "$(x.value!==nothing?x.value:"")"

or, using multiple dispatch -- my favorite option (excellent API for
future extensibility):
  mystr(::Nothing) = ""
  mystr(x) = x
  outstring = "$(mystr(x))"

note that since in your type, you have value::Int, so value will
always be an Int, never another type (like nothing), so it's a
pointless test

final note, string concatenation using $ or * or string (all of which
are exactly equivalent) is going to be slow compared to making an
IOBuffer, printing / writing / or showing all of your text to the
buffer, then calling takebuf_string(iobuf) at then end

On Thu, Apr 17, 2014 at 11:38 PM, Ben Ward  wrote:
> Hi Is it possible to use macros inside o functions in Julia if they are
> expanded at compile time as the manual says? I've been playing with a toy
> type:
>
> type MeltingTemperature
>   value::Int
> end
>
>
>
>
> myvar = MeltingTemperature(56)
>
>
> and say I want to make a function that write it out as an XML string:
> "56
>
> Now I want to make a function that constructs that string by 1). Adding the
> open tag 2). Checking the temperature is not nothing and if it is not,
> including it in the string. 3). add the closing tag.
>
> I figured step 2 would be a good candidate for a macro for a larger type as
> checking each value is not nothing would be tedious. So:
>
> macro INN(string, value)
>   value != nothing ? "$string$value" : "$string"
> end
>
>
> function writePhyXML(x::MeltingTemperature)
>   outstring = ""
>   outstring = @INN outstring x.value;
>   outstring = "$(outstring)"
>   outstring
> end
>
>
> I figured the macro would be expanded and the function definition would
> become:
>
> function writePhyXML(x::MeltingTemperature)
>   outstring = ""
>   outstring = x.value != nothing ? "$outstring$x.value" : "$outstring"
>   outstring = "$(outstring)"
>   outstring
> end
>
>
> But results in "outstringx.value"
>
> Is it possible to do this with macro's? I had presumed it is.
>
> (I know it's possible by just using a sub function, but I wanted to see how
> to try and use macros to generate code for function definitions if
> possible.)
>
> Thanks,
> Ben.


Re: [julia-users] Macros inside functions

2014-04-18 Thread Ben Ward
Thanks, Jameson,

I should say in this case it is obvious the function would be better and I 
agree, this was a case I made myself to see if it could be done. The reason 
being, I'm writing a type, the composition of which could be extended by 
the user to contain other information (I'm working with a data format and 
file format(s) for phylogenetic data which is often non standard). So I 
made the base type extendible, and now I'm trying to get the stuff that 
reads or writes to file to be extendible. I'm currently working on the 
writing stuff to file, and what I've done got is a function which will 
write the data to file, including the extra user extended data, as long as 
the user has provided a method for representing it as a string, and so I 
thought providing some macro's to make defining such methods more quick and 
painless to write for the user, but perhaps providing a set of 
sub-functions would be better. Hence the INN macro, so you don't have to 
write lines checking it's not nothing every time (which I know 
shouldn't happen, but again, this is a bit of a contrived case to try 
and see if it could/should be done this way. I also had an idea for writing 
a macro which generated the entire function for the user given some basic 
information, but baby steps first. Strikes me a lot of times I figure a 
macro would be good for something, a function can do the same job.

Best,
Ben.



 

On Friday, April 18, 2014 6:38:14 AM UTC+1, Jameson wrote:
>
> disclaimer: I would use a function, not a macro for this purpose: 
> INN( outstring, value ) = value !== nothing ? "$outstring$value" : 
> outstring 
> INN(outstring, x.value) 
>
> it is simpler, and gives up nothing in exchange for actually being 
> readable and versatile 
>
> but assuming you had a more interesting use case: when you expand the 
> macro as written, the result is: 
> "$string$value", with string=:outstring and value=:(x.value), exactly 
> as you specified: "outstringx.value" 
>
> but you want the string before interpolation (note that I'm switching 
> to the functional form of string interpolation because it is easier to 
> read in macro form), so we need this complicated thing to make a macro 
> that is actually just a function: 
> macro INN(str, val) 
>   :( v = $(esc(val)); s = $(esc(str)); v != nothing ? string(v, s) : s ) 
> end 
>
> but the better way to write that is: 
> INN( outstring, value ) = value !== nothing ? "$outstring$value" : 
> outstring 
> macro INN(str, val) 
>   :( INN($(esc(str)), $(esc(val))) ) 
> end 
>
> why is this better? it's easier to read, write, and debug (also, 
> because it makes it obvious that you should not be using a macro for 
> this) 
>
> finally, there's the even cleaner options: 
>   outstring = "$(x.value!==nothing?x.value:"")" 
>
> or, using multiple dispatch -- my favorite option (excellent API for 
> future extensibility): 
>   mystr(::Nothing) = "" 
>   mystr(x) = x 
>   outstring = "$(mystr(x))" 
>
> note that since in your type, you have value::Int, so value will 
> always be an Int, never another type (like nothing), so it's a 
> pointless test 
>
> final note, string concatenation using $ or * or string (all of which 
> are exactly equivalent) is going to be slow compared to making an 
> IOBuffer, printing / writing / or showing all of your text to the 
> buffer, then calling takebuf_string(iobuf) at then end 
>
> On Thu, Apr 17, 2014 at 11:38 PM, Ben Ward 
> > 
> wrote: 
> > Hi Is it possible to use macros inside o functions in Julia if they are 
> > expanded at compile time as the manual says? I've been playing with a 
> toy 
> > type: 
> > 
> > type MeltingTemperature 
> >   value::Int 
> > end 
> > 
> > 
> > 
> > 
> > myvar = MeltingTemperature(56) 
> > 
> > 
> > and say I want to make a function that write it out as an XML string: 
> > "56 
> > 
> > Now I want to make a function that constructs that string by 1). Adding 
> the 
> > open tag 2). Checking the temperature is not nothing and if it is not, 
> > including it in the string. 3). add the closing tag. 
> > 
> > I figured step 2 would be a good candidate for a macro for a larger type 
> as 
> > checking each value is not nothing would be tedious. So: 
> > 
> > macro INN(string, value) 
> >   value != nothing ? "$string$value" : "$string" 
> > end 
> > 
> > 
> > function writePhyXML(x::MeltingTemperature) 
> >   outstring = "" 
> >   outstring = @INN outstring x.value; 
> >   outstring = "$(outstring)" 
> >   outstring 
> > end 
> > 
> > 
> > I figured the macro would be expanded and the function definition would 
> > become: 
> > 
> > function writePhyXML(x::MeltingTemperature) 
> >   outstring = "" 
> >   outstring = x.value != nothing ? "$outstring$x.value" : "$outstring" 
> >   outstring = "$(outstring)" 
> >   outstring 
> > end 
> > 
> > 
> > But results in "outstringx.value" 
> > 
> > Is it possible to do this with macro's? I had presumed it is. 
> > 
> > (I know it's possible by just using a sub function, but

Re: [julia-users] Macros inside functions

2014-04-18 Thread Ben Ward
Thinking about it some more, and how you advise to use multiple dispatch to 
write these things out - is it possible to use multiple dispatch to read in 
things similarly? Because the thing you are reading in is to become the 
types you base the dispatch of the method on, so how could this apply to 
reading in types when the instances of the types are not extant yet? Maybe 
if you supply a empty instance of the type you want to read in for the 
dispatch? e.g.

inmystr(x::file, y::MeltingPoint) = # how to extract info from text here.

So I want to reading in MeltingPoint data from a file, and want to use the 
inmystr method that applies based on the function signature, yet I have no 
MeltingPoint types currently, because I'm trying to read them in, instead 
of having the object and writing it out. I know in C++ when trying to catch 
multiple different types of possible throws, you can define empty types to 
act as error types, I wonder if such a tactic here is applicable.

Best,
Ben.

On Friday, April 18, 2014 6:38:14 AM UTC+1, Jameson wrote:
>
> disclaimer: I would use a function, not a macro for this purpose: 
> INN( outstring, value ) = value !== nothing ? "$outstring$value" : 
> outstring 
> INN(outstring, x.value) 
>
> it is simpler, and gives up nothing in exchange for actually being 
> readable and versatile 
>
> but assuming you had a more interesting use case: when you expand the 
> macro as written, the result is: 
> "$string$value", with string=:outstring and value=:(x.value), exactly 
> as you specified: "outstringx.value" 
>
> but you want the string before interpolation (note that I'm switching 
> to the functional form of string interpolation because it is easier to 
> read in macro form), so we need this complicated thing to make a macro 
> that is actually just a function: 
> macro INN(str, val) 
>   :( v = $(esc(val)); s = $(esc(str)); v != nothing ? string(v, s) : s ) 
> end 
>
> but the better way to write that is: 
> INN( outstring, value ) = value !== nothing ? "$outstring$value" : 
> outstring 
> macro INN(str, val) 
>   :( INN($(esc(str)), $(esc(val))) ) 
> end 
>
> why is this better? it's easier to read, write, and debug (also, 
> because it makes it obvious that you should not be using a macro for 
> this) 
>
> finally, there's the even cleaner options: 
>   outstring = "$(x.value!==nothing?x.value:"")" 
>
> or, using multiple dispatch -- my favorite option (excellent API for 
> future extensibility): 
>   mystr(::Nothing) = "" 
>   mystr(x) = x 
>   outstring = "$(mystr(x))" 
>
> note that since in your type, you have value::Int, so value will 
> always be an Int, never another type (like nothing), so it's a 
> pointless test 
>
> final note, string concatenation using $ or * or string (all of which 
> are exactly equivalent) is going to be slow compared to making an 
> IOBuffer, printing / writing / or showing all of your text to the 
> buffer, then calling takebuf_string(iobuf) at then end 
>
> On Thu, Apr 17, 2014 at 11:38 PM, Ben Ward 
> > 
> wrote: 
> > Hi Is it possible to use macros inside o functions in Julia if they are 
> > expanded at compile time as the manual says? I've been playing with a 
> toy 
> > type: 
> > 
> > type MeltingTemperature 
> >   value::Int 
> > end 
> > 
> > 
> > 
> > 
> > myvar = MeltingTemperature(56) 
> > 
> > 
> > and say I want to make a function that write it out as an XML string: 
> > "56 
> > 
> > Now I want to make a function that constructs that string by 1). Adding 
> the 
> > open tag 2). Checking the temperature is not nothing and if it is not, 
> > including it in the string. 3). add the closing tag. 
> > 
> > I figured step 2 would be a good candidate for a macro for a larger type 
> as 
> > checking each value is not nothing would be tedious. So: 
> > 
> > macro INN(string, value) 
> >   value != nothing ? "$string$value" : "$string" 
> > end 
> > 
> > 
> > function writePhyXML(x::MeltingTemperature) 
> >   outstring = "" 
> >   outstring = @INN outstring x.value; 
> >   outstring = "$(outstring)" 
> >   outstring 
> > end 
> > 
> > 
> > I figured the macro would be expanded and the function definition would 
> > become: 
> > 
> > function writePhyXML(x::MeltingTemperature) 
> >   outstring = "" 
> >   outstring = x.value != nothing ? "$outstring$x.value" : "$outstring" 
> >   outstring = "$(outstring)" 
> >   outstring 
> > end 
> > 
> > 
> > But results in "outstringx.value" 
> > 
> > Is it possible to do this with macro's? I had presumed it is. 
> > 
> > (I know it's possible by just using a sub function, but I wanted to see 
> how 
> > to try and use macros to generate code for function definitions if 
> > possible.) 
> > 
> > Thanks, 
> > Ben. 
>


Re: [julia-users] Macros inside functions

2014-04-18 Thread Patrick O'Leary
Every type has a corresponding singleton value that is the type itself, and 
can be dispatched on:

inmystr(x::file, ::MeltingPoint) = #function

new_melting_point_thing = inmystr(f, MeltingPoint)

This is the technique used by the conversions mechanism: 
http://julia.readthedocs.org/en/latest/manual/conversion-and-promotion/#man-conversion

On Friday, April 18, 2014 6:08:35 AM UTC-5, Ben Ward wrote:
>
> Thinking about it some more, and how you advise to use multiple dispatch 
> to write these things out - is it possible to use multiple dispatch to read 
> in things similarly? Because the thing you are reading in is to become the 
> types you base the dispatch of the method on, so how could this apply to 
> reading in types when the instances of the types are not extant yet? Maybe 
> if you supply a empty instance of the type you want to read in for the 
> dispatch? e.g.
>
> inmystr(x::file, y::MeltingPoint) = # how to extract info from text here.
>
> So I want to reading in MeltingPoint data from a file, and want to use the 
> inmystr method that applies based on the function signature, yet I have no 
> MeltingPoint types currently, because I'm trying to read them in, instead 
> of having the object and writing it out. I know in C++ when trying to catch 
> multiple different types of possible throws, you can define empty types to 
> act as error types, I wonder if such a tactic here is applicable.
>
> Best,
> Ben.
>
> On Friday, April 18, 2014 6:38:14 AM UTC+1, Jameson wrote:
>>
>> disclaimer: I would use a function, not a macro for this purpose: 
>> INN( outstring, value ) = value !== nothing ? "$outstring$value" : 
>> outstring 
>> INN(outstring, x.value) 
>>
>> it is simpler, and gives up nothing in exchange for actually being 
>> readable and versatile 
>>
>> but assuming you had a more interesting use case: when you expand the 
>> macro as written, the result is: 
>> "$string$value", with string=:outstring and value=:(x.value), exactly 
>> as you specified: "outstringx.value" 
>>
>> but you want the string before interpolation (note that I'm switching 
>> to the functional form of string interpolation because it is easier to 
>> read in macro form), so we need this complicated thing to make a macro 
>> that is actually just a function: 
>> macro INN(str, val) 
>>   :( v = $(esc(val)); s = $(esc(str)); v != nothing ? string(v, s) : s ) 
>> end 
>>
>> but the better way to write that is: 
>> INN( outstring, value ) = value !== nothing ? "$outstring$value" : 
>> outstring 
>> macro INN(str, val) 
>>   :( INN($(esc(str)), $(esc(val))) ) 
>> end 
>>
>> why is this better? it's easier to read, write, and debug (also, 
>> because it makes it obvious that you should not be using a macro for 
>> this) 
>>
>> finally, there's the even cleaner options: 
>>   outstring = "$(x.value!==nothing?x.value:"")" 
>>
>> or, using multiple dispatch -- my favorite option (excellent API for 
>> future extensibility): 
>>   mystr(::Nothing) = "" 
>>   mystr(x) = x 
>>   outstring = "$(mystr(x))" 
>>
>> note that since in your type, you have value::Int, so value will 
>> always be an Int, never another type (like nothing), so it's a 
>> pointless test 
>>
>> final note, string concatenation using $ or * or string (all of which 
>> are exactly equivalent) is going to be slow compared to making an 
>> IOBuffer, printing / writing / or showing all of your text to the 
>> buffer, then calling takebuf_string(iobuf) at then end 
>>
>> On Thu, Apr 17, 2014 at 11:38 PM, Ben Ward  wrote: 
>> > Hi Is it possible to use macros inside o functions in Julia if they are 
>> > expanded at compile time as the manual says? I've been playing with a 
>> toy 
>> > type: 
>> > 
>> > type MeltingTemperature 
>> >   value::Int 
>> > end 
>> > 
>> > 
>> > 
>> > 
>> > myvar = MeltingTemperature(56) 
>> > 
>> > 
>> > and say I want to make a function that write it out as an XML string: 
>> > "56 
>> > 
>> > Now I want to make a function that constructs that string by 1). Adding 
>> the 
>> > open tag 2). Checking the temperature is not nothing and if it is not, 
>> > including it in the string. 3). add the closing tag. 
>> > 
>> > I figured step 2 would be a good candidate for a macro for a larger 
>> type as 
>> > checking each value is not nothing would be tedious. So: 
>> > 
>> > macro INN(string, value) 
>> >   value != nothing ? "$string$value" : "$string" 
>> > end 
>> > 
>> > 
>> > function writePhyXML(x::MeltingTemperature) 
>> >   outstring = "" 
>> >   outstring = @INN outstring x.value; 
>> >   outstring = "$(outstring)" 
>> >   outstring 
>> > end 
>> > 
>> > 
>> > I figured the macro would be expanded and the function definition would 
>> > become: 
>> > 
>> > function writePhyXML(x::MeltingTemperature) 
>> >   outstring = "" 
>> >   outstring = x.value != nothing ? "$outstring$x.value" : "$outstring" 
>> >   outstring = "$(outstring)" 
>> >   outstring 
>> > end 
>> > 
>> > 
>> > But results in "outstringx.value" 
>> > 
>> > Is it possibl