6

Prompted by Lyndon's question earlier today:

a.

julia> function f1(x::Float64) 
         const y = x;
         y = "This should throw an error since y is of constant type";
         return y;
       end
f1 (generic function with 1 method)

julia> f1(1.0)
"This should throw an error since y is of constant type"

Why does the const keyword not work as expected here? (i.e., disallow assigning a string to y which has been declared as const).

b.

julia> function f2(x::Float64)
         show(x);
         const x = 1.;
       end
f2 (generic function with 1 method)

julia> f2(1.0)
ERROR: UndefVarError: x not defined
Stacktrace:
 [1] f2(::Float64) at ./REPL[1]:2

Why does defining x as const on line 3 affect the value of x on line 2?

c.

In particular, this prevents me from doing:

function f(x::Float64)
  const x = x; # ensure x cannot change type, to simulate "strong typing"
  x = "This should throw an error";
end

I was going to offer this as a way to simulate "strong typing", with regard to Lyndon's "counterexample" comment, but it backfired on me, since this function breaks at line 2, rather than line 3 as I expected it to.

What is causing this behaviour? Would this be considered a bug, or intentional behaviour?

Naming conventions aside, is there a more acceptable way to prevent an argument passed into a function from having its type altered?
(as in, is there a defined and appropriate way to do this: I'm not after workarounds, e.g. creating a wrapper that converts x to an immutable type etc)

EDIT:

So far, this is the only variant that allows me to enforce constness in a function, but it still requires the introduction of a new variable name:

julia> function f(x::Float64)
         const x_const::Float64 = x;
         x_const = "helle"; # this will break, as expected
       end

but even then, the error just complains of an "invalid conversion from string to float" rather than an "invalid redefinition of a constant"

Community
  • 1
  • 1
Tasos Papastylianou
  • 21,371
  • 2
  • 28
  • 57
  • 1
    "I was going to offer this as a way to simulate "strong typing", with regard to Lyndon's "counterexample" comment". For "strong typing" in functions, you'd use a type-declaration, not a const. `local a::Float64 = 2.0`. That can't change types. – Chris Rackauckas Feb 23 '17 at 18:28
  • @ChrisRackauckas yes, I believe that's what's happening with the snippet at the end; const is superfluous there and what's actually enforcing the type is the type assertion; Stefan's answer seems to confirm this. What is interesting to me however is why the type assertion of a local variable introduced as an argument is not enforced in the same way! Or, conversely, why the typeassertion of a local variable is carried forward to subsequent assignments to begin with; semantically it's not clear to me that this should necessarily be the case (i.e. in the absence of an explicit `const` statement). – Tasos Papastylianou Feb 23 '17 at 19:48
  • 1
    I am talking about a type declaration, not a type assertion. Syntactically they look similar, but they are different. See [the documentation page on it](http://docs.julialang.org/en/stable/manual/types/#type-declarations) – Chris Rackauckas Feb 23 '17 at 19:50
  • Thanks, I wasn't aware of the distinction in terminology and semantics! So presumably this means, specifying a type for an input parameter only acts as an assertion rather than a type declaration. Interesting ... – Tasos Papastylianou Feb 23 '17 at 20:02

1 Answers1

8

Because const in local scope is not yet implemented:

https://github.com/JuliaLang/julia/issues/5148

StefanKarpinski
  • 32,404
  • 10
  • 86
  • 111
  • I see. Is this "not yet implemented" behaviour? Or is it intentional? (not entirely clear from the github link). And presumaly the behaviour of **b,** is just a bug then? – Tasos Papastylianou Feb 23 '17 at 17:39
  • 1
    It's not yet implemented. If someone made a good PR to address this, it would be accepted. (b) does seem to be a bug. – StefanKarpinski Feb 23 '17 at 21:08