-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Type restriction should upcast #2729
Comments
smaller example https://carc.in/#/r/10la class A
end
class B < A
end
def foo(a : A)
p typeof(a)
end
foo B.new # => B, expected A |
@jhass the right behavior should be return |
I would say so, yes. |
Crystal only uses the type restriction in methods to choose. It does not restrict or use the type information during body method. For example the following compiles and runs: https://play.crystal-lang.org/#/r/10nc def change(a : Enumerable)
a[0] = 3
end
b = [1,2,3]
pp b # => b = [1, 2, 3]
change b
pp b # => b = [3, 2, 3] The motivation is that it is the nearest behavior to an unrestricted method: def change(a)
a[0] = 3
end I did raise this to @asterite in the past and what I exhibit here is more or less the sample he use to explain why he thinks it should work as it is. And we can't solve the issue @chenkovsky / @jhass shows without loosing the working samples posted in this comment. |
I guess I simply disagree that they should work and that they do work is expected. |
Also: def foo(x : Int)
# I don't want x to be of type Int, just restrict it's type
y = x.to_i32
end And many, many more cases like that. That's why they are called "type restrictions" and not just "argument types". I'd leave this as an RFC or close it. It's a fundamental part of the language that, if changed, will break everything. So it basically needs to be reconsidered once the language evolves a bit more. |
That makes the initial issue a duplicate of #1297 I guess. |
@jhass I still have mixed feelings too :-). The surprise factor is as your minimal example, that the static typeof of the argument does not match the type restriction. It feels too different from what it is used, even not formal, but is because we are narrow to the classic formalism or way to read the functions declarations. I don't see it a duplicate of #1297. There, the question is how generic arguments should participate in the type restrictions or eventually in |
Personally I like the current concept of restriction. Maybe it should be more clearly explained in docs, with increased clearer knowledge among crystal users (many probably assume semantics from syntactic similarity to other typed languages), and then perhaps some one comes up with a better/refined idea, otherwise I think it's neat. |
I'm closing this. A type restriction is just that: a restriction. The examples for def foo(x : Enumerable)
x.first
end
typeof(foo([1,2, 3])) # => Object It's Object, according to this proposal, because Given that you are using a type restriction def foo(x : A)
arr = [x] of A
end and problem solved. |
example
no overload matches 'Array(C)#<<' with type A+
Overloads are:
Couldn't find overloads for these types:
The text was updated successfully, but these errors were encountered: