-
Notifications
You must be signed in to change notification settings - Fork 216
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
Proposal: making Class
and Module
classes generic -- Class[I]
and Module[I]
#1542
Comments
I'm not sure if adding a generic parameter to I'm curious if there are more use cases. |
You are correct, the class << SINGLETON = Superclass.new
def my_singleton_method … and the current workaround is: SINGLETON: Superclass & _SINGLETON
interface _SINGLETON
def my_singleton_method …
class Class[I]
# The attached objects of singleton classes is the only “instance” they can have,
# vs. regular classes that have `#allocate`/`#new`
def attached_object: () -> I
# This is `[T < I] (Class[T]) -> void` with the ineffective `[T]` flattened.
def inherited: (Class[I]) -> void
# ditto
def subclasses: () -> Array[Class[I]]
# If RBS has explicit countervariance like Java does…
def superclass: [I < T] () -> Class[T]
end The top post also includes an abstraction of a user use case. Here’s my use case unabstracted. |
If I may jump in, but i'd consider reserving that syntax to solve either module mixins, or delegation, both of which aren't yet solved in rbs. module A[B]
# A mixin of B, meaning methods of A can call functions defined in B
# or
class A[B]
# class a delegates methods to B, could also solve the "delegate" stdlib |
of coarse you may
Let type variables go wild and do crazy things – module A[B]
include B
… |
Another use case: https://rubydoc.info/gems/ffi/1.16.3/FFI/StructByReference |
Another use case in resolv: #1655 We could type
|
Module[I]
Class
and Module
classes generic -- Class[I]
and Module[I]
I prefer extending generics upper bounds for resolv: class Resolv::DNS::Resource::Generic < Resolv::DNS::Resource
def self.create: [T < singleton(Generic)] (Integer type_value, Integer class_value) -> T
end ( |
Having played with RBS and Steep, I found this is already syntactically valid in RBS but is not yet supported by Steep for type checking. Is this right? I thought class Resolv::DNS::Resource::Generic < Resolv::DNS::Resource
def self.create: (Integer type_value, Integer class_value) -> singleton(Generic)
end NB. |
Right... I forgot it... |
Before, And similarly, String.singleton_class.singleton_class #=> #<Class:#<Class:String>> The implementation this proposal (or at least the shortcomings of |
Currently, we model module/class themselves (as opposed to
instance
s) assingleton(Klass)
, whereas theModule
/Class
classes can only represent the module/class ofuntyped
.I suggest combining those two by giving
Module
andClass
a type variable representing their instances. For example,Class[String]
(andModule[String]
too to under covariance) is equivlaent tosingleton(String)
.For backward compatibility,
singleton(I)
can be a alternate (read: legacy) syntax forModule[I]
.The immediate benefit is
Class[I]
RBS finally able to writedef new: (…) -> I
anddef allocate: () -> I
(rather than expecting type checkers to infer fromsingleton(I)
).Speaking of
singleton(I)
—rbs/docs/syntax.md
Line 9 in 6e5a289
[I < Bound] … singleton(I)
is invalid. (Update: this is #558)[I < singleton(Bound)] -> I
works the limitation around, but what ifI
has other duties?This is also how Java does it (as early as their type args were born).
The text was updated successfully, but these errors were encountered: