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

A function gets executes several times while being only called once #21518

Closed
fjarri opened this issue Apr 24, 2017 · 1 comment
Closed

A function gets executes several times while being only called once #21518

fjarri opened this issue Apr 24, 2017 · 1 comment
Assignees
Labels
compiler:lowering Syntax lowering (compiler front end, 2nd stage)

Comments

@fjarri
Copy link
Contributor

fjarri commented Apr 24, 2017

Consider the following code:

function inner(; kw=nothing)
    println("in inner()")
end

function get_inner()
    println("in get_inner()")
    inner
end

function test1()
    f = get_inner()
    f(kw=1)
end

function test2()
    get_inner()(kw=1)
end

function test3()
    get_inner()(; :kw => 1)
end


println("test1:")
test1()
println("test2:")
test2()
println("test3:")
test3()

In each of the test functions I would expect get_inner() to be only called once. Yet the output I get is

test1:
in get_inner()
in inner()
test2:
in get_inner()
in get_inner()
in inner()
test3:
in get_inner()
in get_inner()
in get_inner()
in inner()

Is it some peculiarity of Julia syntax, or a bug?

versioninfo() output:

Julia Version 0.5.1
Commit 6445c82 (2017-03-05 13:25 UTC)
Platform Info:
  OS: macOS (x86_64-apple-darwin13.4.0)
  CPU: Intel(R) Core(TM) i7-4771 CPU @ 3.50GHz
  WORD_SIZE: 64
  BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Haswell)
  LAPACK: libopenblas64_
  LIBM: libopenlibm
  LLVM: libLLVM-3.7.1 (ORCJIT, haswell)
@martinholters
Copy link
Member

Also present on current master (but for test3, get_inner is only called twice). Seems to be a lowering issue:

julia> expand(:(get_inner()(kw=1)))
:(((Core.kwfunc)(get_inner()))((Base.vector_any)(:kw, 1), get_inner()))

AFAIU, the expression yielding the function to be called would need to be evaluated once with the result being stored in an SSAValue instead of evaluating it twice.

@martinholters martinholters added the compiler:lowering Syntax lowering (compiler front end, 2nd stage) label Apr 24, 2017
@martinholters martinholters self-assigned this Apr 24, 2017
martinholters added a commit that referenced this issue Apr 24, 2017
Lower e.g. `get_inner()(kw=1)` to
```
SSAValue(n) = get_inner()
((Core.kwfunc)(SSAValue(n)))((Base.vector_any)(:kw, 1), SSAValue(n))
```
instead of
```
((Core.kwfunc)(get_inner()))((Base.vector_any)(:kw, 1), get_inner())`
```
as the latter would call `get_inner` twice.

Fixes #21518.
martinholters added a commit that referenced this issue Apr 25, 2017
Lower e.g. `get_inner()(kw=1)` to
```
SSAValue(n) = get_inner()
((Core.kwfunc)(SSAValue(n)))((Base.vector_any)(:kw, 1), SSAValue(n))
```
instead of
```
((Core.kwfunc)(get_inner()))((Base.vector_any)(:kw, 1), get_inner())
```
as the latter would call `get_inner` twice.

Fixes #21518.
JeffBezanson pushed a commit that referenced this issue Apr 27, 2017
* Only evaluate `fexpr` in `fexpr(kw=...)` once

Lower e.g. `get_inner()(kw=1)` to
```
SSAValue(n) = get_inner()
((Core.kwfunc)(SSAValue(n)))((Base.vector_any)(:kw, 1), SSAValue(n))
```
instead of
```
((Core.kwfunc)(get_inner()))((Base.vector_any)(:kw, 1), get_inner())
```
as the latter would call `get_inner` twice.

Fixes #21518.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler:lowering Syntax lowering (compiler front end, 2nd stage)
Projects
None yet
Development

No branches or pull requests

2 participants