# @generated functions aggressively disallowing lambdas (and accusations of impurity! how impious!)

**URL:** https://discourse.julialang.org/t/generated-functions-aggressively-disallowing-lambdas-and-accusations-of-impurity-how-impious/92072
**Category:** Performance
**Tags:** question, generated
**Created:** [December 24, 2022, 1:10am UTC](https://discourse.julialang.org/t/generated-functions-aggressively-disallowing-lambdas-and-accusations-of-impurity-how-impious/92072 "2022-12-24T01:10:36Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### Author: ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)
#### Post date: [December 24, 2022, 1:10am UTC](https://discourse.julialang.org/t/generated-functions-aggressively-disallowing-lambdas-and-accusations-of-impurity-how-impious/92072/1 "2022-12-24T01:10:36Z")

</div>

This seems a bit aggressive:

Code 1:

```julia
julia> @generated f(x) = :( map(i->i, x) )
f (generic function with 1 method)

julia> f((1,2,3))
ERROR: The function body AST defined by this @generated function is not pure. This likely means it contains a closure, a comprehension or a generator.

```

How is the function body not pure? The lambda isn’t capturing anything.

Here’s a simpler example:

Code 2:

```julia
julia> @generated g() = :( x -> x )
g (generic function with 1 method)

julia> g()
ERROR: The function body AST defined by this @generated function is not pure. This likely means it contains a closure, a comprehension or a generator.

```

We can confirm that `g` is pure when not `@generated`:

Code 3:

```julia
julia> g() = x->x
g (generic function with 1 method)

julia> g() === g()
true

```

I suppose maybe in code #1 it’s trying to cover the possibility that this call to an externally-defined function `map` is impure? But if that was it, this should work:

Code 4:

```julia
julia> @generated k(x) = :( α=y->y; α(x) )
k (generic function with 1 method)

julia> k(1)
ERROR: The function body AST defined by this @generated function is not pure. This likely means it contains a closure, a comprehension or a generator.

```

For my use case I wanted a lambda with a capture, which upon construction with its capture I believe to be pure, nested within a greater function I believe also to be pure similar to this:

Code 5:

```julia
julia> @generated h(x, y) = :( map(i->x[i], y) )
h (generic function with 1 method)

julia> h((1,2,3), (1,2,3))
ERROR: The function body AST defined by this @generated function is not pure. This likely means it contains a closure, a comprehension or a generator.

```

I found a way around this by eventually giving up on `@generated` and instead breaking the function into several and using dispatch, but it took a while for me to concede defeat so it made me curious.

According to the [docs](https://docs.julialang.org/en/v1/manual/metaprogramming/#Generated-functions):

> 1. Generated functions must not _mutate_ or _observe_ any non-constant global state (including, for example, IO, locks, non-local dictionaries, or using [`hasmethod`](https://docs.julialang.org/en/v1/base/base/#Base.hasmethod)). This means they can only read global constants, and cannot have any side effects. In other words, they must be completely pure. _ **Due to an implementation limitation, this also means that they currently cannot define a closure or generator.** _

Is the issue maybe that we are simply throwing an erroneous error message, i.e. it is accusing us of defining an impure function when in reality it’s just a limitation of the current implementation?

Or is the issue that the act of hoisting the lambda to global scope on the first function invocation (and thus changing global state) makes the function impure?

Or am I misunderstanding the whole thing somehow?
