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

Reply via email to