Chained keyword assignment in function call leaks scope

I tried to do a chained keyword assignment in a function call and got the following behavior

julia> function params(;kwargs...)
           for kw in kwargs
               println(kw)
           end
       end
params (generic function with 1 method)

julia> params(a=b=1)
:a => 1

julia> a
ERROR: UndefVarError: `a` not defined in `Main`
Suggestion: check for spelling errors or missing imports.

julia> b
1

I would have expected the paprams-function to print a and b or julia giving an error when called that way. The reason why I expeted this behavior is that I think of a=b=1 to be equivalent to a=1; b=1.
But what actually happens, is that the variable b now lives in the scope in which the function was called and only a is passed as a keyword argument to the function.
Can someone please explain why this is happening.

There is no chained keyword argument syntax. When you write params(a=b=1) it means params(a=(b=1)) which is equivalent to doing b=1; params(a=1). There is no syntax error because the value of a keyword can be an arbitrary expression and since Julia is an expression-oriented language, everything is an expression, including assignments like b=1. This is the kind of thing a syntax linting tool could warn you about though.

3 Likes