Repository metrics
- Stars
- (25 stars)
- PR merge metrics
- (PR metrics pending)
Description
Context
Sonata does not implement, yet, any modularization system that allows hiding internal state to a module. Right now the compiler will let you use any defined class, and this class will be stored in the top-level scope.
Sonata, however, does implement a way to import files with source code based on a include path.
Motivation
Any modern language should contain a painless module system that allows developers to reuse code enforcing their best practices:
- Importing external modules from the include path safely.
- Importing only chosen classes from a file.
Requirements
Sonata is meant to be a simple language, so the module system should be also as simple as possible and opinionated on best practices. There is a minimum set of requirements:
- The developer is responsible of hiding any declaration that is not useful outside the module.
- Importing/exporting definitions should not pollute the language, if possible.
Approach
A suggested approach would be:
- All files in Sonata pertain to a module, by default it will be related to the directory where they are. This would work similar to a Java package.
- Modules have a hierarchy: Given the module
std.lib- The module
stdis parent ofstd.lib - The module
std.lobis sibling ofstd.lib - The module
std.lib.streamsis child ofstd.lib
- The module
- Any declaration in a module, is by default public and visible to all modules.
- Declarations marked as
internalcan only be seen by the same module, siblings and children.
Examples
; src/my/module/foo.sn :: module: my.module.foo
internal let foo() = 1
; src/my/module/bar.sn :: module: my.module.bar
requires my.module.foo
let bar() = foo() + 1 ; visible because my.module.bar is sibling of my.module.foo
; src/my/module/foo/fooer.sn :: module: my.module.foo.fooer
requires my.module.foo
let fooer() = foo() ; visible because my.module.foo.fooer is child of my.module.foo
; src/main.sn :: module: main
requires my.module.foo
foo() ; does not compile, foo() is internal to module my.module.foo
Affected Modules
- The standard library needs to be changed to use the new module system.
- The compiler should enforce visibility rules.