You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Original bug ID: 1375 Reporter: administrator Assigned to:@garrigue Status: assigned (set by @mshinwell on 2016-12-07T17:08:53Z) Resolution: open Priority: normal Severity: feature Category: typing
Bug description
I find that when I'm writing types of objects, there are a lot more
type variables running around than I need. The fundamental cause of
this appears to be that it is possible to inherit from any class, so
the type of "self" for an object is never constant; it always has to
be a type variable just in case the present object is a subclass of
the object that's presently being defined.
In practice, it seems that many of the classes I write will never have
a subclass and these type variables are unnecessary. I'd like to be
able to declare that a class will never have a subclass, and then the
compiler will be willing to unify constant types with the type of
self. In this case, of course, any attempt to inherit the class
should get an error.
Here's some sample code illustrating the situation. The comment at
the end shows how I'd like to be able to write the last class.
I suspect method invocation on a final class could be more efficient
than method invocation in the general case, too.
Any comments on whether this is a good idea?
--
Tim Freeman tim@fungible.com
GPG public key fingerprint ECDF 46F8 3B80 BB9E 575D 7180 76DF FE00 34B1 5C78
(* The real hierarchy_node is exported by a package that displays trees of
nodes in general. The type variables are necessary. *)
class type hierarchy_node = object ('node)
method children: 'node array
end
(* I can believe the type variables are necessary here, too. *)
class type nodetype =
object ('node)
constraint 'node = #hierarchy_node
method children: 'node array
method add_child: 'node -> unit
method parent: 'node option
end
(* I omitted a bunch of code here that uses nodetype (above) and is used by
omitted methods on node (below). This is why I have to separate the
declaration of nodetype from the declaration of node. *)
(* I don't think the type variables in the definition of node make anything
better at all. Fundamentally, node has to be polymorphic when considering
its own class so we can cope with taking a subclass of node.
But I know that I don't want to take any subclasses, so I'd rather not have
the polymorphism. I'd like the option of telling the compiler this so I
could avoid type variables I don't need. *)
initializer
match parent with
None -> ()
| Some p -> p#add_child self
method children: 'node array = children
method add_child (n: 'node): unit =
assert (n#parent = Some self);
for i = 0 to Array.length children - 1 do
assert (n != children.(i));
done;
children <- Array.append children [|n|]
method parent: 'node option = parent
end
(* I propose that the way to tell the compiler that the class will never have a
subclass is by using the new keyword "final", as in Java. Then I could
write something like this instead:
class final node ~(parent: node option): nodetype =
object self
val mutable children: node array = [||]
initializer
match parent with
None -> ()
| Some p -> p#add_child self
method children: node array = children
method add_child (n: node): unit =
assert (n#parent = Some self);
for i = 0 to Array.length children - 1 do
assert (n != children.(i));
done;
children <- Array.append children [|n|]
method parent: node option = parent
end
*)
The text was updated successfully, but these errors were encountered:
I came over your request from september 2002 while looking at feature wishes.
I find that when I'm writing types of objects, there are a lot more
type variables running around than I need. The fundamental cause of
this appears to be that it is possible to inherit from any class, so
the type of "self" for an object is never constant; it always has to
be a type variable just in case the present object is a subclass of
the object that's presently being defined.
In practice, it seems that many of the classes I write will never have
a subclass and these type variables are unnecessary. I'd like to be
able to declare that a class will never have a subclass, and then the
compiler will be willing to unify constant types with the type of
self. In this case, of course, any attempt to inherit the class
should get an error.
Here's some sample code illustrating the situation. The comment at
the end shows how I'd like to be able to write the last class.
I suspect method invocation on a final class could be more efficient
than method invocation in the general case, too.
Any comments on whether this is a good idea?
Well, classes are just about being able to inherit, so your request seems
surprising at first. And in general final is intended to allow compiler
optimizations, not to simplify typing.
This said, you are right that the way subclassing is handled in ocaml makes
typing more complex, especially when you want to store objects of the same
class in fields.
This has been somehow solved by the introduction of immediate objects: since
you cannot inherit from them, they are typed as final classes; i.e. self is
of the type of the class being defined, not that of any subclass.
The only limitation compared to the final classes you suggest is that an
immediate object does not define a type: you must define your type
independently,
but there is no need for spurious type variables there.
Does this solve your problem? And can we say that you wish was (inadvertently)
granted?
This issue has been open one year with no activity. Consequently, it is being marked with the "stale" label. What this means is that the issue will be automatically closed in 30 days unless more comments are added or the "stale" label is removed. Comments that provide new information on the issue are especially welcome: is it still reproducible? did it appear in other contexts? how critical is it? etc.
Original bug ID: 1375
Reporter: administrator
Assigned to: @garrigue
Status: assigned (set by @mshinwell on 2016-12-07T17:08:53Z)
Resolution: open
Priority: normal
Severity: feature
Category: typing
Bug description
I find that when I'm writing types of objects, there are a lot more
type variables running around than I need. The fundamental cause of
this appears to be that it is possible to inherit from any class, so
the type of "self" for an object is never constant; it always has to
be a type variable just in case the present object is a subclass of
the object that's presently being defined.
In practice, it seems that many of the classes I write will never have
a subclass and these type variables are unnecessary. I'd like to be
able to declare that a class will never have a subclass, and then the
compiler will be willing to unify constant types with the type of
self. In this case, of course, any attempt to inherit the class
should get an error.
Here's some sample code illustrating the situation. The comment at
the end shows how I'd like to be able to write the last class.
I suspect method invocation on a final class could be more efficient
than method invocation in the general case, too.
Any comments on whether this is a good idea?
--
Tim Freeman
tim@fungible.com
GPG public key fingerprint ECDF 46F8 3B80 BB9E 575D 7180 76DF FE00 34B1 5C78
(* The real hierarchy_node is exported by a package that displays trees of
nodes in general. The type variables are necessary. *)
class type hierarchy_node = object ('node)
method children: 'node array
end
(* I can believe the type variables are necessary here, too. *)
class type nodetype =
object ('node)
constraint 'node = #hierarchy_node
method children: 'node array
method add_child: 'node -> unit
method parent: 'node option
end
(* I omitted a bunch of code here that uses nodetype (above) and is used by
omitted methods on node (below). This is why I have to separate the
declaration of nodetype from the declaration of node. *)
(* I don't think the type variables in the definition of node make anything
better at all. Fundamentally, node has to be polymorphic when considering
its own class so we can cope with taking a subclass of node.
But I know that I don't want to take any subclasses, so I'd rather not have
the polymorphism. I'd like the option of telling the compiler this so I
could avoid type variables I don't need. *)
class node ~(parent: 'node option) =
object (self: 'node)
constraint 'node = #nodetype
val mutable children: 'node array = [||]
initializer
match parent with
None -> ()
| Some p -> p#add_child self
method children: 'node array = children
method add_child (n: 'node): unit =
assert (n#parent = Some self);
for i = 0 to Array.length children - 1 do
assert (n != children.(i));
done;
children <- Array.append children [|n|]
method parent: 'node option = parent
end
(* I propose that the way to tell the compiler that the class will never have a
subclass is by using the new keyword "final", as in Java. Then I could
write something like this instead:
class final node ~(parent: node option): nodetype =
object self
val mutable children: node array = [||]
initializer
match parent with
None -> ()
| Some p -> p#add_child self
method children: node array = children
method add_child (n: node): unit =
assert (n#parent = Some self);
for i = 0 to Array.length children - 1 do
assert (n != children.(i));
done;
children <- Array.append children [|n|]
method parent: node option = parent
end
*)
The text was updated successfully, but these errors were encountered: