{"action":"created","issue":{"url":"https://api.github.com/repos/JuliaLang/julia/issues/13412","labels_url":"https://api.github.com/repos/JuliaLang/julia/issues/13412/labels{/name}","comments_url":"https://api.github.com/repos/JuliaLang/julia/issues/13412/comments","events_url":"https://api.github.com/repos/JuliaLang/julia/issues/13412/events","html_url":"https://github.com/JuliaLang/julia/pull/13412","id":109391246,"number":13412,"title":"WIP: redesign closures, then generic functions","user":{"login":"JeffBezanson","id":744556,"avatar_url":"https://avatars.githubusercontent.com/u/744556?v=3","gravatar_id":"","url":"https://api.github.com/users/JeffBezanson","html_url":"https://github.com/JeffBezanson","followers_url":"https://api.github.com/users/JeffBezanson/followers","following_url":"https://api.github.com/users/JeffBezanson/following{/other_user}","gists_url":"https://api.github.com/users/JeffBezanson/gists{/gist_id}","starred_url":"https://api.github.com/users/JeffBezanson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JeffBezanson/subscriptions","organizations_url":"https://api.github.com/users/JeffBezanson/orgs","repos_url":"https://api.github.com/users/JeffBezanson/repos","events_url":"https://api.github.com/users/JeffBezanson/events{/privacy}","received_events_url":"https://api.github.com/users/JeffBezanson/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":29,"created_at":"2015-10-01T21:42:45Z","updated_at":"2015-11-06T14:03:41Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/JuliaLang/julia/pulls/13412","html_url":"https://github.com/JuliaLang/julia/pull/13412","diff_url":"https://github.com/JuliaLang/julia/pull/13412.diff","patch_url":"https://github.com/JuliaLang/julia/pull/13412.patch"},"body":"This is a very early preview of the likely future direction for how functions work. It's very much pre-alpha quality but does have a working REPL. I have one cool demo:\r\n\r\n```\r\njulia> function foo()\r\n       a = rand(2000,2000);\r\n       @time 2*a\r\n       @time map(x->2x, a)\r\n       end\r\nfoo (generic function with 1 method)\r\n\r\njulia> foo();\r\n  0.011471 seconds (2 allocations: 30.518 MB, 44.34% gc time)\r\n  0.009771 seconds (2 allocations: 30.518 MB)\r\n\r\njulia> foo();\r\n  0.007800 seconds (2 allocations: 30.518 MB, 23.52% gc time)\r\n  0.006837 seconds (2 allocations: 30.518 MB)\r\n```\r\n\r\nOk, maybe two cool demos:\r\n\r\n```\r\njulia> function inner(a)\r\n        x->a*x\r\n       end\r\ninner (generic function with 1 method)\r\n\r\njulia> f = inner(6)\r\n#2#g0(6)\r\n\r\njulia> f(2)\r\n12\r\n\r\njulia> f.a\r\n6\r\n```\r\n\r\nFastAnonymous.jl, you are in my sights and your days are numbered.\r\n\r\nMy full plan has three stages, the first of which is now almost complete:\r\n\r\n1. Rewrite closures (inner functions) to new types that define `call`.\r\n2. Deprecate the `call` function, and instead put method tables inside TypeName. Remove the `Function` concrete type. All generic functions use the same basic design as closures in stage 1.\r\n3. Fix various problems and redesign parts of Base to exploit this change.\r\n\r\nSome next steps:\r\n\r\n- [ ] Improve typing of closure fields\r\n- [ ] Remove some unnecessary `Box`es\r\n- [ ] Propagate static parameters to closure types\r\n- [ ] `jl_instantiate_staged` is probably a bit buggy\r\n\r\nSome problems to solve:\r\n\r\n1. The situation with some kind of `Callable` type is now more urgent. I'd propose making `Function` an abstract type, and making anonymous functions subtypes of it by default. That will at least handle all the cases in Base where function arguments had `::Function`, and will also handle \"functors\" that had nothing to subtype from before.\r\n1. How to serialize closures? If all code is present on all nodes, then sending closures is actually way more efficient than ever, since you only need to send the (small) environment object. However we need to decide when to send the whole type definition as well.\r\n1. Decide how to deal with inner functions with multiple definitions. Currently they work fine assuming (1) all definitions are in the same basic block, (2) the type signatures can be evaluated at the top level. These are reasonable restrictions, but we need to solidify them and add good error messages etc.\r\n1. This uses way too many gensyms, and the generated names are *horrible*, as in the type of `f` above, `#2#g0`. There should be a nice standard name mangling, e.g. `__hidden__.inner_1`.\r\n1. Figure out how to pass static parameters for `--compile=all` mode. This currently depends on the old implementation of closures.\r\n1. Figure out how (if at all) to mitigate the additional excess code specialization. So far it's actually not too bad; the system image is maybe 10% bigger and the build takes a bit longer, but it's nothing horrible. However after stage 2 this will probably get worse.\r\n"},"comment":{"url":"https://api.github.com/repos/JuliaLang/julia/issues/comments/154416908","html_url":"https://github.com/JuliaLang/julia/pull/13412#issuecomment-154416908","issue_url":"https://api.github.com/repos/JuliaLang/julia/issues/13412","id":154416908,"user":{"login":"mauro3","id":4098145,"avatar_url":"https://avatars.githubusercontent.com/u/4098145?v=3","gravatar_id":"","url":"https://api.github.com/users/mauro3","html_url":"https://github.com/mauro3","followers_url":"https://api.github.com/users/mauro3/followers","following_url":"https://api.github.com/users/mauro3/following{/other_user}","gists_url":"https://api.github.com/users/mauro3/gists{/gist_id}","starred_url":"https://api.github.com/users/mauro3/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mauro3/subscriptions","organizations_url":"https://api.github.com/users/mauro3/orgs","repos_url":"https://api.github.com/users/mauro3/repos","events_url":"https://api.github.com/users/mauro3/events{/privacy}","received_events_url":"https://api.github.com/users/mauro3/received_events","type":"User","site_admin":false},"created_at":"2015-11-06T14:03:41Z","updated_at":"2015-11-06T14:03:41Z","body":"Also, as far as I understand the problem, the example used above by @lstagner and others is not correct:\r\n```julia\r\nfunction Foo{T <: AbstractBar; S}(bar::S)\r\n...\r\nend\r\n```\r\nas the parameter `T` does not occur in the signature.  I think is should read, say:\r\n```julia\r\nfunction Foo{T <: AbstractBar; T, S}(bar::S, ::T) ...\r\n```\r\nthus repetition would still be necessary (unless some extra rules are used)."}}