Use a not exists Type in the arg default value not raise compile error?

Following code actually compiled and run correctly

class Foo
  def self.foo(arg = AAA.new)
    p! arg
  end
end

p! Foo.foo("hello")

if this is the case there exists a AAA, but i misuse it, the result is accepted, but, i never defined the AAA!

I consider a language that claims type safe can’t handle this, it’s not quite right, any idea? I don’t want to always use editor to search and replace this type issue, but instead, i hope compiler can handle this for me, this is one of the key reason I use Crystal instead of Ruby.

1 Like

You aren’t type restricting the argument so the compiler believes it is a AAA | String.

class Foo
  def self.foo(arg : AAA = AAA.new)
    p! arg
  end
end

p! Foo.foo("hello") #=> Error: Waaah

Crystal has type inference which allows us to not always have to type-restrict variables, and instead allow “any” values to be passed through to create a union type.

https://carc.in/#/r/heox

You aren’t type restricting the argument so the compiler believes it is a AAA | String.

Yes, I know, in fact, i have another similar question asked several days ago, but, i still consider this is not acceptable, both case not all same, that is a literal, but, this time exactly a Type, it don’t want use Ruby back.

I commented on the original post, but my advice here is the same. You can’t treat Crystal like Ruby.

I’m pretty sure this is basically the same problem/feature of Crystal in which it doesn’t do semantic analysis on unused code. I.e. since the default value is never used, it’s essentially removed from the final binary, hence there is no problem. Same idea as:

class Foo
  # This is never used so it's optimized out so you don't get an error that the method doesn't exist.
  def test
    some_method_that_doesnt_exist
  end
  
  def test2
    pp "foo"
  end
end

Foo.new.test2
4 Likes

Wow, this is very interesting. (Personally, I find these imperfections fascinating, like Easter eggs, but I’m sure there are many who don’t.)