Skip to content
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

Extending type modules #3327

Closed
janmasrovira opened this issue Feb 13, 2025 · 4 comments · Fixed by #3336
Closed

Extending type modules #3327

janmasrovira opened this issue Feb 13, 2025 · 4 comments · Fixed by #3336
Assignees
Labels
Milestone

Comments

@janmasrovira
Copy link
Collaborator

janmasrovira commented Feb 13, 2025

Context

While writing apps, we've realized that the following pattern is quite common:

module ExternalIdentity;
  type ExternalIdentity :=
    mkExternalIdentity@{
      unExternalIdentity : ByteArray;
    };

  fromByteArray : ByteArray -> ExternalIdentity := mkExternalIdentity;

  toByteArray : ExternalIdentity -> ByteArray :=
    ExternalIdentity.unExternalIdentity;

  toNat : ExternalIdentity -> Nat := toByteArray >> toAnomaContents;
end;

open ExternalIdentity using {ExternalIdentity} public;

We follow this pattern because we always want to use ExternalIdentity.toNat rather than toNat directly.
Essentially, this pattern is a workaround to extend the local module SatisfiedIndent implicitly defined by the type definition of SatisfiedIntent.

Proposal

I propose that we allow users to extend the module implicitly defined by type definitions by appending with module to the type definition. Then, all definitions in that (nameless) module will be appended to the implicit module that we generate.

With the proposed syntax the example above would become:

type ExternalIdentity :=
  mkExternalIdentity@{
    unExternalIdentity : ByteArray;
  }
 with
  fromByteArray : ByteArray -> ExternalIdentity := mkExternalIdentity;

  toByteArray : ExternalIdentity -> ByteArray :=
    ExternalIdentity.unExternalIdentity;

  toNat : ExternalIdentity -> Nat := toByteArray >> toAnomaContents;
end;

example (i : ExternalIdentity) : Nat := ExternalIdentity.toNat i;
@lukaszcz
Copy link
Collaborator

lukaszcz commented Feb 13, 2025

Just a note on the syntax: these semicolons in the middle (before with and after module) seem somewhat out of place for me. I think people can keep getting tripped on that - I definitely would. My intuition is that a semicolon in Juvix ends a definition (the only exception to this seems to be module definition - but maybe we should actually rethink that?).

@janmasrovira
Copy link
Collaborator Author

janmasrovira commented Feb 13, 2025

Just a note on the syntax: these semicolons in the middle (before with and after module) seem somewhat out of place for me.

Agreed, we could remove them

the only exception to this seems to be module definition - but maybe we should actually rethink that?

I think we kept them so that if we add module arguments we don't have parsing problems. But maybe parse it correctly with some backtracking even if we have module arguments.

@lukaszcz
Copy link
Collaborator

I think we kept them so that if we add module arguments we don't have parsing problems. But maybe parse it correctly with some backtracking even if we have module arguments.

Or we could (more consistently) use, e.g.,:

module M :=
  f1 (x : Nat) : Nat := ..;
  z := 10;
end;

?

@janmasrovira
Copy link
Collaborator Author

That makes sense

@janmasrovira janmasrovira added this to the 0.6.10 milestone Feb 14, 2025
@janmasrovira janmasrovira self-assigned this Feb 14, 2025
@janmasrovira janmasrovira linked a pull request Feb 17, 2025 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants