This should work:
class Foo
@action : ->
def initialize
@action = -> { }
end
end
Foo.new
Extracted from: https://github.com/crystal-lang/crystal/issues/2666#issuecomment-222317868
Since Void accepts every value, Void? or generally Void|Foo should either degrade into just Void or be disallowed, WDYT?
On second though, I'm not sure about this. For example:
proc1 = ->{ 1 }
proc2 = Proc(Void).new { ... }
proc = rand < 0.5 > proc1 : proc2
value = proc.call
# value should be Void | Int32, not Void
I wouldn't like to mess with types there, and loose some type information. So to solve the snippet in the original comment one can do:
class Foo
@action : ->
def initialize
@action = Proc(Void).new { ... }
end
end
Foo.new
I'll mark it as a draft RFC because this needs more thought.
Actually, that should work, but right now the compiler doesn't distinguish between "assigning something to a variable" and "merging types": when it assigns something to a variable it first merges its type with the type of the right-hand side, and then sets that final type as the instance variable type. I'll try to improve this first.
If we do follow https://github.com/crystal-lang/crystal/issues/2666#issuecomment-222318426 this issue basically vanishes, no?
It vanishes if one explicitly puts nil at the end of the proc. Maybe this should work:
class Foo
@action : -> # Now this would be the same as `-> Nil`
def initialize
@action = -> { 1 } # this is -> Int32, but we said we don't care about the return value,
# so maybe it should work
end
end
Foo.new
I'd say plan forward would to get rid of Void and then tackle this issue for Nil
Most helpful comment
It vanishes if one explicitly puts
nilat the end of the proc. Maybe this should work: