Yes, that can be sort of a pain. Our I/O functions all have this issue – you have to pass the IO object through all the way down the call stack. The alternative is to do some kind of dynamic scoping, which we don't have language support for, so you'd have to do it manually. I.e. something like this:
module X export f, g const h = Function[] f(x) = 2g(x) g(x) = 3h[end](x) end module Y using X function f(x) push!(X.h, x->5x) y = X.f(x) pop!(X.h) return y end end julia> Y.f(7) 210 On Wed, Feb 17, 2016 at 5:40 PM, Julia Tylors <juliatyl...@gmail.com> 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 <julia...@gmail.com> 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 <julia...@gmail.com> >>>> 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 <julia...@gmail.com> >>>>>> 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 <julia...@gmail.com> >>>>>>>> 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 ( >>>>>>>>>>>>> julia...@gmail.com(mailto:juliatyl...@gmail.com)) 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 >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>> >>>>>> >>>> >>