{"action":"created","issue":{"url":"https://api.github.com/repos/JuliaLang/julia/issues/9535","labels_url":"https://api.github.com/repos/JuliaLang/julia/issues/9535/labels{/name}","comments_url":"https://api.github.com/repos/JuliaLang/julia/issues/9535/comments","events_url":"https://api.github.com/repos/JuliaLang/julia/issues/9535/events","html_url":"https://github.com/JuliaLang/julia/issues/9535","id":53219476,"number":9535,"title":"Function argument evaluation grantee and forwarding keyword arguments","user":{"login":"yuyichao","id":712232,"avatar_url":"https://avatars.githubusercontent.com/u/712232?v=3","gravatar_id":"","url":"https://api.github.com/users/yuyichao","html_url":"https://github.com/yuyichao","followers_url":"https://api.github.com/users/yuyichao/followers","following_url":"https://api.github.com/users/yuyichao/following{/other_user}","gists_url":"https://api.github.com/users/yuyichao/gists{/gist_id}","starred_url":"https://api.github.com/users/yuyichao/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yuyichao/subscriptions","organizations_url":"https://api.github.com/users/yuyichao/orgs","repos_url":"https://api.github.com/users/yuyichao/repos","events_url":"https://api.github.com/users/yuyichao/events{/privacy}","received_events_url":"https://api.github.com/users/yuyichao/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/JuliaLang/julia/labels/bug","name":"bug","color":"e10c02"},{"url":"https://api.github.com/repos/JuliaLang/julia/labels/priority","name":"priority","color":"7b07ce"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":9,"created_at":"2015-01-01T13:14:51Z","updated_at":"2015-01-02T14:27:21Z","closed_at":null,"body":"I was trying to figure out what is the order julia evaluate it's arguments (especially when there's keyword arguments passed in different forms). IIRC, python grantee that the arguments are evaluated in the order they appear in the code. Is there similar garentee in julia? I'm sorry if it is already in the document but at least I didn't find anything when I look through the page about functions.\r\n\r\nI was trying to figure out the current order myself with some code and I see the following very unexpected result.\r\n\r\n```julia\r\njulia> function get_next()\r\n           global counter\r\n           counter = counter + 1\r\n           return counter\r\n       end\r\nget_next (generic function with 1 method)\r\n\r\njulia> \r\n\r\njulia> function get_type(typ::Type)\r\n           id = get_next()\r\n           println(\"$id: $typ\")\r\n           return typ\r\n       end\r\nget_type (generic function with 1 method)\r\n\r\njulia> \r\n\r\njulia> function f(args...; kws...)\r\n           println((args, kws))\r\n       end\r\nf (generic function with 1 method)\r\n\r\njulia> \r\n\r\njulia> counter = 1\r\n1\r\n\r\njulia> f(get_next(), a=get_next(), get_next()::get_type(Int),\r\n         b=get_next(), get_next()::get_type(Number),\r\n         [get_next(), get_next()]...; c=get_next(),\r\n         [(:d, get_next()), (:f, get_next())]...)\r\n9: Int64\r\n11: Number\r\n((13,13,13,13,13),Any[(:a,13),(:b,13),(:c,13),(:d,3),(:f,3)])\r\n\r\njulia> \r\n\r\njulia> counter = 1\r\n1\r\n\r\njulia> f(get_next(),; c=get_next(), [(:d, get_next()), (:f, get_next())]...)\r\n((5,),Any[(:c,5),(:d,3),(:f,3)])\r\n\r\njulia> counter = 1\r\n1                                                                                  \r\n                                                                                   \r\njulia> f(get_next(), a=get_next(), get_next()::get_type(Int),\r\n         b=get_next(), get_next()::get_type(Number),\r\n         [get_next(), get_next()]...; c=get_next())\r\n7: Int64                                                                           \r\n9: Number                                                                          \r\n((5,6,8,10,11),Any[(:a,2),(:b,3),(:c,4)])                                          \r\n\r\njulia> counter = 1\r\n1\r\n\r\njulia> kws = [(:d, get_next()), (:f, get_next())]\r\n2-element Array{(Symbol,Int64),1}:\r\n (:d,2)\r\n (:f,3)\r\n\r\njulia> f(get_next(), a=get_next(), get_next()::get_type(Int),\r\n         b=get_next(), get_next()::get_type(Number),\r\n         [get_next(), get_next()]...; c=get_next(),\r\n         kws...)\r\n9: Int64\r\n11: Number\r\n((13,13,13,13,13),Any[(:a,13),(:b,13),(:c,13),(:d,2),(:f,3)])\r\n```\r\n\r\nAs shown above in the REPL output, the arguments passed to the function are fine as long as I'm not passing (/forwarding) keyword arguments with the `(;kw...)` syntax (is there a name for it?) and the arguments are evaluated in the order they appear in the code with the keyword arguments first and then the positional ones. However, whenever I'm trying to forward some keyword arguments, the whole thing gets messed up and the `get_next` function \"appears to\" return same value for multiple calls.\r\n\r\nThis issue disappears when I tweak the `get_next` function\r\n```julia\r\njulia> function get_next()\r\n           global counter\r\n           counter = counter + 1\r\n           res = counter\r\n           return res\r\n       end\r\nget_next (generic function with 1 method)\r\n\r\njulia> counter = 1\r\n1\r\n\r\njulia> f(get_next(),; c=get_next(), [(:d, get_next()), (:f, get_next())]...)\r\n((5,),Any[(:c,4),(:d,2),(:f,3)])\r\n\r\njulia> counter = 1\r\n1\r\n\r\njulia> f(get_next(),; c=get_next(), [(:d, get_next()), (:f, get_next())]..., [(:e, get_next()), (:g, get_next())]...)\r\n((7,),Any[(:c,6),(:d,2),(:f,3),(:e,4),(:g,5)])\r\n```\r\n\r\nIt seems like sth related to the compiler/optimizer to me. It also shows that the forwarded kw args are evaluated before everything else (which is fine as long as it's consistent but a little bit weird....)\r\n"},"comment":{"url":"https://api.github.com/repos/JuliaLang/julia/issues/comments/68529662","html_url":"https://github.com/JuliaLang/julia/issues/9535#issuecomment-68529662","issue_url":"https://api.github.com/repos/JuliaLang/julia/issues/9535","id":68529662,"user":{"login":"yuyichao","id":712232,"avatar_url":"https://avatars.githubusercontent.com/u/712232?v=3","gravatar_id":"","url":"https://api.github.com/users/yuyichao","html_url":"https://github.com/yuyichao","followers_url":"https://api.github.com/users/yuyichao/followers","following_url":"https://api.github.com/users/yuyichao/following{/other_user}","gists_url":"https://api.github.com/users/yuyichao/gists{/gist_id}","starred_url":"https://api.github.com/users/yuyichao/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yuyichao/subscriptions","organizations_url":"https://api.github.com/users/yuyichao/orgs","repos_url":"https://api.github.com/users/yuyichao/repos","events_url":"https://api.github.com/users/yuyichao/events{/privacy}","received_events_url":"https://api.github.com/users/yuyichao/received_events","type":"User","site_admin":false},"created_at":"2015-01-02T14:27:20Z","updated_at":"2015-01-02T14:27:20Z","body":"The issue is with this part\r\n```julia\r\ncounter = counter + 1::Any\r\ncounter = counter + 1::Any\r\n#s449 = vcat((top(tuple))(:d,counter)::(Symbol,Any),(top(tuple))(:f,counter)::(Symbol,Any))::Any\r\n```\r\nThe compiler decided to increment the global variable twice before the value is used. Type inference not being able to decide the type of counter is not the issue here\r\n"}}