kmruiz/sonata

Module System

开放

#1 创建于 2020年2月26日

 (0 条评论) (0 个反应) (0 位负责人)C++ (0 个派生)auto 404
compilerdiscoveryhelp wantedlanguage

仓库指标

星标
 (25 个星标)
PR 合并指标
 (PR 指标待抓取)

描述

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 std is parent of std.lib
    • The module std.lob is sibling of std.lib
    • The module std.lib.streams is child of std.lib
  • Any declaration in a module, is by default public and visible to all modules.
  • Declarations marked as internal can 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.

贡献者指南