Why is constness not respected inside these julia functions?
Asked Answered
F

1

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"

Footed answered 23/2, 2017 at 17:15 Comment(4)
"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.Angeli
@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).Footed
I am talking about a type declaration, not a type assertion. Syntactically they look similar, but they are different. See the documentation page on itAngeli
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 ...Footed
D
8

Because const in local scope is not yet implemented:

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

Diencephalon answered 23/2, 2017 at 17:30 Comment(2)
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?Footed
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.Diencephalon

© 2022 - 2024 — McMap. All rights reserved.