Skip to content

Add export directive#2697

Merged
mergify[bot] merged 6 commits into
mainfrom
feature/byorgey/export
Mar 16, 2026
Merged

Add export directive#2697
mergify[bot] merged 6 commits into
mainfrom
feature/byorgey/export

Conversation

@byorgey
Copy link
Copy Markdown
Member

@byorgey byorgey commented Mar 8, 2026

Adds a new export construct for better control over module exports.

  • export "foo" in ... imports the module "foo" (just like import) and also re-exports it in its entirety. This is actually parsed as an import with a special "re-export" flag set.
  • export x in ... causes the name x to be exported (which must be in scope).

This PR also replaces the generic strict Pair with a custom data type ModuleExports.

Related features which we could either leave to a subsequent PR, or possibly address here if there is a consensus on a nice design:

  • A way to re-export tydefs in addition to defs. Currently export x only works on value-level names.
  • A way to hide things from being exported. Right now, every def in a module is exported by default.

Closes #2664.

@byorgey byorgey force-pushed the feature/byorgey/export branch from 66905ff to e8f347f Compare March 9, 2026 19:48
@byorgey byorgey marked this pull request as ready for review March 9, 2026 19:49
Co-authored-by: Restyled.io <commits@restyled.io>
Copy link
Copy Markdown
Member

@xsebek xsebek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! 👍

I don't like export in that much, it feels like forward declarations in C, but backwards. Could we have a syntax for def/tydef?

export def foo = 1 end
export tydef Bar b = (b,b) end

to desugar to:

def foo = 1 end; 
export foo;
tydef Bar b = (b,b) end;
export Bar;

EDIT: Ah, after reading the comment in go I see that is not how it works. Maybe the name should be reexport?

@byorgey
Copy link
Copy Markdown
Member Author

byorgey commented Mar 12, 2026

@xsebek Yeah, the export ... in is kind of an artifact of the way we encode it in the AST; I imagine no one will ever actually use that syntax, but will instead write export blah; foo. Maybe we should not even allow the export ... in ... syntax?

In any case, def foo = 1 end already does mean

def foo = 1 end; 
export foo;

That is, every def is already exported by default. Adding an export foo would be allowed but would be redundant.

I think export is still an accurate name: saying export foo makes foo be exported. It just so happens that every local definition is exported by default, so the only places where you would need to say export are when you are re-exporting something from an imported module.

@byorgey byorgey added the merge me Trigger the merge process of the Pull request. label Mar 16, 2026
@mergify mergify Bot added the queued label Mar 16, 2026
mergify Bot added a commit that referenced this pull request Mar 16, 2026
@mergify mergify Bot merged commit 1efd0ce into main Mar 16, 2026
14 checks passed
@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented Mar 16, 2026

Merge Queue Status

This pull request spent 11 seconds in the queue, including 1 second running CI.

Required conditions to merge

@mergify mergify Bot removed the queued label Mar 16, 2026
@mergify mergify Bot deleted the feature/byorgey/export branch March 16, 2026 00:21
@byorgey
Copy link
Copy Markdown
Member Author

byorgey commented Mar 16, 2026

I went ahead and merged this but happy to still entertain ideas for making it better!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge me Trigger the merge process of the Pull request.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

export directive for re-exporting individual names or entire modules

2 participants