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. >