Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hygiene of named function objects #25955

Closed
Roger-luo opened this issue Feb 8, 2018 · 3 comments
Closed

Hygiene of named function objects #25955

Roger-luo opened this issue Feb 8, 2018 · 3 comments
Assignees
Labels
bug Indicates an unexpected problem or unintended behavior macros @macros

Comments

@Roger-luo
Copy link
Contributor

Roger-luo commented Feb 8, 2018

shouldn't this macro have no effect?

macro noeffect(e)
    return e
end

but it raises error if you use it to this function

struct foo
end

@noeffect function (f::foo)()
   println("no effect")
end
ERROR: LoadError: syntax: "Main.f" is not a valid function argument name

Version Info

Julia Version 0.6.0
Commit 9036443 (2017-06-19 13:05 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Core(TM) i5-4200M CPU @ 2.50GHz
  WORD_SIZE: 64
  BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Haswell)
  LAPACK: libopenblas64_
  LIBM: libopenlibm
  LLVM: libLLVM-3.9.1 (ORCJIT, haswell)

@KristofferC
Copy link
Sponsor Member

KristofferC commented Feb 8, 2018

julia> @macroexpand @noeffect function (f::foo)()
          println("no effect")
       end
:(function (Main.f::Main.foo)()
      #= REPL[5]:2 =#
      (Main.println)("no effect")
  end)
julia> macro noeffect2(e)
           return esc(e)
       end
@noeffect2 (macro with 1 method)

julia> @macroexpand @noeffect2 function (f::foo)()
          println("no effect")
       end
:(function (f::foo)()
      #= REPL[7]:2 =#
      println("no effect")
  end)

See https://docs.julialang.org/en/stable/manual/metaprogramming/#Hygiene-1

Please use the forum at https://discourse.julialang.org list for usage question

@mbauman
Copy link
Sponsor Member

mbauman commented Feb 8, 2018

I agree that this seems to be a usage question — and using esc is definitely the right answer.

But it does seem like there's an issue here. I would expect the hygiene of (f::T)() = f to behave similarly to g(f::T) = f. You're naming a local argument. Compare:

julia> @macroexpand @noeffect (f::foo)() = f
:((Main.f::Main.foo)() = begin
          #= REPL[4]:1 =#
          Main.f
      end)

julia> @macroexpand @noeffect g(f::Foo) = f
:((Main.g)(#5#f::Main.Foo) = begin
          #= REPL[6]:1 =#
          #5#f
      end)

@mbauman mbauman reopened this Feb 8, 2018
@mbauman mbauman changed the title macro behaves differently when apply to call method Hygiene of named function objects Feb 8, 2018
@mbauman mbauman added the macros @macros label Feb 8, 2018
@JeffBezanson
Copy link
Sponsor Member

Agreed, this is a hygiene bug.

@JeffBezanson JeffBezanson added the bug Indicates an unexpected problem or unintended behavior label Feb 8, 2018
@StefanKarpinski StefanKarpinski added this to the 1.0.x milestone Feb 9, 2018
@JeffBezanson JeffBezanson self-assigned this Aug 13, 2018
KristofferC pushed a commit that referenced this issue Sep 10, 2018
KristofferC pushed a commit that referenced this issue Feb 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Indicates an unexpected problem or unintended behavior macros @macros
Projects
None yet
Development

No branches or pull requests

5 participants