Skip to content

First-class impls? #262

@osa1

Description

@osa1

Here's an alternative fix to #261: we make impls first-class and allow users to create and manipulate them.

  • Conceptually, an impl block becomes a record of functions. (i.e. dictionaries)
  • When calling a generic function with predicates, we implicitly synthesize and pass the records.
  • However we also allow user to pass them explicitly, probably using the type application syntax.
  • We also allow manipulating existing impls and creating new ones.
  • When compiling generic functions with predicates, we monomorphise based on the impls passed (same as today).

When compiling explicit impl passing, we have two options:

  1. We may have a notion of "const" expressions (like in most languages these days) and require the record exprs to be consts.
  2. We may monomorphise the function to take a record object in runtime and call the functions in the record.

I think we may need something like (2) regardless, to support trait objects. So maybe we implement that first and then reuse.

Lots of details to figure out, but here's a simple example:

# In the standard library:
impl[ToDoc[t]] ToDoc[Vec[t]]:
    toDoc(self: Vec[t]) Doc:
        ...


# In a third-party library:
debug[ToDoc[t]](...):
    ...

Then in my code I want to use debug on a Vec[U32], but print the numbers in hex. I need a record for ToDoc[Vec[U32]] that will call something else other than toDoc on the elements. This will require a new syntax. Note that I may not have access to Vec's toDoc function here. I want to reuse it here, just overriding ToDoc[t] parts.

Just an idea:

debug[ToDoc[Vec[U32]] with ToDoc[U32] = (toDoc = toHexDoc)](myVec)

The (toDoc = toHexDoc) part is the record. with syntax specifies the predicate on the impl, in impl[ToDoc[t]] ToDoc[Vec[t]]: ....

Another idea: we allow naming impl blocks and have another ToDoc[U32] that prints in hex. Then use that named impl:

impl ToDoc[U32] as U32ToDocInHex:       # `as` gives name to the `impl`
    ...


debug[ToDoc[Vec[U32]] with U32ToDocInHex](...)

Here ToDoc[Vec[U32]] with U32ToDocInHex synthesizes a new impl for ToDoc[Vec[U32]] using U32ToDocInHex for ToDoc[U32], instead of the default one.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions