On Thu, Jul 21, 2016 at 4:01 PM, Marius Millea <mariusmil...@gmail.com> wrote:
> In an attempt to make some numerical code (ie something thats basically just
> a bunch of equations) more readable, I am trying to write a macro that lets
> me write the code more succinctly. The code uses parameters from some data
> structure, call it "mytype", so its littered with "t.a", "t.b", etc.. where
> t::mytype. My macro basically splices in the the "t." part for me. Its kind
> of like how C++ member functions automatically access the class's fields, as
> an example. To my amazement / growing love of Julia, I actually managed to
> hack it together without too much difficulty, it looks like this,
>
>
> macro self(func)
>     @assert func.head == :function
>
>     # add "self" as a first function argument
>     insert!(func.args[1].args,2,:(self::mytype))
>
>
>     # recurse through AST and rename X to self.X if
>     # its a fieldname of mytype
>     function visit(ex)
>         if typeof(ex) == Expr
>             ex.args = map(visit,ex.args)
>         elseif (typeof(ex) == Symbol) & (ex in fieldnames(mytype))
>             return :(self.$ex)
>         end
>         ex
>     end
>     func.args[2] = visit(func.args[2])
>
>     show(func) # print the edited function so we can see it in action
>
>     :($(esc(func)))
> end
>
>
>
>
> Here it is in action:
>
>> @self function inc()
>     x = x + 1
> end
>
>
> :(function inc(self::mytype)
>         self.x = self.x + 1
>     end)
>
>
> inc (generic function with 1 method)
>
>
>
>
>> inc(mytype(0))
> 1
>
>
>
> where I'm assuming I've defined mytype as
>
> type mytype
>     x
> end
>
>
>
> As you can see, all it did was add self::mytype as an arg and replace x with
> self.x everywhere it found it. This is also super nice because there is zero
> run-time overhead vs. having written the "self." myself, everything happens
> compile time.
>
> Now for the question. I'd like to also to be able automatically pass the
> "self" argument to functions, so that I could write something like,
>
> @self function inc2()
>     inc()
>     inc()
> end
>
>
>
> and it would produce
>
> function inc2(self::mytype)
>     inc(self)
>     inc(self)
> end
>
>
>
> For this though, my macro needs to somehow figure out that "inc" was also
> defined with @self (since it shouldn't blindly add self as a first arg so
> other non-@self'ed function calls). Is this possible in Julia? I suppose
> somehow the macro must access the global scope where the expression is being
> evaluated? I'm not entirely sure that's doable. I'm happy to take any tips
> how to achieve this though, especially ones incurring minimal overhead for
> the rewritten function. Thanks!

You should not do this. It is possible to access the current module
but you don't have any scope information.

>

Reply via email to