kitten icon indicating copy to clipboard operation
kitten copied to clipboard

Finish module system

Open evincarofautumn opened this issue 10 years ago • 1 comments

The existing hack is a hacky hack which is actually worse than #include.

I have two possible implementations in mind. One is akin to a mix of Haskell’s and Perl’s module systems. Important examples:

import fooall default-exported things from foo
import foo (bar)only bar from foo
import qualified fooall default-exported things from foo with a foo. prefix
import qualified foo (bar)only foo.bar from foo
… as fas above but with f. instead of foo.
module bar ()export nothing
module bar (baz)export only baz
module bar (qualified baz)export baz as bar.baz
module bar (module quux)re-export everything from quux
module bar (qualified module quux)re-export everything from quux with a quux. prefix

The other option is to can the notion of modules entirely, and:

  • Export everything from a file by default
  • Allow hiding internal definitions somehow (private def?)
  • Use namespaces?

Either way, I want to discourage deep hierarchies. At worst it should go package.module.definition.

evincarofautumn avatar Jan 11 '14 07:01 evincarofautumn

Here’s my latest thinking on this.

Definitions will be private by default. In most circumstances, when we look up a name in the dictionary, we’ll give a vocabulary qualifier representing where we’re looking it up from. The metadata for a definition will contain some attribute that determines its visibility, based on the vocab hierarchy.

define foo (…) { … }

about foo:
  visibility: public

The export element will be syntactic sugar for adding this metadata.

// "export" <element>
export define foo (…) { … }
export type Bar { … }

// "export" <name>
define foo (…) { … }
type Bar { … }
export foo
export Bar

// "export" "{" <name>* "}"
define foo (…) { … }
type Bar { … }
export:
  foo
  Bar

The import statement just brings a name into scope by declaring a local synonym, which can be re-exported.

// "import" <name> 
// synonym bar (foo::bar)
import foo::bar

// "import" <name> "{" <name>* "}"
// synonym bar (foo::bar)
// synonym Baz (foo::Baz)
import foo:
  bar
  Baz

There are no wildcard imports—it should always be possible to grep the source for where an identifier came from.

The old compiler would search for files corresponding to imported modules; I’m not sure that was the right approach, so for now the compiler will only operate on a batch of sources, in dependency order. Later on, the front-end can do proper dependency calculation and loading.

evincarofautumn avatar Dec 06 '16 04:12 evincarofautumn