# Is there a way to create task from not yet defined function without eval?

**URL:** <https://discourse.julialang.org/t/is-there-a-way-to-create-task-from-not-yet-defined-function-without-eval/109961>\
**Category:** General Usage\
**Created:** [February 9, 2024, 12:47am UTC](https://discourse.julialang.org/t/is-there-a-way-to-create-task-from-not-yet-defined-function-without-eval/109961 "2024-02-09T00:47:19Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Dandan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dandan/32/8935_2.png) [@Dandan](https://discourse.julialang.org/u/Dandan)\
**Post date:** [February 9, 2024, 12:47am UTC](https://discourse.julialang.org/t/is-there-a-way-to-create-task-from-not-yet-defined-function-without-eval/109961/1 "2024-02-09T00:47:19Z")

</div>

I have a code like this

```julia
jobs = []

function main()
    while true
        sleep(1)
        for j in jobs
            @async j()
        end
    end
end

# f() = println("f") # this works
@async main()
f() = println("f") # doesn't work

push!(jobs, f)

```

The problem is the following. If I define a function f and add it to the jobs collection after starting `@async main()` then it does nothing (it works if `f` is defined before). I can fix it by using eval around `@async j()` but I’m wondering is there a better approach? I’ve tried defining a macro, but with no success. Also, what’s the reason for this? I thought that task is like a function that accepts function as input.

---

<div class="post-metadata">

**Author:** ![mrufsvold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrufsvold/32/31600_2.png) [@mrufsvold](https://discourse.julialang.org/u/mrufsvold)\
**Post date:** [February 9, 2024, 1:13am UTC](https://discourse.julialang.org/t/is-there-a-way-to-create-task-from-not-yet-defined-function-without-eval/109961/2 "2024-02-09T01:13:40Z")

</div>

Can you give a full MWE where you’re defining the jobs too? Hard to diagnose the problem without the whole context.

---

<div class="post-metadata">

**Author:** ![Dandan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dandan/32/8935_2.png) [@Dandan](https://discourse.julialang.org/u/Dandan)\
**Post date:** [February 9, 2024, 6:54am UTC](https://discourse.julialang.org/t/is-there-a-way-to-create-task-from-not-yet-defined-function-without-eval/109961/3 "2024-02-09T06:54:14Z")

</div>

Edited the question for clarity

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [February 9, 2024, 7:12am UTC](https://discourse.julialang.org/t/is-there-a-way-to-create-task-from-not-yet-defined-function-without-eval/109961/4 "2024-02-09T07:12:00Z")

</div>

If you modify your `main` like so:

> [@Dandan](#):
>
> ```julia
> for j in jobs
> t = @async j()
> display(t)
> end
> 
> ```

You’ll get this output when you `push!(jobs, f)`:

```julia
julia> Task (failed) @0x000076edaa7c95f0
julia> MethodError: no method matching f()
The function `f` exists, but no method is defined for this combination of argument types.

Closest candidates are:
  f() (method too new to be called from this world context.)
   @ Main REPL[4]:1

Stacktrace:
 [1] (::var"#3#4"{typeof(f)})()
   @ Main ./REPL[2]:5
Task (failed) @0x000076eda78007e0

```

Note the “method too new to be called from this world context” bit. This is because methods can only call other methods that are “at least as old” as themselves. You can use `invokelatest` to get around this, though in general it’s better (for precompilability, type stability etc) to design your program in such a way that you don’t rely on being able to call methods defined after you start your program.

---

<div class="post-metadata">

**Author:** ![Dandan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dandan/32/8935_2.png) [@Dandan](https://discourse.julialang.org/u/Dandan)\
**Post date:** [February 9, 2024, 7:29am UTC](https://discourse.julialang.org/t/is-there-a-way-to-create-task-from-not-yet-defined-function-without-eval/109961/5 "2024-02-09T07:29:23Z")

</div>

Thanks!

`invokelatest` works and I understand that it’s better to define methods before calling them, in general. I thought that async execution of main could take into account the changing “world order”.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [February 9, 2024, 7:35am UTC](https://discourse.julialang.org/t/is-there-a-way-to-create-task-from-not-yet-defined-function-without-eval/109961/6 "2024-02-09T07:35:02Z")

</div>

> [@Dandan](#):
>
> I thought that async execution of main could take into account the changing “world order”.

At the most fundamental level, it can’t! The way `eval` (which is what happens when a new method/object is defined) is limited in Julia is precisely what allows it to be compiled to native code ahead of time, instead of having to insert dynamic lookups every time you call a function, in spite of being a semantically dynamic language.

---

<div class="post-metadata">

**Author:** ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)\
**Post date:** [February 9, 2024, 7:39am UTC](https://discourse.julialang.org/t/is-there-a-way-to-create-task-from-not-yet-defined-function-without-eval/109961/7 "2024-02-09T07:39:56Z")

</div>

> [@Dandan](#):
>
> the changing “world order”.

👁⃤
