Crystal: Adding type restriction to ivar makes compiler fail

Created on 20 Jun 2018  路  7Comments  路  Source: crystal-lang/crystal

Reproducible code:

class Foo
  @bar : Int32 = uninitialized Int32
end

Fails at compile time:

Error in line 2: undefined method 'uninitialized'

While:

class Foo
  @bar = uninitialized Int32
end

Works just as expected, i.e. the programs compiles, and Foo@bar is not initialized.

Crystal version and OS

% crystal -v 
Crystal 0.25.0 (2018-06-12)

LLVM: 6.0.0
Default target: x86_64-pc-linux-gnu

% uname -mors
Linux 4.17.2-1-ARCH x86_64 GNU/Linux

All 7 comments

uninitialized is a fixed construct. The only valid syntax is one of these:

name = uninitialized Type
@name = uninitialized Type
@@name = uninitialized Type

That means this is not valid syntax:

@name : Int32 = uninitialized Type

This is not a bug.

I know x = uninitialized Type is not consistent with the rest of the language, but, well, it's not something that should be used, ever. There's always a better solution. It just exists to implement super low-level stuff. In fact, maybe it should be removed from the language altogether and just pay for the small performance hit whenever its used.

At least it seems to me that using uninitialized is very practical to use with C bindings and ivars. As long as it is done properly.

I ran into this trying to write some simple getters:

class Foo
  getter bar : Int32 = uninitialized Int32
end
% crystal foo.cr
Error in line 2: expanding macro

in macro 'getter' expanded macro: macro_94066989783344:113, line 4:

   1.       
   2.         
   3.           
>  4.             @bar : Int32 = uninitialized(Int32)
   5. 
   6.             def bar : Int32
   7.               @bar
   8.             end
   9.           
  10.         
  11.       
  12.     

undefined method 'uninitialized'

As long as it is done properly.

Doing it properly means what @asterite said.

What's your issue with that?

@bar = uninitialized Int32
getter bar : Int32

Don't use uninitialized. You really don't need it.

What are you trying to do?

Yes. I really don't need it, but I found it to work, hence I use it. There are safer ways, I still use this.

I am not trying to convince you that people should use it, I am trying to tell you:

getter bar : Type = uninitialized Type

fails. Because this only fails when using uninitialized with type restrictions, and getter requires to specify type after ivar name. I think that the current behaviour is not optimal.

I think it is optimal: it's harder for you to use uninitialized variables, and that's a good thing in my opinion.

Closing. As stated above this is by design. Please use alternatives. Thanks!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sergey-kucher picture sergey-kucher  路  66Comments

asterite picture asterite  路  139Comments

asterite picture asterite  路  70Comments

asterite picture asterite  路  71Comments

chocolateboy picture chocolateboy  路  87Comments