payload: {"action":"created","issue":{"url":"https://api.github.com/repos/JuliaLang/julia/issues/33119","repository_url":"https://api.github.com/repos/JuliaLang/julia","labels_url":"https://api.github.com/repos/JuliaLang/julia/issues/33119/labels{/name}","comments_url":"https://api.github.com/repos/JuliaLang/julia/issues/33119/comments","events_url":"https://api.github.com/repos/JuliaLang/julia/issues/33119/events","html_url":"https://github.com/JuliaLang/julia/pull/33119","id":487276356,"node_id":"MDExOlB1bGxSZXF1ZXN0MzEyNTczNTQy","number":33119,"title":"Adds `Threads.@spawncall`, which evaluates arguments immediately","user":{"login":"NHDaly","id":1582097,"node_id":"MDQ6VXNlcjE1ODIwOTc=","avatar_url":"https://avatars2.githubusercontent.com/u/1582097?v=4","gravatar_id":"","url":"https://api.github.com/users/NHDaly","html_url":"https://github.com/NHDaly","followers_url":"https://api.github.com/users/NHDaly/followers","following_url":"https://api.github.com/users/NHDaly/following{/other_user}","gists_url":"https://api.github.com/users/NHDaly/gists{/gist_id}","starred_url":"https://api.github.com/users/NHDaly/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/NHDaly/subscriptions","organizations_url":"https://api.github.com/users/NHDaly/orgs","repos_url":"https://api.github.com/users/NHDaly/repos","events_url":"https://api.github.com/users/NHDaly/events{/privacy}","received_events_url":"https://api.github.com/users/NHDaly/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":2,"created_at":"2019-08-30T04:13:26Z","updated_at":"2019-08-30T14:58:24Z","closed_at":null,"author_association":"CONTRIBUTOR","pull_request":{"url":"https://api.github.com/repos/JuliaLang/julia/pulls/33119","html_url":"https://github.com/JuliaLang/julia/pull/33119","diff_url":"https://github.com/JuliaLang/julia/pull/33119.diff","patch_url":"https://github.com/JuliaLang/julia/pull/33119.patch"},"body":"Adds a new macro, `Threads.@spawncall`, which evaluates its arguments immediately, then `@spawn`s the closure with the argument values.\r\n\r\nThis acts more like a \"parallel function call\", where the arguments are\r\nevaluated immediately, in the current thread, and the function is then\r\ninvoked in any available thread with the stored argument values.\r\n\r\nThis prevents variables being \"boxed\" when capturing them in the closure.\r\n\r\nThis mirrors the behavior of golangs `go` command, which requires it be used with a function call.\r\n\r\nFixes #30896"},"comment":{"url":"https://api.github.com/repos/JuliaLang/julia/issues/comments/526634181","html_url":"https://github.com/JuliaLang/julia/pull/33119#issuecomment-526634181","issue_url":"https://api.github.com/repos/JuliaLang/julia/issues/33119","id":526634181,"node_id":"MDEyOklzc3VlQ29tbWVudDUyNjYzNDE4MQ==","user":{"login":"NHDaly","id":1582097,"node_id":"MDQ6VXNlcjE1ODIwOTc=","avatar_url":"https://avatars2.githubusercontent.com/u/1582097?v=4","gravatar_id":"","url":"https://api.github.com/users/NHDaly","html_url":"https://github.com/NHDaly","followers_url":"https://api.github.com/users/NHDaly/followers","following_url":"https://api.github.com/users/NHDaly/following{/other_user}","gists_url":"https://api.github.com/users/NHDaly/gists{/gist_id}","starred_url":"https://api.github.com/users/NHDaly/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/NHDaly/subscriptions","organizations_url":"https://api.github.com/users/NHDaly/orgs","repos_url":"https://api.github.com/users/NHDaly/repos","events_url":"https://api.github.com/users/NHDaly/events{/privacy}","received_events_url":"https://api.github.com/users/NHDaly/received_events","type":"User","site_admin":false},"created_at":"2019-08-30T14:58:24Z","updated_at":"2019-08-30T14:58:24Z","author_association":"CONTRIBUTOR","body":"> I am not the biggest fan of adding a new name/verb with subtlety different behavior.\r\n\r\nYeah, i agree, i think that's a reasonable concern. Thanks.\r\n\r\n> I liked Jeff's idea of passing arguments to be evaluated, which seems similar to `let`\r\n\r\nMy concerns with passing arguments to be evaluated are two-fold:\r\n 1. If we require users to specify which arguments to evaluate, it's not functionally much different than just having users use a `let` block. The main motivation I have for introducing something like this is to enable users to super easily write multithreaded function calls (as easy as it is in go) without having to understand the intricacies of scoping and closure capture. I think that if we had a mechanism that was _specific to function calls_, and we encourage its use, then people will just know \"oh i call functions with this verb, and I spawn arbitrary blocks of code with this other verb.\" And then their code will just work as expected without having to understand why sometimes variables are boxed.\r\n 2. I think the syntax is strange and non-obvious. If I just read `@async i j k println(i, j, k)`, i would definitely _not_ understand what the first few arguments were doing there, and i wouldn't know when I was supposed to put them there or not.\r\n\r\n\r\n------------------\r\n\r\nBut yeah, i do agree that it could be non-ideal to have these two verbs that are pretty similar yet subtly different...\r\n\r\nWhat if this also had a different syntax,  not just a different name? That could help distinguish them better?\r\nMaybe something silly like:\r\n```julia\r\nfunction spawnfunc(f)\r\n    (args...; kwargs...) -> @spawn f(args...; kwargs...)\r\nend\r\n```\r\n```julia\r\njulia> spawnfunc(println)(1)\r\n1\r\nTask (done) @0x0000000114d958d0\r\n\r\njulia> fetch(spawnfunc(sort)([3 2; 1 0], dims=2))\r\n2×2 Array{Int64,2}:\r\n 2  3\r\n 0  1\r\n```\r\n"}}
other: {"actor":{"display_login":"NHDaly"}}