Open drewc opened 3 weeks ago
I think this is very important for multiple reasons:
The proper solution is for each interface, we define a method namespace (default: the module namespace + the interface name + the method name, so as drew suggested module#Interface::method
.
The interface macro will emit a linearized list of method names in the interface descriptor, instead of a single unnamespaced one, and similary the prototype creation will resolve for a particular class in the linearized order.
Finally, the defmethod macro will get a interface:
directive to do the proper namespacing at the binding site.
This will leave the global namespace reserved for dynamic dispatch methods, which is a big enough namespace. The restriction will be that you need to namespace your defmethods, but I was planning to enforce that anyway for static type checking and safety.
cc @fare
The issue is simple: dynamic methods have no namespace and interfaces cast to them. Also, different interfaces (aka typeclasses) could have different methods with the same name. And curly's should
{be-not-prefixed 'by-default 'for 'KISS}
In short;
module/name#interface-name::method-name
for the default allows both easy dispatch AND static signature checking while keeping name and module separation to make unintended duplication difficult.The solution is a
namespace:
keyword that acts similar to theextern
one only defaults to the interface name. If it's#f
, no namespace. It could also beprefix:
.So,
(interface foo (bar baz))
will, at prototype, look for and bind thefoo::bar
method. It could then, iffoo::bar
does not exist, look for the:bar
method, and then thebar
method. That solves almost all the problems, right?Then
(interface (bat foo) (xyz n))
could first look for thebat::bar
method before thefoo::bar
et al methods. That allows for some interesting specialization while allowing a hierarchy. outside of class/types.But
(interface (fu namespace: foo) (bar me))
could lookupfoo::bar
as well?Should the prefix actually be
module/name#foo::bar
by default? I think that may be better as I can have interfaces with the same name and same functions but in a different space.So
(rename: food foo)
on an export and then in another module(interface (foo food) (bar baz))
could have ananother/module#foo::bar
first dispatch attempt?Thoughts?