[RFC PATCH 0/2] impl specialization and lookup changes
  [Thread Prev] | [Thread Next]
 
 
- Subject: [RFC PATCH 0/2] impl specialization and lookup changes
 - From: Michael Forney <mforney@xxxxxxxxxxx>
 - Date: Sat, 1 Jul 2017 14:43:20 -0700
 - To: myrddin-dev@xxxxxxxxxxxxxx
 
These two patches change how trait declarations are specialized and
looked up.
Here is the motivation:
In libwl, I have one common object struct, and for each interface, a new
type name for object. For error reporting, I need to keep track of the
interface name in the object. In all but one case, I know the type of
object I am creating, so can just create the object with the appropriate
interface name. However, global objects are created with the
wl_registry.bind request, which can return any interface type. The
object interface name is sent in the request to the server.
Currently I have this implemented as a generic function takes an interface
name and returns a @a. However, nothing checks that this interface name
matches the interface type. Ideally I'd be able to define a trait
isobject which declares an interface name.
	trait isobject @o =
		Interface: interface
	;;
However, since the type of Interface does not refer to @o, only one type
can implement it (trait declarations are specialized with a name
based on its type alone).
The first patch adds new syntax
	impl(name, type)
which behaves almost exactly like `name`, except that the trait
parameter is specified explicitly. This change alone is not very useful,
but does allow you to disambiguate a trait declaration when used in a
generic context. For example.
	trait default @a =
		Def: @a
	;;
	impl default int =
		Def = 12
	;;
	const main {
		std.put("Def: {}\n", impl(Def, int))
	}
Otherwise, you'd have to write
	const main {
		var def: int = Def
		std.put("Def: {}\n", def)
	}
in order to choose the implementation of Def you want.
The second patch makes it so trait declarations are specialized by the
trait parameter in addition to the declaration type. This way, multiple
types can implement traits which may have a declaration with a concrete
type (i.e. one that does not allow you to deduce the trait parameter).
With both of the patches together, you can do something like
	trait name @a =
		Name: byte[:]
	;;
	impl name int =
		Name = "int"
	;;
	impl name char =
		Name = "char"
	;;
	generic f = {@a::name
		std.put("name: {}\n", impl(Name, @a))
	}
	const main = {
		f('a')
		std.put("name: {}\n", impl(Name, int))
	}
ALTERNATIVES:
These changes aren't strictly necessary, and can be worked around by
having a trait like
	type tag(@a, @t) = @a
	trait t @a =
		foo: tag(int, @a)
	;;
	impl t bool =
		foo = 6
	;;
	const main = {
		var x: tag(int, bool) = foo
		var y = (x: int)
	}
This seemed awkward enough for me to warrant the changes, which I think
are fairly unobtrusive.
DISCLAIMER:
I am in way over my head with this type inference stuff so I probably
did something wrong in these patches. They probably need a careful
review.
Michael Forney (2):
  Add impl(type, name) to retrieve a particular implementation of a
    trait decl
  Specialize impl declarations on impl type in addition to decl type
 doc/lang.txt               | 12 ++++++++++--
 mbld/deps.myr              |  2 +-
 parse/export.c             |  2 ++
 parse/gram.y               |  6 +++++-
 parse/infer.c              | 34 ++++++++++++++++++++++++----------
 parse/parse.h              |  6 +++---
 parse/specialize.c         | 16 +++++++++++-----
 parse/use.c                |  5 +++++
 test/implexpr-concrete.myr | 15 +++++++++++++++
 test/implexpr.myr          | 18 ++++++++++++++++++
 test/tests                 |  3 ++-
 11 files changed, 96 insertions(+), 23 deletions(-)
 create mode 100644 test/implexpr-concrete.myr
 create mode 100644 test/implexpr.myr
-- 
2.13.2
| [RFC PATCH 1/2] Add impl(type, name) to retrieve a particular implementation of a trait decl | Michael Forney <mforney@xxxxxxxxxxx> | 
| [RFC PATCH 2/2] Specialize impl declarations on impl type in addition to decl type | Michael Forney <mforney@xxxxxxxxxxx> | 
| Re: [RFC PATCH 0/2] impl specialization and lookup changes | Quentin Carbonneaux <quentin@xxxxxx> | 
- Prev by Date: [RFC PATCH 1/2] Add impl(type, name) to retrieve a particular implementation of a trait decl
 - Next by Date: [RFC PATCH 2/2] Specialize impl declarations on impl type in addition to decl type
 - Next by thread: [RFC PATCH 1/2] Add impl(type, name) to retrieve a particular implementation of a trait decl
 - Index(es):