Julia is pass-by-value, so you can’t modify the caller’sx::Int (unlike Fortran which is pass-by-reference). There is no way to a make a local variable const, though (see also https://github.com/JuliaLang/julia/issues/5148).
I think there is a need for a uniform declaration of an immutable variable in global and local scopes. This helps a lot for correct programming and makes Julia syntax consistent, imo, since one can now declare an immutable struct in Julia.
Making immutability explicit is always a good programming practice, I believe.
I believe a closure might be the best alternative in many instances. See for example Tips and tricks - Optim.jl section on dealing with constant parameters.
A pull request implementing constant local variables would be a welcomed contribution to the language!
Note on terminology: const and immutable are not the same – const refers to a binding which cannot be reassigned; immutable refers to a type whose value cannot be modified. These are orthogonal: one can have a const binding to a mutable value or a non-const binding to an immutable value.
thanks for the clarification. I am only a layman in that respect
My idea is simply to have compile-time constants, as in C++ for instance.
But having explicit immutable declaration is also a nice thing; we have now for structs.
I am now confused. I thought you wanted function arguments to be “constant” (ie presumably error on attempted assignment within the function scope) at runtime, with their values, of course, depending on the caller, so definitely not constant at compile time.
I would really like an orthogonal feature: make const redefinable, via a mechanism similar to what fixed #265. It would be a hint to the compiler so that it can assume unchanged type and value, but redefining would trigger recompilation. (I know I can get this already via myconstant() = value though.)
Regarding your suggestion to use closures – if I have understood that correctly --, consider the following example:
# original function
function foo(x, y)
return x+y
end
# generator for closures on `f`, fixes 2nd argument
function closure_gen(y)
cl(x) = foo(x, y)
return cl
end
# closure
bar = closure_gen(2)
# equivalent function to `bar`
baz(x) = x + 2
println( bar(1) == baz(1) ) # prints 'true': the results match
Could you explain the meaning of Val{n} and function closure_gen(y::Val{n}) where n in your example?
What should one do, if y is an Array or a user-defined type?
I just noticed that in my code I broke the convention stated in the manual:
“For consistency across Julia, the call site should always pass a Valtype rather than creating an instance, i.e., use foo(Val{:bar}) rather than foo(Val{:bar}()).”