Crystal: Don't allow `out` to be used as a variable name

Created on 17 Feb 2017  路  9Comments  路  Source: crystal-lang/crystal

Code to reproduce

When out is used as a variable's name there are unexpected results

require "openssl/cipher"
out = ""
string="test"
cipher = OpenSSL::Cipher.new("AES256")
cipher.decrypt
cipher.key = "somekey"
out = cipher.update(string)
puts typeof(out) # Slice(UInt8)
string = String.new(out, "utf-8") # expecting variable or instance variable after out
Syntax error in src/source.cr:36: expecting variable or instance variable after out

      string = String.new(out, "utf-8")
$ crystal -v                                                                                                               -1-
Crystal 0.20.5 (2017-01-25)

By the way, this happens only when "out" is used as a variable (apparently)
Is it a reserved keyword somehow?
I apologize if this is a user fault, I'm still learning and I'm not sure if this is a compiler or user error

Reference

feature compiler

Most helpful comment

I think either this code should be valid and allowed or the error should be given as soon as you do out = "". It's strange otherwise.

All 9 comments

Hi! Indeed, out is a reserved keyword. See: https://crystal-lang.org/docs/syntax_and_semantics/c_bindings/out.html.

I'm leaving this open because maybe we can link to that document from the syntax error message.

@asterite: as a general rule of thumb, what do you think about linking error messages to the Language Reference? I feel it is a good way of pointing users to relevant design aspects of the language while not bloating error messages.

I think either this code should be valid and allowed or the error should be given as soon as you do out = "". It's strange otherwise.

Yes indeed @lbguilherme, that was exactly my point.
There is no way a reserved keyword should be allowed to be used as a variable (and that's exactly what happens here).
In my opinion, the compiler should give an error as soon as an assignment (or variable declaration) is made

Hadn't noticed that detail. I agree, ideally the compiler should fail on the declaration.

Just wanted to test this, and it appear that the out rule is buggy on usage in implicit return:

def func
  out = "bla"
  out.size
end

puts func # => 3

https://carc.in/#/r/1nd0

What do you mean by buggy? I think it's the same issue that we've been discussing: there's no conflict using "out" as a variable as long as you don't try to use it as a param to call another function or method.

Then the compiler assumes you're using the out keyword and expects a variable name after that.

I don't think it's buggy, it's just a bit confusing/surprising. So maybe we should do as @lbguilherme suggests and just throw an error as soon as you do out = "bla" :).

@mverzilli you're right, not buggy, but kinda confusing/surprising.

out = "bla" being an error is good to me

It would also be a possible solution to allow out as variable name and don't complain about the above code. According to the documentation it should be easily to distinguish between out as a keyword (when followed by a variable or instance variable) and as a variable name.
I don't think this could lead to any problems. Although it is questionable if a keyword should be allowed as variable name at all, even if it is unambiguous.

Also I think we need to error for out as a method name:

def out(foo)
  pp foo
end

out 1      # works
out(out 1) # error: expecting variable or instance variable after out

I think that it's confusing that it works sometimes only. Having a proper error message when trying to define a method named out would resolve this.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

asterite picture asterite  路  3Comments

costajob picture costajob  路  3Comments

grosser picture grosser  路  3Comments

TechMagister picture TechMagister  路  3Comments

asterite picture asterite  路  3Comments