# Language restriction to solve 15276?

**URL:** https://discourse.julialang.org/t/language-restriction-to-solve-15276/10625
**Category:** Internals & Design
**Created:** [April 30, 2018, 5:29pm UTC](https://discourse.julialang.org/t/language-restriction-to-solve-15276/10625 "2018-04-30T17:29:12Z")
**Posts on this page:** 1
**Showing post:** 30

<div class="post-metadata">

### Author: ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)
#### Post date: [May 6, 2018, 6:02am UTC](https://discourse.julialang.org/t/language-restriction-to-solve-15276/10625/30 "2018-05-06T06:02:24Z")

</div>

Unfortunately inference can’t help us much here. The boxing is occurring at the _syntax_ level. This is before Julia has access to inference. It’s before compilation. That’s what makes it so tricky. We’re in #development — let’s make it more #development-y. Here’s one of the simpler examples from the big #15276 thread:

```julia
julia> Meta.@lower function f()
           if true
           end
           r = 1
           cb = ()->r
           cb()
       end

```

[(output)](https://gist.github.com/mbauman/c914f1ac07a9da9a803231455714c434)

There’s a lot going on there, and that’s pretty hard to read for folks not well versed in Julia’s intermediate representation, but it’s approximately:

```julia
function f end
struct __9_10 <: Core.Function
    r::Core.Box
end
(self::__9_10)() = isdefined(self.r, :contents) ? self.r.contents : error()
function f
    r = Core.Box()
    if true
    end
    r.contents = 1
    cb = __9_10(r)
    return cb()
end

```

That syntax isn’t just lowering to the method you wrote — it’s also defining a callable struct that represents the anonymous function, and more importantly it’s transforming `r` into something that has behavior. I highly recommend folks who are interested to play around with this basic framework and see how the `Meta.@lower` output changes as you add an `::Int` annotation or remove the branch or add another assignment to `r` in between constructing and calling `cb`. You can see how this being a syntax-level transform is important: assignments to `r` need to _mutate_ something that has identity and behavior in order to also affect the inner function. It can no longer just be a machine integer.

If the parser can _prove_ that `r` is constant-valued over its entire lifespan, the above becomes approximately:

```julia
struct __9_10{R} <: Core.Function
    r::R
end
(self::__9_10)() = self.r
function f
    if true
    end
    r = 1
    cb = __9_10(r)
    return cb()
end

```

Now that’s the kind of thing inference/inlining/codegen is gonna love. The hard part is proving it.

* * *

I hope that helps de-mystify the boxes and anonymous functions. I know just writing this up helped me get a better handle on what’s happening here.

Alright, so, what can we do about this? Well, since it’s at the syntax-level, that means that linting it can be _really_ easy. Just check `Meta.@lower` — no runtime values or types needed. At the same time, since it’s syntax-level, expanding and improving this analysis requires working in [julia-syntax.scm](https://github.com/JuliaLang/julia/blob/master/src/julia-syntax.scm). That’s also why the `let x=x` trick works: it simplifies the scope of the captured variable to a super-trivial block that’s easy on the parser.

I’d love it if we could get the parser to the point where a rule like “only one assignment and no uses before definition” would be sufficient to get the optimized behavior. That’d be my ideal documented rule. I have _absolutely no idea_ how hard that is; I fear the “before definition” part makes it tantamount to the halting problem. I don’t know what the rule is now, but there is one and it’s somewhere between “no other statements or control flow blocks beyond the variable and its closure with a well-defined lifespan” (the `let` trick) and my ideal.

In the meantime, we have `let` workarounds. Perhaps this would be a good impetus for getting [local `const`s](https://github.com/JuliaLang/julia/issues/5148) working — they’ll only become available after 0.7 but maybe that could be an easier task? It’d be a slightly less-annoying workaround, and we already have the syntax for it.

---

_[View the full topic](https://discourse.julialang.org/t/language-restriction-to-solve-15276/10625)._
