Taking a slightly different tack, does this example help? julia> module X > export f > function g end > f(x) = g(x) > end > X > > julia> module Y > using X > X.g(x) = 3x > println(f(4)) > end > 12 > Y
You can also add (or "inject") type-specific methods for `X.g`, as is done in external packages for many methods in Base (Base.convert, Base.show, etc.): http://docs.julialang.org/en/release-0.4/manual/methods/ (you just can't avoid the time required to Just-in-Time compile new specializations based on the new methods -- but that is true of all method definitions) On Wed, Feb 17, 2016 at 5:40 PM, Julia Tylors <[email protected]> wrote: > Thanks Stephen. > than i will go by passing g as a parameter to f, but that will make me > pass g down to all other functions needing g along the way in the call > stack of f. > > Thanks again. > > On Wednesday, February 17, 2016 at 2:32:16 PM UTC-8, Stefan Karpinski > wrote: >> >> The behavior of a function does not depend on where it is called from, >> that's a basic principle of the language and one that we are not going to >> change. So I think the bottom line is that by design there is no way to do >> what you're trying to do. >> >> On Wed, Feb 17, 2016 at 5:20 PM, Julia Tylors <[email protected]> wrote: >> >>> basically you generate the code every time in the module of interest. >>> but in my case, the function f is very huge and i don't want to generate it >>> all the time. >>> so that is not what i want to do either. I have seen that already. That >>> is why i was asking "is there some sort of a special AST node, which >>> resolves the function based on the current scope the code.????" >>> >>> that would be a lot more helpful. >>> Thanks >>> >>> >>> On Wednesday, February 17, 2016 at 2:12:31 PM UTC-8, Stefan Karpinski >>> wrote: >>>> >>>> module X >>>> export @make_f >>>> macro make_f() >>>> :($(esc(:f))(x) = $(esc(:g))(x)) >>>> end >>>> end >>>> >>>> module Y >>>> using X >>>> g(x) = 3x >>>> @make_f >>>> end >>>> >>>> julia> Y.f(2) >>>> 6 >>>> >>>> On Wed, Feb 17, 2016 at 5:01 PM, Julia Tylors <[email protected]> >>>> wrote: >>>> >>>>> Yes, exactly. >>>>> >>>>> >>>>> On Wednesday, February 17, 2016 at 1:53:57 PM UTC-8, Stefan Karpinski >>>>> wrote: >>>>>> >>>>>> So you want to have a macro that defines f for you in Y such that it >>>>>> calls Y's g? >>>>>> >>>>>> On Wed, Feb 17, 2016 at 4:48 PM, Julia Tylors <[email protected]> >>>>>> wrote: >>>>>> >>>>>>> I know, but would it be possible to generate code in module X, using >>>>>>> g as a globally defined function so that the function g gets resolved >>>>>>> based >>>>>>> on the module where f is being used? >>>>>>> >>>>>>> Ps: I don't want to pass g as a parameter to f. >>>>>>> >>>>>>> Here is an example: >>>>>>> >>>>>>> julia> module X >>>>>>> export f >>>>>>> g(x) = 2x >>>>>>> f(x) = g(x) >>>>>>> end >>>>>>> X >>>>>>> >>>>>>> julia> module Y >>>>>>> using X >>>>>>> g(x) = 3x >>>>>>> println(f(4)) >>>>>>> end >>>>>>> 8 *# this should have been 12 if the function g is used from Y, it >>>>>>> hasn't been used because when we look at the AST, we would see it is >>>>>>> making >>>>>>> a call to the function g in module X.* >>>>>>> Y >>>>>>> >>>>>>> julia> f.env.defs.func.code >>>>>>> AST(:($(Expr(:lambda, Any[:x], >>>>>>> Any[Any[Any[:x,:Any,0]],Any[],0,Any[]], :(begin # none, line 4: >>>>>>> *return (X.g)(x) # here* >>>>>>> end))))) >>>>>>> >>>>>>> So in the light of this, is it possible to generate code using a >>>>>>> macro with some sort of a special AST node, which resolves the function >>>>>>> based on the current scope the code.???? >>>>>>> >>>>>>> >>>>>>> >>>>>>> On Wednesday, February 17, 2016 at 1:24:33 PM UTC-8, Stefan >>>>>>> Karpinski wrote: >>>>>>>> >>>>>>>> There is no g defined inside of module X. >>>>>>>> >>>>>>>> On Wed, Feb 17, 2016 at 3:19 PM, Julia Tylors <[email protected]> >>>>>>>> wrote: >>>>>>>> >>>>>>>>> julia> module X >>>>>>>>> export f >>>>>>>>> function f(x) >>>>>>>>> g(x) >>>>>>>>> end >>>>>>>>> end >>>>>>>>> X >>>>>>>>> >>>>>>>>> julia> module Y >>>>>>>>> using X >>>>>>>>> g(x) = 2x >>>>>>>>> f(4) >>>>>>>>> end >>>>>>>>> ERROR: UndefVarError: g not defined >>>>>>>>> in f at ./none:4 >>>>>>>>> >>>>>>>>> I am trying to use another function g(x) which can be defined in >>>>>>>>> any other module by calling function f. >>>>>>>>> This is the idea at its simplest. But It seems it doesn't work. >>>>>>>>> >>>>>>>>> >>>>>>>>> On Monday, February 15, 2016 at 7:03:54 PM UTC-8, Cedric St-Jean >>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>> Hi Julia, what are you trying to achieve, concretely? >>>>>>>>>> >>>>>>>>>> On Monday, February 15, 2016 at 2:36:15 PM UTC-5, Julia Tylors >>>>>>>>>> wrote: >>>>>>>>>>> >>>>>>>>>>> I started to think, this may be normal working of julia. >>>>>>>>>>> >>>>>>>>>>> import X:_ex_func >>>>>>>>>>> using X >>>>>>>>>>> _ex_func() = println("DDD") >>>>>>>>>>> _1ex_func() >>>>>>>>>>> julia> _1ex_func() >>>>>>>>>>> DDD >>>>>>>>>>> sty >>>>>>>>>>> >>>>>>>>>>> julia> module Y >>>>>>>>>>> using X >>>>>>>>>>> _ >>>>>>>>>>> _1ex_func __precompile__ _ex_func >>>>>>>>>>> julia> module Y >>>>>>>>>>> using X >>>>>>>>>>> _1ex_func() >>>>>>>>>>> end >>>>>>>>>>> DDD >>>>>>>>>>> sty >>>>>>>>>>> Y >>>>>>>>>>> >>>>>>>>>>> However, it seems once a function is overridden, it stays >>>>>>>>>>> overridden in every module. >>>>>>>>>>> That is a very weird idea. why is there such a design decision? >>>>>>>>>>> Can someone care to explain it? >>>>>>>>>>> >>>>>>>>>>> Thanks >>>>>>>>>>> >>>>>>>>>>> On Monday, February 15, 2016 at 11:04:07 AM UTC-8, Julia Tylors >>>>>>>>>>> wrote: >>>>>>>>>>>> >>>>>>>>>>>> Guys, this is no solution to my problem, >>>>>>>>>>>> >>>>>>>>>>>> escaping basically tells the the quoted expr to be resolved >>>>>>>>>>>> outside the macro as Lutfullah did. However in my case, escaping a >>>>>>>>>>>> function >>>>>>>>>>>> call doesn't work for some reason. >>>>>>>>>>>> And for that matter, esc should be recursive though... >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On Monday, February 15, 2016 at 6:44:58 AM UTC-8, Joshua >>>>>>>>>>>> Ballanco wrote: >>>>>>>>>>>>> >>>>>>>>>>>>> On February 14, 2016 at 21:49:30, Julia Tylors ( >>>>>>>>>>>>> [email protected](mailto:[email protected])) wrote: >>>>>>>>>>>>> >>>>>>>>>>>>> > Hi fellows, >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > I was coding a macro, and I am having a prefix issue with >>>>>>>>>>>>> functions. >>>>>>>>>>>>> > >>>>>>>>>>>>> > basically the problem is: Every single one of available >>>>>>>>>>>>> functions (_ex_func) which i want to be globally accessible are >>>>>>>>>>>>> prefixed >>>>>>>>>>>>> with the name of the module(X) in which the macro f is defined >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > Here is the code example: >>>>>>>>>>>>> > >>>>>>>>>>>>> > julia> module X >>>>>>>>>>>>> > export @f >>>>>>>>>>>>> > macro f(x) >>>>>>>>>>>>> > st = string("_",x) >>>>>>>>>>>>> > sy = symbol(st) >>>>>>>>>>>>> > esc(quote >>>>>>>>>>>>> > function ($sy)() >>>>>>>>>>>>> > println("st") >>>>>>>>>>>>> > end >>>>>>>>>>>>> > >>>>>>>>>>>>> > function ($(symbol(string("_1",x))))() >>>>>>>>>>>>> > ($sy)() >>>>>>>>>>>>> > println("sty") >>>>>>>>>>>>> > end >>>>>>>>>>>>> > export $sy >>>>>>>>>>>>> > export $(symbol(string("_1",x))) >>>>>>>>>>>>> > end >>>>>>>>>>>>> > ) >>>>>>>>>>>>> > end >>>>>>>>>>>>> > @eval @f ex_func >>>>>>>>>>>>> > end >>>>>>>>>>>>> > X >>>>>>>>>>>>> > >>>>>>>>>>>>> > julia> using X >>>>>>>>>>>>> > >>>>>>>>>>>>> > julia> _ >>>>>>>>>>>>> > >>>>>>>>>>>>> > _1ex_func __precompile__ _ex_func >>>>>>>>>>>>> > julia> _1ex_func.env.defs.func.code >>>>>>>>>>>>> > AST(:($(Expr(:lambda, Any[], Any[Any[],Any[],0,Any[]], >>>>>>>>>>>>> :(begin # none, line 12: >>>>>>>>>>>>> > (X._ex_func)() # none, line 13: # i want this to be not >>>>>>>>>>>>> prefixed by X >>>>>>>>>>>>> > return (X.println)("sty") >>>>>>>>>>>>> > end))))) >>>>>>>>>>>>> > >>>>>>>>>>>>> > julia> macroexpand(:(@f ex_func)) >>>>>>>>>>>>> > quote # none, line 7: >>>>>>>>>>>>> > function _ex_func() # none, line 8: >>>>>>>>>>>>> > println("st") >>>>>>>>>>>>> > end # none, line 11: >>>>>>>>>>>>> > function _1ex_func() # none, line 12: >>>>>>>>>>>>> > _ex_func() # none, line 13: # it seems OK, here!!! >>>>>>>>>>>>> > println("sty") >>>>>>>>>>>>> > end # none, line 15: >>>>>>>>>>>>> > export _ex_func # none, line 16: >>>>>>>>>>>>> > export _1ex_func >>>>>>>>>>>>> > end >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>>>> > as you may see , I may well define _ex_func in other modules >>>>>>>>>>>>> and use it from the function X._1ex_func(). >>>>>>>>>>>>> > But this prevents me doing it. >>>>>>>>>>>>> > >>>>>>>>>>>>> > How can i solve this problem? >>>>>>>>>>>>> > >>>>>>>>>>>>> > Thanks >>>>>>>>>>>>> >>>>>>>>>>>>> OH! I know this! >>>>>>>>>>>>> >>>>>>>>>>>>> Actually, I do believe this is a bug in macro hygiene and have >>>>>>>>>>>>> been meaning to file it. In the mean time, double-escaping should >>>>>>>>>>>>> work for >>>>>>>>>>>>> you: >>>>>>>>>>>>> >>>>>>>>>>>>> julia> module X >>>>>>>>>>>>> macro p(y) >>>>>>>>>>>>> quote >>>>>>>>>>>>> println($y) >>>>>>>>>>>>> end >>>>>>>>>>>>> end >>>>>>>>>>>>> macro q(y) >>>>>>>>>>>>> quote >>>>>>>>>>>>> println(:($($y))) >>>>>>>>>>>>> end >>>>>>>>>>>>> end >>>>>>>>>>>>> end >>>>>>>>>>>>> X >>>>>>>>>>>>> >>>>>>>>>>>>> julia> using X >>>>>>>>>>>>> >>>>>>>>>>>>> julia> test = "Hello, world" >>>>>>>>>>>>> "Hello, world" >>>>>>>>>>>>> >>>>>>>>>>>>> julia> @X.p(test) >>>>>>>>>>>>> ERROR: UndefVarError: test not defined >>>>>>>>>>>>> >>>>>>>>>>>>> julia> @X.q(test) >>>>>>>>>>>>> Hello, world >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>> >>>>>> >>>> >>
