mirror of
https://github.com/enso-org/enso.git
synced 2024-12-27 01:02:30 +03:00
Merge branch 'master' of github.com:luna/enso
This commit is contained in:
commit
6f84b8a772
53
.github/ISSUE_TEMPLATE/bug-report.md
vendored
Normal file
53
.github/ISSUE_TEMPLATE/bug-report.md
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: Report a bug in Enso.
|
||||
title: ''
|
||||
labels: 'Type: Bug'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
Please ensure that you are running the latest version of Enso before reporting
|
||||
the bug! It may have been fixed since.
|
||||
-->
|
||||
|
||||
### General Summary
|
||||
<!--
|
||||
- Please include a high-level description of your bug here.
|
||||
-->
|
||||
|
||||
### Steps to Reproduce
|
||||
<!--
|
||||
Please list the reproduction steps for your bug. For example:
|
||||
|
||||
1. Launch the enso interpreter in server mode `enso --server --socket:8080`.
|
||||
2. Send it a message as follows, where `path/to/project` doesn't exist.
|
||||
|
||||
```json
|
||||
{
|
||||
message-type: "load-project",
|
||||
load-project: {
|
||||
path: "path/to/project"
|
||||
}
|
||||
...
|
||||
}
|
||||
```
|
||||
3. Observe that the compiler crashes.
|
||||
-->
|
||||
|
||||
### Expected Result
|
||||
<!--
|
||||
- A description of the results you expected from the reproduction steps.
|
||||
-->
|
||||
|
||||
### Actual Result
|
||||
<!--
|
||||
- A description of what actually happens when you run these steps.
|
||||
- Please include any error output if relevant.
|
||||
-->
|
||||
|
||||
### Luna Version
|
||||
<!--
|
||||
- Please include the output of `enso --version`.
|
||||
-->
|
31
.github/ISSUE_TEMPLATE/epic.md
vendored
Normal file
31
.github/ISSUE_TEMPLATE/epic.md
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
---
|
||||
name: Epic
|
||||
about: Create a new epic for Enso development.
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
### Summary
|
||||
<!--
|
||||
- This section should summarise the work we want to accomplish during the epic.
|
||||
-->
|
||||
|
||||
### Value
|
||||
<!--
|
||||
- A description of the value this epic brings to users.
|
||||
- The motivation behind this epic.
|
||||
-->
|
||||
|
||||
### Specification
|
||||
<!--
|
||||
- The high-level requirements of the epic.
|
||||
- Any performance requirements for the epic.
|
||||
-->
|
||||
|
||||
### Acceptance Criteria & Test Cases
|
||||
<!--
|
||||
- The high-level acceptance criteria for the epic.
|
||||
- The test plan for the epic.
|
||||
-->
|
24
.github/ISSUE_TEMPLATE/feature-request.md
vendored
Normal file
24
.github/ISSUE_TEMPLATE/feature-request.md
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
---
|
||||
name: Feature Request
|
||||
about: Request a new feature in Enso.
|
||||
title: ''
|
||||
labels: 'Type: Enhancement'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
Please ensure that you check the latest version of Enso to see if your feature
|
||||
has been implemented.
|
||||
-->
|
||||
|
||||
### General Summary
|
||||
<!--
|
||||
- Describe the feature you are requesting.
|
||||
-->
|
||||
|
||||
### Motivation
|
||||
<!--
|
||||
- A description of the motivation for adding this feature to Enso.
|
||||
- Ideally this would include use-cases that support the feature.
|
||||
-->
|
31
.github/ISSUE_TEMPLATE/task.md
vendored
Normal file
31
.github/ISSUE_TEMPLATE/task.md
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
---
|
||||
name: Task
|
||||
about: Create a new development task for Enso.
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
### Summary
|
||||
<!--
|
||||
- A summary of the task.
|
||||
-->
|
||||
|
||||
### Value
|
||||
<!--
|
||||
- This section should describe the value of this task.
|
||||
- This value can be for users, to the team, etc.
|
||||
-->
|
||||
|
||||
### Specification
|
||||
<!--
|
||||
- Detailed requirements for the feature.
|
||||
- The performance requirements for the feature.
|
||||
-->
|
||||
|
||||
### Acceptance Criteria & Test Cases
|
||||
<!--
|
||||
- Any criteria that must be satisfied for the task to be accepted.
|
||||
- The test plan for the feature, related to the acceptance criteria.
|
||||
-->
|
19
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
19
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
### Pull Request Description
|
||||
<!--
|
||||
- Please describe the nature of your PR here, as well as the motivation for it.
|
||||
- If it fixes an open issue, please mention that issue number here.
|
||||
-->
|
||||
|
||||
### Important Notes
|
||||
<!--
|
||||
- Mention important elements of the design.
|
||||
- Mention any notable changes to APIs.
|
||||
-->
|
||||
|
||||
### Checklist
|
||||
Please include the following checklist in your PR:
|
||||
|
||||
- [ ] The documentation has been updated if necessary.
|
||||
- [ ] The code conforms to the [Scala](https://github.com/luna/enso/blob/master/doc/scala-style-guide.md) or [Haskell](https://github.com/luna/enso/blob/master/doc/haskell-style-guide.md) style guides as appropriate.
|
||||
- [ ] The code has been tested where possible.
|
||||
|
54
.gitignore
vendored
54
.gitignore
vendored
@ -1,2 +1,56 @@
|
||||
|
||||
###########
|
||||
## Scala ##
|
||||
###########
|
||||
|
||||
target/
|
||||
*.class
|
||||
*.log
|
||||
|
||||
#############
|
||||
## Haskell ##
|
||||
#############
|
||||
|
||||
dist
|
||||
cabal-dev
|
||||
*.o
|
||||
*.hi
|
||||
*.chi
|
||||
*.chs.h
|
||||
*.dyn_o
|
||||
*.dyn_hi
|
||||
.hpc
|
||||
.hsenv
|
||||
.cabal-sandbox/
|
||||
cabal.sandbox.config
|
||||
*.cabal
|
||||
*.prof
|
||||
*.aux
|
||||
*.hp
|
||||
*.DS_Store
|
||||
.stack-work/
|
||||
|
||||
############
|
||||
## System ##
|
||||
############
|
||||
|
||||
# OSX
|
||||
.DS_Store
|
||||
|
||||
############
|
||||
## Images ##
|
||||
############
|
||||
|
||||
*.jpg
|
||||
*.jpeg
|
||||
*.png
|
||||
*.bmp
|
||||
*.psd
|
||||
|
||||
######################
|
||||
## Tooling Specific ##
|
||||
######################
|
||||
|
||||
.idea/
|
||||
*.swp
|
||||
.projections.json
|
||||
|
@ -1,8 +1,14 @@
|
||||
// Scala Formatting Configuration
|
||||
|
||||
// All Scala files should be reformatted through this formatter before being
|
||||
// committed to the repositories.
|
||||
|
||||
version = "2.0.0-RC8"
|
||||
|
||||
// Wrapping and Alignment
|
||||
align = most
|
||||
maxColumn = 80
|
||||
assumeStandardLibraryStripMargin = true
|
||||
continuationIndent.defnSite = 2
|
||||
newlines.alwaysBeforeTopLevelStatements = true
|
||||
align.openParenCallSite = false
|
||||
align.openParenDefnSite = false
|
||||
align.tokens = [
|
||||
{code = "=>", owner = "Case"}
|
||||
{code = "%", owner = "Term.ApplyInfix"}
|
||||
@ -12,9 +18,36 @@ align.tokens = [
|
||||
{code = "extends"}
|
||||
{code = ":", owner = "Defn.Def"}
|
||||
]
|
||||
maxColumn = 80
|
||||
verticalAlignMultilineOperators = true
|
||||
|
||||
// Comments and Documentation
|
||||
docstrings = "scaladoc"
|
||||
|
||||
// Indentation
|
||||
assumeStandardLibraryStripMargin = true
|
||||
continuationIndent.callSite = 2
|
||||
continuationIndent.defnSite = 2
|
||||
|
||||
// Newlines
|
||||
newlines.alwaysBeforeElseAfterCurlyIf = true
|
||||
newlines.alwaysBeforeTopLevelStatements = true
|
||||
|
||||
// Rewrite Rules
|
||||
rewrite.rules = [
|
||||
ExpandImportSelectors
|
||||
RedundantParens
|
||||
SortModifiers
|
||||
PreferCurlyFors
|
||||
]
|
||||
ExpandImportSelectors,
|
||||
PreferCurlyFors,
|
||||
RedundantParens,
|
||||
SortModifiers,
|
||||
]
|
||||
rewrite.sortModifiers.order = [
|
||||
"implicit", "final", "sealed", "abstract",
|
||||
"override", "private", "protected", "lazy"
|
||||
]
|
||||
|
||||
// Multiline Configuration
|
||||
verticalMultiline.atDefnSite = true
|
||||
verticalMultiline.arityThreshold = 4
|
||||
|
||||
// Please remember that `//format: off` and `//format: on` directives should be
|
||||
// used sparingly, if at all.
|
88
CODE_OF_CONDUCT.md
Normal file
88
CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,88 @@
|
||||
# The Enso Code of Conduct
|
||||
|
||||
## Conduct
|
||||
|
||||
**Contact**: [luna-mods@luna-lang.org](mailto:luna-mods@luna-lang.org)
|
||||
|
||||
- We are committed to providing a friendly, safe and welcoming environment for
|
||||
all, regardless of level of experience, gender identity and expression, sexual
|
||||
orientation, disability, personal appearance, body size, race, ethnicity, age,
|
||||
religion, nationality, or other similar characteristic.
|
||||
- On Discord, please avoid using overtly sexual nicknames or other nicknames
|
||||
that might detract from a friendly, safe and welcoming environment for all.
|
||||
- Please be kind and courteous. There's no need to be mean or rude.
|
||||
- Respect that people have differences of opinion and that every design or
|
||||
implementation choice carries a trade-off and numerous costs. There is seldom
|
||||
a right answer.
|
||||
- Please keep unstructured critique to a minimum. If you have solid ideas you
|
||||
want to experiment with, make a fork and see how it works.
|
||||
- We will exclude you from interaction if you insult, demean or harass anyone.
|
||||
That is not welcome behaviour. We interpret the term "harassment" as including
|
||||
the definition in the
|
||||
[Citizen Code of Conduct](http://citizencodeofconduct.org/); if you have any
|
||||
lack of clarity about what might be included in that concept, please read
|
||||
their definition. In particular, we don't tolerate behaviour that excludes
|
||||
people in socially marginalized groups.
|
||||
- Private harassment is also unacceptable. No matter who you are, if you feel
|
||||
you have been or are being harassed or made uncomfortable by a community
|
||||
member, please contact one of the moderators or any of the
|
||||
[Enso moderation team][mod_team] immediately. Whether you're a regular
|
||||
contributor or a newcomer, we care about making this community a safe place
|
||||
for you and we've got your back.
|
||||
- Likewise any spamming, trolling, flaming, baiting or other attention-stealing
|
||||
behaviour is not welcome.
|
||||
|
||||
## Moderation
|
||||
These are the policies for upholding our community's standards of conduct. If
|
||||
you feel that a thread needs moderation, please contact the
|
||||
[Enso moderation team][mod_team].
|
||||
|
||||
1. Remarks that violate the Enso standards of conduct, including hateful,
|
||||
hurtful, oppressive, or exclusionary remarks, are not allowed. Cursing is
|
||||
allowed, but never targeting another user, and never in a hateful manner.
|
||||
2. Remarks that moderators find inappropriate, whether listed in the code of
|
||||
conduct or not, are also not allowed.
|
||||
3. Moderators will first respond to such remarks with a warning.
|
||||
4. If the warning is unheeded, the user will be "kicked," i.e., kicked out of
|
||||
the communication channel to cool off.
|
||||
5. If the user comes back and continues to make trouble, they will be banned,
|
||||
i.e., indefinitely excluded.
|
||||
6. Moderators may choose at their discretion to un-ban the user if it was a
|
||||
first offense and they offer the offended party a genuine apology.
|
||||
7. If a moderator bans someone and you think it was unjustified, please take it
|
||||
up with that moderator, or with a different moderator, **in private**.
|
||||
Complaints about bans in-server are not allowed.
|
||||
8. Moderators are held to a higher standard than other community members. If a
|
||||
moderator creates an inappropriate situation, they should expect less leeway
|
||||
than others.
|
||||
|
||||
In the Enso community we all aim to go the extra mile and look out for each
|
||||
other. We don't just aim to be technically unimpeachable, but we try to be our
|
||||
very best selves. In particular, avoid flirting with offensive or sensitive
|
||||
topics, particularly if they're off-topic. Doing so all too often leads to
|
||||
unnecessary fights, hurt feelings and damaged trust; worse, it can drive people
|
||||
away from the community entirely.
|
||||
|
||||
If someone takes issue with something you said or did, resist the urge to be
|
||||
defensive. Just stop what it was they complained about and apologise. Even if
|
||||
you feel that you were misinterpreted or unfairly accused, it is likely that
|
||||
there was something you could've communicated better — remember it is _your_
|
||||
responsibility to make your fellow Enso contributors comfortable. Everyone wants
|
||||
to get along, and everyone in this community is here first and foremost to talk
|
||||
about cool technology! You will find that people will be eager to assume good
|
||||
intent and forgive as long as there is an atmosphere of trust.
|
||||
|
||||
The enforcement policies listed above apply to all official Enso venues. This
|
||||
includes the official discord and GitHub repositories under `luna`.
|
||||
|
||||
_Adapted from the_
|
||||
_[Node.js Policy on Trolling](http://blog.izs.me/post/30036893703/policy-on-trolling)_
|
||||
_as well as the_
|
||||
_[Contributor Covenant v1.3.0](https://www.contributor-covenant.org/version/1/3/0/)._
|
||||
|
||||
[mod_team]: [luna-mods@luna-lang.org](mailto:luna-mods@luna-lang.org)
|
||||
|
||||
## Credits
|
||||
This code of conduct is adapted from the [Rust](https://rust-lang.org) code of
|
||||
conduct. Many thanks to the Rust community for being such an exemplar of the
|
||||
open-source spirit!
|
197
CONTRIBUTING.md
Normal file
197
CONTRIBUTING.md
Normal file
@ -0,0 +1,197 @@
|
||||
# Contributing to Enso
|
||||
Thank you for your interest in contributing to Enso! We believe that only
|
||||
through community involvement can Enso be the best it can be! There are a whole
|
||||
host of ways to contribute, and every single one is appreciated. The major
|
||||
sections of this document are linked below:
|
||||
|
||||
<!-- MarkdownTOC levels="2" autolink="true" -->
|
||||
|
||||
- [Issues](#issues)
|
||||
- [Feature Enhancements](#feature-enhancements)
|
||||
- [Bug Reports](#bug-reports)
|
||||
- [Hacking on Enso](#hacking-on-enso)
|
||||
- [Pull Requests](#pull-requests)
|
||||
- [Documentation](#documentation)
|
||||
- [Issue Triage](#issue-triage)
|
||||
- [Out-of-Tree Contributions](#out-of-tree-contributions)
|
||||
- [Helpful Documentation and Links](#helpful-documentation-and-links)
|
||||
|
||||
<!-- /MarkdownTOC -->
|
||||
|
||||
All contributions to Luna should be in keeping with our
|
||||
[Code of Conduct](https://github.com/luna/luna/blob/CODE_OF_CONDUCT.md).
|
||||
|
||||
## Issues
|
||||
If you are looking for somewhere to start, check out the `Help Wanted` tag in
|
||||
the following repositories:
|
||||
- [Enso](https://github.com/luna/luna/labels/Status%3A%20Help%20Wanted)
|
||||
- [Luna Studio](https://github.com/luna/luna-studio/labels/Status%3A%20Help%20Wanted)
|
||||
- [Luna Manager](https://github.com/luna/luna-manager/labels/Status%3A%20Help%20Wanted)
|
||||
- [Luna Dataframes](https://github.com/luna/dataframes/labels/Status%3A%20Help%20Wanted)
|
||||
|
||||
## Feature Enhancements
|
||||
If you feel like you have a suggestion for a change to the way that Enso works
|
||||
as a language, please open an issue in our
|
||||
[RFCs Repository](https://github.com/luna/luna-rfcs), rather than in this one!
|
||||
New features and other significant language changes must go through the RFC
|
||||
process so they can be properly discussed.
|
||||
|
||||
## Bug Reports
|
||||
While it's never great to find a bug, they are a reality of software and
|
||||
software development! We can't fix or improve on the things that we don't know
|
||||
about, so report as many bugs as you can! If you're not sure whether something
|
||||
is a bug, file it anyway!
|
||||
|
||||
**If you are concerned that your bug publicly presents a security risk to the
|
||||
users of Enso, please contact
|
||||
[security@luna-lang.org](mailto:security@luna-lang.org).**
|
||||
|
||||
Even though GitHub search can be a bit hard to use sometimes, we'd appreciate if
|
||||
you could
|
||||
[search](https://github.com/luna/enso/search?q=&type=Issues&utf8=%E2%9C%93) for
|
||||
your issue before filing a bug as it's possible that someone else has already
|
||||
reported the issue. We know the search isn't the best, and it can be hard to
|
||||
know what to search for, so we really don't mind if you do submit a duplicate!
|
||||
|
||||
Opening an issue is as easy as following [this link](https://github.com/luna/enso/issues/new?template=bug-report.md)
|
||||
and filling out the fields. The template is intended to collect all the
|
||||
information we need to best diagnose the issue, so please take the time to fill
|
||||
it out accurately.
|
||||
|
||||
The reproduction steps are particularly important, as the more easily we can
|
||||
reproduce it, the faster we can fix the bug! It's also helpful to have the
|
||||
output of `enso --version`, as that will let us know if the bug is Operating
|
||||
System or Architecture specific.
|
||||
|
||||
## Hacking on Enso
|
||||
This will get you up and running for Enso development, with only a minimal
|
||||
amount of setup required. Enso's build system is fairly simple, allowing you to
|
||||
bootstrap the compiler as long as you have...
|
||||
|
||||
### Design Documentation
|
||||
If you're going to start contributing to Enso, it is often a good idea to take a
|
||||
look at the design documentation for the language. These files explain provide
|
||||
both a rigorous specification of Enso's design, but also insight into the _why_
|
||||
behind the decisions that have been made.
|
||||
|
||||
These can be found in [`doc/design/`](doc/design/), and are organised by the
|
||||
part of the compiler that they relate to.
|
||||
|
||||
### System Requirements
|
||||
TBC
|
||||
|
||||
### Getting the Sources
|
||||
Given you've probably been reading this document on GitHub, you might have an
|
||||
inkling where to look!. You can clone Luna using two methods:
|
||||
|
||||
- **Via HTTPS:** We recommend you only use HTTPS if checking out the sources as
|
||||
read-only.
|
||||
|
||||
```
|
||||
git clone https://github.com/luna/enso.git
|
||||
```
|
||||
|
||||
- **Via SSH:** For those who plan on regularly making direct commits, cloning
|
||||
over SSH may provide a better user experience (but requires setting up your
|
||||
SSH Keys with GitHub).
|
||||
|
||||
```
|
||||
git clone git@github.com:luna/enso.git
|
||||
```
|
||||
|
||||
### Building Enso
|
||||
TBC
|
||||
|
||||
#### Building Enso Components
|
||||
TBC
|
||||
|
||||
#### Developing Enso's Libraries
|
||||
TBC
|
||||
|
||||
#### Building Enso for Release
|
||||
TBC
|
||||
|
||||
#### Packaging Enso
|
||||
TBC
|
||||
|
||||
### Running Luna
|
||||
TBC
|
||||
|
||||
#### Projects
|
||||
|
||||
#### Standalone Files
|
||||
|
||||
#### Language Server Mode
|
||||
|
||||
## Pull Requests
|
||||
Pull Requests are the primary method for making changes to Enso. GitHub has
|
||||
[fantastic documentation](https://help.github.com/articles/about-pull-requests/)
|
||||
on using the pull request feature. Luna uses the 'fork-and-pull' model of
|
||||
development. It is as described
|
||||
[here](https://help.github.com/articles/about-collaborative-development-models/)
|
||||
and involves people pushing changes to their own fork and creating pull requests
|
||||
to bring those changes into the main Luna repository.
|
||||
|
||||
Please make all pull requests against the `master` branch.
|
||||
|
||||
Before making your PR, please make sure that the commit passes the Enso test
|
||||
suite. You can run all the tests by ... TBC. In addition, please ensure that
|
||||
your code conforms to the Enso [Scala Style Guide](./doc/scala-style-guide.md)
|
||||
and [Haskell Style Guide](./doc/haskell-style-guide.md) as relevant.
|
||||
|
||||
Make sure you perform these checks before _every_ pull request. You can even add
|
||||
[git hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) before
|
||||
every push to make sure that you can't forget.
|
||||
|
||||
Every pull request for Enso is reviewed by another person! You'll get a
|
||||
reviewer from the core team assigned at random, but feel free to ask for a
|
||||
specific person if you've dealt with them in a certain area before!
|
||||
|
||||
Once the reviewer approves your pull request it will be tested by our continuous
|
||||
integration provider before being merged!
|
||||
|
||||
## Documentation
|
||||
Documentation improvements are very welcome! The source for the Enso, Book can be
|
||||
found in [`luna/luna-book`](https://github.com/luna/luna-book), but most of the
|
||||
API documentation is generated directly from the code!
|
||||
|
||||
Documentation pull requests are reviewed in exactly the same way as normal pull
|
||||
requests.
|
||||
|
||||
To find documentation-related issues, sort by the
|
||||
[Category: Documentation](hhttps://github.com/luna/enso/labels/Category%3A%20Documentation)
|
||||
label.
|
||||
|
||||
## Issue Triage
|
||||
Sometimes issues can be left open long after the bug has been fixed. Other
|
||||
times, a bug might go stale because something has changed in the meantime.
|
||||
|
||||
It can be helpful to go through older bug reports and make sure that they are
|
||||
still valid. Load up an older issue, double check that it's still true, and
|
||||
leave a comment letting us know if it is or is not. The
|
||||
[least recently updated](https://github.com/luna/enso/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-asc)
|
||||
sort is good for finding issues like this.
|
||||
|
||||
Contributors with sufficient permissions can help by adding labels to help with
|
||||
issue triage.
|
||||
|
||||
If you're looking for somewhere to start, take a look at the
|
||||
[Difficulty: Beginner](https://github.com/luna/enso/labels/Difficulty%3A%20Beginner)
|
||||
issue label, as well as the
|
||||
[Status: Help Wanted](https://github.com/luna/enso/labels/Status%3A%20Help%20Wanted)
|
||||
label.
|
||||
|
||||
## Out-of-Tree Contributions
|
||||
As helpful as contributing to Enso directly is, it can also be just as helpful
|
||||
to contribute in other ways outside this repository:
|
||||
|
||||
- Answer questions in the [Discord](https://discordapp.com/invite/YFEZz3y) or
|
||||
on [StackOverflow](https://stackoverflow.com/questions/tagged/luna).
|
||||
- Participate in the [RFC Process](https://github.com/luna/luna-rfcs).
|
||||
|
||||
## Helpful Documentation and Links
|
||||
For people new to Luna, and just starting to contribute, or even for more
|
||||
seasoned developers, some useful places to look for information are:
|
||||
|
||||
- [The Enso Book](https://luna-lang.gitbooks.io/docs/)
|
||||
- The community! Don't be afraid to ask questions.
|
201
LICENSE
Normal file
201
LICENSE
Normal file
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
59
README.md
Normal file
59
README.md
Normal file
@ -0,0 +1,59 @@
|
||||
<!-- [![Build Status](https://dev.azure.com/luna-lang/luna/_apis/build/status/luna.luna?branchName=master)](https://dev.azure.com/luna-lang/luna/_build/latest?definitionId=1&branchName=master) -->
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/luna/luna-studio/raw/master/resources/logo.ico" style="margin: 0 auto;">
|
||||
</p>
|
||||
<h1 align="center">Enso Programming Language</h1>
|
||||
<h3 align="center">
|
||||
Visual and textual functional programming language with a focus on productivity, collaboration and development ergonomics.
|
||||
</h3>
|
||||
|
||||
Enso is a developer’s whiteboard on steroids. Design, prototype, develop and
|
||||
refactor any application simply by connecting visual elements together.
|
||||
Collaborate with co-workers, interactively fine tune parameters, inspect the
|
||||
results and visually profile the performance in real-time.
|
||||
|
||||
Visit [The Enso Website](http://www.luna-lang.org) to learn more!
|
||||
|
||||
This repository contains the Enso interpreter and runtime, as well as its
|
||||
command-line interface. For the full (visual) Enso Studio, please take a look at
|
||||
[Enso Studio](https://github.com/luna/luna-studio).
|
||||
|
||||
## Contributing to Enso
|
||||
If you are interested in contributing to the development of Enso, please read
|
||||
the [`CONTRIBUTING.md`](./CONTRIBUTING.md) file. It describes all the ways in
|
||||
which you can help the project, as well as provides instructions for how to
|
||||
build Enso.
|
||||
|
||||
## Enso's Design
|
||||
If you would like to gain a better understanding of the principles on which Enso
|
||||
is based, or just delve into the why's and what's of Luna's design, please take
|
||||
a look in the [`doc/design/` folder](./doc/design).
|
||||
|
||||
This documentation will evolve as Enso does, both to help newcomers to the
|
||||
project understand the reasoning behind the code, but also to act as a record of
|
||||
the decisions that have been made through Enso's evolution.
|
||||
|
||||
## License
|
||||
This repository is licensed under the
|
||||
[Apache 2.0](https://opensource.org/licenses/apache-2.0), as specified in the
|
||||
[LICENSE](https://github.com/luna/luna/blob/master/LICENSE) file.
|
||||
|
||||
Please be aware that, as the commercial backing for Enso,
|
||||
**New Byte Order Sp. z o. o.** reserves the right under the CLA to use
|
||||
contributions made to this repository as part of commercially available Enso
|
||||
products.
|
||||
|
||||
If these terms are unacceptable to you, please do not contribute to the
|
||||
repository.
|
||||
|
||||
### The Contributor License Agreement
|
||||
As part of your first contribution to this repository, you need to accept the
|
||||
Contributor License Agreement. You will automatically be asked to sign the CLA
|
||||
when you make your first pull request.
|
||||
|
||||
Any work intentionally submitted for inclusion in Luna shall be licensed under
|
||||
this CLA.
|
||||
|
||||
The CLA you sign applies to all repositories associated with the Enso project,
|
||||
so you will only have to sign it once at the start of your contributions.
|
@ -34,4 +34,4 @@ lazy val syntax = (project in file("syntax"))
|
||||
.settings(mainClass in (Compile,run) := Some("org.enso.syntax.Main"))
|
||||
.settings(bench := {
|
||||
(test in Benchmark).value
|
||||
})
|
||||
})
|
||||
|
BIN
doc/.DS_Store
vendored
Normal file
BIN
doc/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
doc/design/.DS_Store
vendored
Normal file
BIN
doc/design/.DS_Store
vendored
Normal file
Binary file not shown.
100
doc/design/enso-philosophy.md
Normal file
100
doc/design/enso-philosophy.md
Normal file
@ -0,0 +1,100 @@
|
||||
# Enso's Philosophy
|
||||
Enso is a programming language unlike any that have come before it, a seamless
|
||||
blend of code and visual communication that can span organisations.
|
||||
|
||||
> "The compiler is your assistant, and you interact with it to arrive at a
|
||||
> working program via a conversation, with information going both ways."
|
||||
>
|
||||
> – [Edwin Brady](https://twitter.com/edwinbrady/status/1115361451005423617)
|
||||
|
||||
<!-- MarkdownTOC levels="2,3" autolink="true" -->
|
||||
|
||||
- [Tenets of Enso](#tenets-of-enso)
|
||||
- [Explicit Overrides Implicit](#explicit-overrides-implicit)
|
||||
- [Designing Enso](#designing-enso)
|
||||
|
||||
<!-- /MarkdownTOC -->
|
||||
|
||||
## Tenets of Enso
|
||||
As we design Enso, we rely on a small set of principles to guide the design and
|
||||
evolution of the language. They are elucidated below.
|
||||
|
||||
- **Visual and Textual:** The visual and textual syntaxes are both first-class.
|
||||
One is not translated to the other, but they are instead equivalent. New
|
||||
features must work across both.
|
||||
- **Unified Syntax:** The language syntax should be simple, concise, and be
|
||||
usable at both the type and term levels.
|
||||
- **Visual Communication:** A pure and functional language that lends itself
|
||||
easily to visualisation of data-flows.
|
||||
- **One Right Way:** There should, overwhelmingly, be only one way to perform a
|
||||
given task. Limited choice breeds simplicity.
|
||||
- **Help the User:** Enso should do its utmost to make things easier for the
|
||||
user, even if that involves accepting additional tooling complexity. This does
|
||||
not come at the exclusion of letting users access that power.
|
||||
- **Simple Complexity:** Though the language is backed by powerful functionality
|
||||
and compiler smarts, this should be invisible to the users until they care to
|
||||
engage with it.
|
||||
- **Powerful When Necessary:** Designed to employ powerful techniques that
|
||||
confer safety and speed, allowing the users to write correct programs.
|
||||
- **Performance and Predictability:** Predictable performance, with integrated
|
||||
debugging and profiling features to help users diagnose their problems.
|
||||
- **Explicit Overrides Implicit:** The design of Enso and its libraries should
|
||||
_always_ account for making all behaviour implicit.
|
||||
|
||||
### Explicit Overrides Implicit
|
||||
When designing Enso and its libraries, we don't want to have any behaviour of a
|
||||
function that is not recorded in its type, or its defaults. This gives rise to
|
||||
two main principles for designing Enso's APIs:
|
||||
|
||||
1. Use the correct types to inform both users and the tools about the behaviour
|
||||
of the function.
|
||||
2. Use the inbuilt capabilities for named and default arguments to provide
|
||||
_sensible defaults_, for an API, without hiding behaviour.
|
||||
|
||||
An example of this trade-off is reading a opening a file handle with
|
||||
`openHandle`.
|
||||
|
||||
Unlike more specialised functions such as `readFile` and `writeFile`,
|
||||
`openHandle` is much more flexible about how it opens the file. In such cases,
|
||||
users making use of this file function can generally be assumed to want to open
|
||||
the file for both reading _and_ writing.
|
||||
|
||||
This is the sensible, default, but it is made properly explicit by inclusion as
|
||||
a defaulted keyword argument to the function:
|
||||
|
||||
```
|
||||
type File.Mode :
|
||||
Read
|
||||
Write
|
||||
RW
|
||||
Append
|
||||
RWA
|
||||
|
||||
openHandle : File.Path -> File.Mode -> File.Handle
|
||||
openHandle path -> fileMode = RW -> ...
|
||||
```
|
||||
|
||||
In doing so, the design of the function tells the user the following things:
|
||||
|
||||
- It takes a file path, which represents the location of a file on the user's
|
||||
local system (as opposed to a `Resource.Path`, which is a location for a
|
||||
generic resource).
|
||||
- It has an _explicit_ default behaviour that it opens the file for both reading
|
||||
and writing, that is defaulted as part of the definition, but can be
|
||||
overridden if necessary.
|
||||
|
||||
As a result, this design allows for _explicit_ communication of the behaviour of
|
||||
the function, both under default, and non-default circumstances. Hence, the user
|
||||
who would like to open a file for appending (via `appendHandle`), as well as
|
||||
reading and writing, can call it as follows: `openHandle path (fileMode = RWA)`,
|
||||
or just `openHandle path RWA`.
|
||||
|
||||
## Designing Enso
|
||||
As Enso's design and functionality evolves, we have to take the utmost care to
|
||||
ensure that it doesn't balloon beyond control. As a result, every new feature
|
||||
that we contemplate adding to the language should advance these core tenets, and
|
||||
thereby ensure that it matches with the overall vision for Enso.
|
||||
|
||||
We stick to the above principles when we're _building_ the compiler as well,
|
||||
with code being liberally commented with need-to-know information, as well as
|
||||
for clean and clear design documents to accompany it.
|
76
doc/design/runtime/graalvm.md
Normal file
76
doc/design/runtime/graalvm.md
Normal file
@ -0,0 +1,76 @@
|
||||
# GraalVM
|
||||
The following are notes based on questions that we have about using GraalVM to
|
||||
provide a backend for Enso.
|
||||
|
||||
- C-API is a potentially useful tool for combining the Java/Truffle side and the
|
||||
Haskell side.
|
||||
- The polyglot API is the bindings to Graal itself, with access from both C and
|
||||
Java. This is _not_ the same thing as the truffle framework for building new
|
||||
programming languages.
|
||||
- You can define your own C-API (as C-entry points) for your hosted language,
|
||||
which then allows for you to call into the hosted language.
|
||||
- There are no current plans to allow for compilation of the hosted language to
|
||||
native code via SubstrateVM. You can store part of the JVM heap in the native
|
||||
image, allowing for standalone executables. Serialisation of heap into the
|
||||
image.
|
||||
- JavaScript and LLVM are possible backends for SubstrateVM, so we can compile
|
||||
Enso code indirectly to JS. The LLVM backend is on the roadmap, while the
|
||||
former is possible.
|
||||
- No explicit control of memory layout for the hosted language, instead with a
|
||||
high level (JS-style) API for working with objects. There is no
|
||||
non-encapsulated mechanism for accessing objects due to optimisation reasons.
|
||||
If we wanted explicit memory layout control. Hybrid systems are supported.
|
||||
- GraalPython is at an early stage of development, with a critical focus on the
|
||||
scientific libraries. It is very much a first-class language on the Graal
|
||||
platform.
|
||||
- The Graal garbage collector is evolving to be a Java port of G1. Fairly high
|
||||
priority to improve the GC, and its support for immutability.
|
||||
- Graal doesn't currently have support for saving the heap except via something
|
||||
like SubstrateVM.
|
||||
- Caching: Truffle is designed for live specialisation, and has support for
|
||||
inline caching. No support for retention or eviction at this stage.
|
||||
- Truffle provides some support for reusable front-end optimisations in the form
|
||||
of AST specialisation. Strong support for AST re-writing as an optimisation
|
||||
technique. You can walk the tree at creation time, or at execution time, in
|
||||
order to implement more global optimisations. Separation between allocation
|
||||
and re-writing.
|
||||
- Commercial support for bugfixes, but not necessarily for feature requests yet.
|
||||
- Introspection/Debugging framework lets you introspect all portions of the code
|
||||
during execution. We can dynamically add those introspection hooks in order to
|
||||
do this optimally.
|
||||
- There is no way to force compilation, but could modify truffle to add some
|
||||
support for an API that allows this control. There is currently only one tier
|
||||
of compilation, but it is _possible_ to write additional JIT phases.
|
||||
- There is the polyglot REPL, but it is definitely possible to build a proper
|
||||
polyglot repl based around Enso. Take a look at `polyglot - shell`.
|
||||
|
||||
Sit down with Chris in London with some concrete code and examples.
|
||||
|
||||
## A Design Based on GraalVM
|
||||
|
||||
- The parser remains in Haskell.
|
||||
- The backend works on AST changesets instead.
|
||||
- The compiler is written in Scala using Truffle, implementing the following set
|
||||
of processes:
|
||||
+ Ingestion: Transformation of AST to Graal internal AST.
|
||||
+ Desugaring: Removal of all syntax sugar from the expressions to create a
|
||||
core language.
|
||||
+ Typechecking: Typechecking of the core language.
|
||||
+ Optimisation: Optimisation of the core language.
|
||||
+ Interpretation: Using GraalVM.
|
||||
|
||||
Roadmap:
|
||||
|
||||
1. Write up a specification of the runtime, type system, and syntax.
|
||||
2. WD fixes the parser for the new syntax including markers, double rep, and AST
|
||||
printing.
|
||||
3. Build the first version of the GraalVM backend to operate in a standalone
|
||||
fashion, with no interactivity. This will have no standard library support.
|
||||
4. Build the standard library, initially focusing on the basics, HTTP, and the
|
||||
primary interchange formats (JSON and YAML).
|
||||
5. Design the IDE protocol and implement the necessary introspection
|
||||
functionality. The messages should only be implemented enough to support the
|
||||
Enso Studio use-cases.
|
||||
6. Implement the caching in earnest.
|
||||
7. Implement the typechecker and rework caching as needed.
|
||||
8. Implement the necessary sets of optimisation passes in GraalVM.
|
394
doc/design/runtime/runtime.md
Normal file
394
doc/design/runtime/runtime.md
Normal file
@ -0,0 +1,394 @@
|
||||
# Enso Runtime
|
||||
This document contains a detailed specification of Enso's runtime. It includes
|
||||
a description of the technologies on which it is built, as well as the features
|
||||
and functionality that it is required to support. In addition, the document aims
|
||||
to explain why _this_ design, rather than one of the many alternatives available
|
||||
to the team.
|
||||
|
||||
When we refer to the Enso 'runtime' in this document, we are referring to the
|
||||
combination of the language communication protocol, typechecker, optimiser, and
|
||||
interpreter. Though the interpreter itself has its own runtime, it is these
|
||||
components that make up _Enso's_ runtime.
|
||||
|
||||
The runtime is built on top of [GraalVM](https://www.graalvm.org/), a universal
|
||||
virtual machine on which you can run any language with an appropriate
|
||||
interpreter. In basing Enso's runtime on GraalVM, we not only have access to a
|
||||
comprehensive toolkit for building high-performance language interpreters, but
|
||||
also to the ecosystems of all the other languages (e.g. C++, Python, R) that can
|
||||
run on top of it. GraalVM also brings some additional important tooling, such as
|
||||
the JVM ecosystem's performance monitoring, analysis, and debugging toolsets.
|
||||
|
||||
The runtime described below is a complex beast, so this document is broken up
|
||||
into a number of sections. These aim to provide an architectural overview, and
|
||||
then describe the design of each component in detail.
|
||||
|
||||
<!-- MarkdownTOC levels="1,2" autolink="true" -->
|
||||
|
||||
- [Architectural Overview](#architectural-overview)
|
||||
- [The Broader Enso Ecosystem](#the-broader-enso-ecosystem)
|
||||
- [The Runtime's Architecture](#the-runtimes-architecture)
|
||||
- [Choosing GraalVM](#choosing-graalvm)
|
||||
- [The Runtime Components](#the-runtime-components)
|
||||
- [Language Server](#language-server)
|
||||
- [Filesystem Driver](#filesystem-driver)
|
||||
- [Typechecker](#typechecker)
|
||||
- [Optimiser](#optimiser)
|
||||
- [Interpreter and JIT](#interpreter-and-jit)
|
||||
- [Cross-Cutting Concerns](#cross-cutting-concerns)
|
||||
- [Caching](#caching)
|
||||
- [Profiling and Debugging](#profiling-and-debugging)
|
||||
- [Foreign Language Interoperability](#foreign-language-interoperability)
|
||||
- [Lightweight Concurrency](#lightweight-concurrency)
|
||||
- [The Initial Version of the Runtime](#the-initial-version-of-the-runtime)
|
||||
- [Development Considerations](#development-considerations)
|
||||
|
||||
<!-- /MarkdownTOC -->
|
||||
|
||||
# Architectural Overview
|
||||
The Enso runtime is just one of the many components of the Enso ecosystem. This
|
||||
section provides an overview of how it fits into the broader ecosystem, with a
|
||||
particular focus on how it enables workflows for Enso Studio, the Enso CLI, and
|
||||
Language Server integration. In addition, this section also explores the
|
||||
architecture of the runtime itself, breaking down the opaque 'runtime' label
|
||||
into the
|
||||
|
||||
## The Broader Enso Ecosystem
|
||||
While the runtime is arguably the core part of Enso, for the language would not
|
||||
be able to exist without it, the language's success is just as dependent on the
|
||||
surrounding ecosystem.
|
||||
|
||||
TBC...
|
||||
|
||||
It is worth providing a brief explanation of each of the components to aid in
|
||||
understanding how the runtime fits into the ecosystem.
|
||||
|
||||
- **Enso Studio GUI:** This is the interface with which most of Enso's users
|
||||
will interact. It handles the drawing of and interaction with the Enso graph
|
||||
for users, as well as the searcher and other user-facing functionality. It
|
||||
also provides a text editor.
|
||||
- **Project Manager:** This allows for management of one or more Enso projects,
|
||||
and is primarily responsible for file-system-agnostic interaction with the
|
||||
project structure, and spawning of the Enso runtime.
|
||||
- **GUI Backend:** The GUI backend is instantiated for each project, and is
|
||||
responsible for all of the user-facing logic that goes into interaction with
|
||||
the Enso runtime.
|
||||
+ **Graph State Manager:** This component handles management of the state
|
||||
required to draw the graph in the GUI.
|
||||
+ **Double Representation Manager:** This component handles the encoding and
|
||||
decoding of the Enso program to and from the intermediate representation.
|
||||
+ **Undo/Redo Manager:** This component handles undo and redo for the graph, a
|
||||
somewhat novel operation as it does not not always have a 1:1 correspondence
|
||||
with textual editing.
|
||||
- **CLI:** This provides a command-line (specifically a terminal) interface to
|
||||
the Enso runtime. This allows both for the CLI invocation of Enso, as well as
|
||||
an interactive REPL. This communicates with the runtime itself via the
|
||||
language server protocol.
|
||||
- **Enso Runtime:** This is what is described in this document, and is
|
||||
responsible for the execution of Enso programs. It handles the typechecking,
|
||||
optimisation, and interpretation of Enso code, as well as the provision of
|
||||
interfaces to foreign languages.
|
||||
|
||||
## The Runtime's Architecture
|
||||
In order to better appreciate how the components specified below interact, it is
|
||||
important to have an understanding of the high-level architecture of the runtime
|
||||
itself. The design in this document pertains _only_ to the 'Enso Runtime'
|
||||
component of the diagram above, and hence makes no mention of the others.
|
||||
|
||||
In the diagram below, the direction of arrows is used to represent the 'flow' of
|
||||
information between the various components.
|
||||
|
||||
TBC...
|
||||
|
||||
# Choosing GraalVM
|
||||
Building the runtime on top of GraalVM was of course not the only choice that
|
||||
could've been made, but it was overwhelmingly the most sensible option out of
|
||||
those considered.
|
||||
|
||||
At the time the runtime was designed, there were three main options that were
|
||||
being considered.
|
||||
|
||||
- **LLVM:** A battle-tested and comprehensive toolchain for the creation of
|
||||
language compilers, [LLVM](https://llvm.org/) includes facilities for
|
||||
compilation, optimisation, JIT, and linking.
|
||||
- **GHC:** The [Glasgow Haskell Compiler](https://gitlab.haskell.org/ghc/) is
|
||||
a sophisticated compiler and runtime for Haskell that provides a
|
||||
language-agnostic set of internal representations that could be leveraged to
|
||||
compile and/or interpret other functional languages.
|
||||
- **JVM:** The [JVM](https://openjdk.java.net/) is a high-performance virtual
|
||||
machine that includes sophisticated garbage collection, profiling tools, and
|
||||
a JIT compiler.
|
||||
- **GraalVM:** A universal virtual machine and language development toolkit,
|
||||
[GraalVM](https://www.graalvm.org/) provides a framework for building language
|
||||
interpreters, as well as a JIT compiler. Most importantly, it provides tools
|
||||
for seamless interoperability between languages that can run on Graal, which
|
||||
include Python and R.
|
||||
|
||||
The decision to build Enso's runtime using GraalVM was primarily motivated by
|
||||
business concerns, but these concerns did not override the technical as well.
|
||||
Addressing them one by one provides a comprehensive picture of why the decision
|
||||
was made.
|
||||
|
||||
Overall, it is clear that GraalVM is an optimal choice for Enso at this stage of
|
||||
the language's development. While the other potential targets do have their
|
||||
upsides (e.g. the JVM's sophisticated garbage collection machinery), they all
|
||||
had at least one 'fatal flaw' for Enso's use case.
|
||||
|
||||
### Speed of Development
|
||||
A language runtime is a complex beast, so any solution that could remove some of
|
||||
the implementation burden would be beneficial to Enso as a product.
|
||||
|
||||
Where LLVM provides comprehensive tools for compiling languages, it provides no
|
||||
actual runtime. This would require significant implementation effort, requiring
|
||||
the implementation of facilities for concurrency, as well as garbage collection,
|
||||
neither of which are simple tasks.
|
||||
|
||||
GHC, on the other hand, provides a comprehensive runtime system that includes
|
||||
both a garbage collector and sophisticated concurrency system. However, while it
|
||||
does provide language-agnostic intermediate representations, these are tied to
|
||||
Haskell from a development perspective. Unlike LLVM, GraalVM, or even the JVM,
|
||||
if GHC Haskell requires a change to these representations, that change will be
|
||||
made.
|
||||
|
||||
With many languages already targeting the JVM it also seemed like an attractive
|
||||
option. The stable bytecode target would be useful, but other languages have
|
||||
proven the challenges of generating sensible bytecode to provide good language
|
||||
performance.
|
||||
|
||||
GraalVM manages to provide excellent performance with a sensible, high-level
|
||||
interface, thereby enabling rapid development of a performant runtime without
|
||||
the need to implement complex components such as a GC and concurrency.
|
||||
|
||||
### Language Interoperability Support
|
||||
With Enso aiming to be the be-all and end-all for the data-science world, the
|
||||
ability to seamlessly interoperate with other programming languages is key. This
|
||||
means that a user should be able to paste in some Python or R code and have it
|
||||
work properly.
|
||||
|
||||
From a simple perspective, there were no other options in this category. While
|
||||
the JVM would allow for interoperability with other JVM languages such as Scala,
|
||||
Kotlin, and Java itself, the two 'most important' languages for interoperation
|
||||
had no support. LLVM's story is similar, allowing users to use LLVM IR as a
|
||||
common interoperation format, but this is far less practical than the JVM. With
|
||||
GHC, any interoperation would have to be developed from-scratch and by hand,
|
||||
essentially ruling it out in this category.
|
||||
|
||||
With GraalVM supporting not only our primary interoperability targets, but also
|
||||
the whole JVM ecosystem and any language that targets LLVM, it is an absolute
|
||||
dream for ensuring that Luna can seamlessly communicate with a whole host of
|
||||
other programming languages.
|
||||
|
||||
### Implementation Performance
|
||||
Data science often involves the manipulation of very large amounts of data, and
|
||||
ensuring that an interactive environment like Enso doesn't slow down as it does
|
||||
so requires a high level of performance.
|
||||
|
||||
GraalVM's partially-evaluated-interpreter based approach allows the developers
|
||||
to write a 'naive interpreter' and automatically have the platform provide
|
||||
better performance. This is a stark contrast to all of the other listed options,
|
||||
each of which would require significant complexity around generating the right
|
||||
intermediate representation structures, as well as significant work on front-end
|
||||
language optimisations.
|
||||
|
||||
In essence, GraalVM provides for the best performance with the smallest amount
|
||||
of effort, while still providing comprehensive facilities to improve performance
|
||||
further in the future.
|
||||
|
||||
### Maintenance Burden
|
||||
Just as important as getting a working runtime is the ability for the developers
|
||||
to improve and evolve it. This encompasses many factors, but Enso is primarily
|
||||
concerned with being able to evolve without having to account for undue changes
|
||||
to the runtime.
|
||||
|
||||
LLVM provides a relatively stable IR target, so the maintenance burden wouldn't
|
||||
have been too onerous. Similarly for the JVM, where the bytecode format has been
|
||||
stable for many years. Though both projects add new instructions, they very
|
||||
rarely remove them, meaning that Enso's potential code generator would be able
|
||||
to work as the underlying platform evolves.
|
||||
|
||||
As mentioned before, however, the intermediate representations in GHC that Enso
|
||||
would have used as a target are very much changeable. This is due to their
|
||||
primary existence being to support GHC's version of Haskell, which means that
|
||||
they change often. Furthermore, their generation would require copying of many
|
||||
of the idiosyncrasies of GHC's lowering mechanisms, and in all likelihood place
|
||||
a significant burden on Enso's developers.
|
||||
|
||||
GraalVM, on the other hand, provides a stable interface to writing an
|
||||
interpreter that is far higher level than any of the other options. This API is
|
||||
very unlikely to change, but even if it does the high-level nature means that
|
||||
the maintenance burden of coping with those changes is significantly reduced.
|
||||
Furthermore, GraalVM comes with the truffle toolkit for building interpreters,
|
||||
and as a result provides many of the facilities required by Enso for free or at
|
||||
least for little effort.
|
||||
|
||||
# The Runtime Components
|
||||
Like any sensible large software project, Enso's runtime is modular and broken
|
||||
down into components. These are described in detail below.
|
||||
|
||||
## Language Server
|
||||
The language server component is responsible for controlling the runtime itself.
|
||||
It communicates with other portions of the ecosystem (such as the REPL and the
|
||||
Enso Studio backend) via a protocol. While this protocol is based on the
|
||||
[Language Server Protocol](https://microsoft.github.io/language-server-protocol/specification),
|
||||
it has been extended significantly to better support Enso's use-cases.
|
||||
|
||||
<!-- TODO
|
||||
- A description of the protocol format.
|
||||
- A description of bidirectional protocol operation. This means that Enso's
|
||||
runtime is not purely a server, but can also push data to the client.
|
||||
- A description of how the protocol design admits extensibility.
|
||||
- An informal description of each of the protocol messages, for example \
|
||||
(`expandOptionalArgs`, which expands all defaulted arguments in a call with
|
||||
the defaults as the values). Needs to account for on-demand opt, metadata
|
||||
handling.
|
||||
- A description of how a Luna process should manage source files in server mode,
|
||||
including a description of changesets (dual payload, text diff or AST diff).
|
||||
- https://github.com/luna/luna/issues/365
|
||||
-->
|
||||
|
||||
## Filesystem Driver
|
||||
This component of the runtime deals with access from the runtime to external
|
||||
devices. This includes the Enso code files on disk, but is also responsible for
|
||||
watching filesystem resources (such as databases, files, and sockets) that are
|
||||
used by Enso programs.
|
||||
|
||||
<!-- TODO
|
||||
- A diagram of the interactive file-system watching.
|
||||
- A description of how this layer words.
|
||||
- A design for the strategy for reloading based on source-data changes.
|
||||
-->
|
||||
|
||||
## Typechecker
|
||||
The typechecker is the portion of the runtime that handles the type-inference
|
||||
and type-checking of Enso code. This is a sophisticated piece of machinery, with
|
||||
the primary theory under which it operates being described in the specification
|
||||
of [the type-system](../type-system/types.md).
|
||||
|
||||
<!-- TODO
|
||||
- A description of the typechecker's architecture as graph transformations.
|
||||
- An analysis of how the typechecking process interacts with the interpreter.
|
||||
- An analysis of how we can associate type information with nodes in the Enso
|
||||
graph. A description of what information can be erased.
|
||||
- An analysis of how the typechecker will support for runtime metaprogramming
|
||||
and the manipulation of types.
|
||||
-->
|
||||
|
||||
## Optimiser
|
||||
With much of Enso's performance relying on the JIT optimiser built into Graal,
|
||||
the native language optimiser instead relies on handling more front-end specific
|
||||
optimisations.
|
||||
|
||||
<!-- TODO
|
||||
- A diagram of the optimisation process.
|
||||
- A description of its architecture.
|
||||
- A description of the optimisations that it needs to perform to generate a
|
||||
sensible input to GraalVM.
|
||||
- A description of additional transformations it needs to perform (e.g. for
|
||||
the handling of strictness).
|
||||
- A design for hierarchical description of optimisation passes.
|
||||
- A design for parallel local optimisation.
|
||||
-->
|
||||
|
||||
## Interpreter and JIT
|
||||
The interpreter component is responsible for the actual execution of Enso code.
|
||||
It is built on top of the Truffle framework provided by GraalVM, and is JIT
|
||||
compiled by GraalVM.
|
||||
|
||||
<!-- TODO
|
||||
- A design for encoding the execution model for Lazy and Strict computations.
|
||||
- A design for encoding the evaluation of monadic contexts (how `=` works).
|
||||
- A design for the compilation strategy (what is resolved when).
|
||||
- A design for how we work with wired-in functionality (e.g. the stdlib).
|
||||
- An analysis of techniques that can be used to minimise interpreter startup
|
||||
time.
|
||||
- A description of support for library precompilation.
|
||||
- An analysis of how the interpreter is involved in the typechecking process.
|
||||
-->
|
||||
|
||||
# Cross-Cutting Concerns
|
||||
The runtime also has to deal with a number of concerns that don't fit directly
|
||||
into the above components, but are nevertheless important parts of the design.
|
||||
|
||||
## Caching
|
||||
The runtime cache for Enso is a key part of how it delivers exceptional
|
||||
performance when working on big data sets. The key recognition, as seen in many
|
||||
data processing tools, is that changing code or data often doesn't require the
|
||||
interpreter to recompute the entire program. Instead, it can only recompute the
|
||||
portions that are required of it, while using cached results for the rest.
|
||||
|
||||
<!-- TODO
|
||||
- Describe the architecture of the cache.
|
||||
- Describe the dependency-tracking, keying, and cache eviction strategies with a
|
||||
focus on granularity, performance, and type information (e.g. strictness).
|
||||
- Describe the LRU mechanism that can be used to constrain cache size to under a
|
||||
certain amount of RAM.
|
||||
- A description of how the cache is made IO aware and operates in relation to
|
||||
the filesystem layer (see Skip for more ideas).
|
||||
- An examination of how cache state can be persisted to disk to enable fast
|
||||
reloading of analysis projects.
|
||||
-->
|
||||
|
||||
## Profiling and Debugging
|
||||
Similarly important to the Enso user experience is the ability to visually
|
||||
debug and profile programs. This component deals with the retrieval, storage,
|
||||
and manipulation of profiling data, as well as the ability to debug programs in
|
||||
Enso using standard and non-standard debugging paradigms.
|
||||
|
||||
<!-- TODO
|
||||
- An analysis of how breakpoints can be set in the Truffle interpreter.
|
||||
- A design for a framework / API for introspection of the interpreter state.
|
||||
- An analysis of how the JVM tools can be used to collect Enso-side profiling
|
||||
information.
|
||||
- A design for this profiling data collection and a discussion of how to expose
|
||||
it to users.
|
||||
-->
|
||||
|
||||
## Foreign Language Interoperability
|
||||
This component deals with using the GraalVM language interoperability features
|
||||
to provide a seamless interface to foreign code from inside Enso.
|
||||
|
||||
<!-- TODO
|
||||
- A design for standard, unsafe, C-level FFI using JNI.
|
||||
- A design for what types can be exposed across the C-FFI boundary.
|
||||
- A design for how to expose foreign languages to Luna in a safe fashion.
|
||||
- An analysis of how Luna can minimise the conversions that take place when
|
||||
going between languages.
|
||||
-->
|
||||
|
||||
## Lightweight Concurrency
|
||||
Though not strictly a component, this section deals with how Enso can provide
|
||||
its users with lightweight concurrency primitives in the form of green threads.
|
||||
|
||||
<!-- TODO
|
||||
- Examine how the JVM's basic concurrency primitives can be used in Enso.
|
||||
- A design for how these can be used for automatic parallelism.
|
||||
- An examination of how Project Loom could be employed to provide users with
|
||||
lightweight concurrency in Enso, thereby avoiding async/await 'colouring' of
|
||||
functions.
|
||||
-->
|
||||
|
||||
# The Initial Version of the Runtime
|
||||
In order to have a working version of the new runtime as quickly as possible, it
|
||||
was decided to design and build an initial, stripped-down version of the final
|
||||
design. This design focused on development of a minimal working subset of the
|
||||
runtime that would allow Enso to run.
|
||||
|
||||
<!-- TODO
|
||||
- Describe a design for a dynamic-only runtime
|
||||
- Describe hardcoded support for IO, State, Exception (!) monads
|
||||
-->
|
||||
|
||||
# Development Considerations
|
||||
As part of developing the new Enso runtime, the following things need to be
|
||||
accounted for. This is to ensure that the eventual quality of the software is
|
||||
high, and that we also provide a product that is actually useful to our users.
|
||||
|
||||
- **Benchmarking:** A comprehensive micro and macro benchmark suite that tests
|
||||
all the components of the runtime. This should be accompanied by a regression
|
||||
suite to catch performance regressions.
|
||||
- **Execution Tests:** A test suite that checks that executing Enso programs
|
||||
results in the correct outputs.
|
||||
- **Typechecker Tests:** A test suite that ensures that changes made to the
|
||||
typechecker do not result in acceptance of ill-typed programs, or rejection of
|
||||
well-typed programs.
|
||||
- **Caching Tests:** A test suite that ensures that data is evicted from the
|
||||
cache when it should be, and retained when it should be.
|
2917
doc/design/syntax/syntax.md
Normal file
2917
doc/design/syntax/syntax.md
Normal file
File diff suppressed because it is too large
Load Diff
BIN
doc/design/type-system/.DS_Store
vendored
Normal file
BIN
doc/design/type-system/.DS_Store
vendored
Normal file
Binary file not shown.
1049
doc/design/type-system/types.md
Normal file
1049
doc/design/type-system/types.md
Normal file
File diff suppressed because it is too large
Load Diff
7
doc/graphmod/run.sh
Executable file
7
doc/graphmod/run.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
SELF="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
ROOT=$SELF/../..
|
||||
|
||||
find $ROOT/core/src -name "*.hs" -print | xargs graphmod -p > $SELF/dist/overview.dot
|
||||
dot -Tpng -Gdpi=600 $SELF/dist/overview.dot > $SELF/dist/overview.png
|
1375
doc/haskell-style-guide.md
Normal file
1375
doc/haskell-style-guide.md
Normal file
File diff suppressed because it is too large
Load Diff
306
doc/scala-style-guide.md
Normal file
306
doc/scala-style-guide.md
Normal file
@ -0,0 +1,306 @@
|
||||
# Scala Style Guide
|
||||
Like many style guides, this Scala style guide exists for two primary reasons.
|
||||
The first is to provide guidelines that result in a consistent code style across
|
||||
all of the Luna codebases, while the second is to guide people towards a style
|
||||
that is expressive while still easy to read and understand.
|
||||
|
||||
In general, it aims to create a set of 'zero-thought' rules in order to ease the
|
||||
programmer burden; there is usually only _one way_ to lay out code correctly.
|
||||
|
||||
<!-- MarkdownTOC levels="2,3" autolink="true" -->
|
||||
|
||||
- [Code Formatting](#code-formatting)
|
||||
- [Naming](#naming)
|
||||
- [Imports](#imports)
|
||||
- [Visibility](#visibility)
|
||||
- [Section Headers](#section-headers)
|
||||
- [Build Tooling](#build-tooling)
|
||||
- [Commenting](#commenting)
|
||||
- [Documentation Comments](#documentation-comments)
|
||||
- [Source Notes](#source-notes)
|
||||
- [TODO Comments](#todo-comments)
|
||||
- [Other Comment Usage](#other-comment-usage)
|
||||
- [Program Design](#program-design)
|
||||
- [Safety](#safety)
|
||||
- [Testing and Benchmarking](#testing-and-benchmarking)
|
||||
- [Warnings, and Lints](#warnings-and-lints)
|
||||
|
||||
<!-- /MarkdownTOC -->
|
||||
|
||||
## Code Formatting
|
||||
This section explains the rules for visually laying out your code. They provide
|
||||
a robust set of guidelines for creating a consistent visual to the code.
|
||||
|
||||
Primary formatting is dealt with through use of the Scala formatting tool
|
||||
[`scalafmt`](https://scalameta.org/scalafmt/), which enforces rules around
|
||||
whitespace, line-wrapping, and alignment. The Luna repository contains the main
|
||||
[`.scalafmt.conf`](../.scalafmt.conf) configuration file, and this is what
|
||||
should be used for all new Scala projects.
|
||||
|
||||
All files must be formatted using `scalafmt` before commit, and this should be
|
||||
set up as either a precommit hook, or using the integration in IntelliJ. If you
|
||||
use the IntelliJ integration, please note that you need only have the official
|
||||
[Scala Plugin](https://www.jetbrains.com/help/idea/discover-intellij-idea-for-scala.html) installed, and be using IntelliJ 2019.1
|
||||
or later. You should _not_ use the independent Scalafmt plugin.
|
||||
|
||||
### Naming
|
||||
Luna has some fairly simple general naming conventions, though the sections
|
||||
below may provide more rules for use in specific cases.
|
||||
|
||||
- Types are written using `UpperCamelCase`.
|
||||
- Variables and function names are written using `camelCase`.
|
||||
- If a name contains an initialism or acronym, all parts of that initialism
|
||||
should be of the same case: `httpRequest` or `makeHTTPRequest`.
|
||||
- Short variable names such as `a` and `b` should only be used in contexts where
|
||||
there is no other appropriate name, and should _never_ be used to refer to
|
||||
temporary data in a function.
|
||||
- Names should be descriptive, even if this makes them longer.
|
||||
|
||||
### Imports
|
||||
Organisation of imports is simple, and should be ordered alphabetically within
|
||||
each of the following sections. Each section should be separated from the one
|
||||
above using a blank line.
|
||||
|
||||
1. **Standard Library:** Any imports from the standard library.
|
||||
2. **Java Standard Library:** Any imports from the Java standard library.
|
||||
3. **Additional Dependencies:** Imports from project dependencies.
|
||||
|
||||
In general, we prefer not to import unqualified into the package scope, as this
|
||||
just leads to additional clutter.
|
||||
|
||||
### Visibility
|
||||
There is nothing more frustrating than needing to use a function that hasn't
|
||||
been exported from a package. To this end, we strongly discourage making things
|
||||
private or protected in our codebase.
|
||||
|
||||
If, however, you want to indicate that something is for internal use, you use
|
||||
one of the following two methods.
|
||||
|
||||
1. **Nested Types:** Declaration of inner types called `Internal`.
|
||||
2. **Internal Packages:** For a package named `com.luna-lang.package` that
|
||||
contains `MyType`, we can define internal functions and data-types in a
|
||||
package named `com.luna-lang.package.mytype`. This means that these functions
|
||||
can be imported by clients of the API if they need to, but that we provide no
|
||||
guarantees about API stability when using those functions.
|
||||
|
||||
### Section Headers
|
||||
In order to visually break up the code for easier 'visual grepping', we organise
|
||||
it using section headers. These allow us to easily find the section that we are
|
||||
looking for, even in a large file.
|
||||
|
||||
For each Scala type, within the body of the type, we organise functions as
|
||||
follows:
|
||||
|
||||
```hs
|
||||
-- === Definition === --
|
||||
{- The definition of the type goes here -}
|
||||
|
||||
|
||||
-- === API === --
|
||||
{- The API of the type goes here -}
|
||||
|
||||
|
||||
-- === Instances === --
|
||||
{- Any instances for the type go here -}
|
||||
|
||||
```
|
||||
|
||||
The section header must be preceded by three blank lines, while the subsection
|
||||
headers (except the first) should be preceded by two blank lines. Any of these
|
||||
subsections may be omitted if they don't exist.
|
||||
|
||||
## Build Tooling
|
||||
All Scala projects in the Luna organisation should manage their dependencies and
|
||||
build setup using [SBT](hhttps://www.scala-sbt.org/1.x/docs/index.html).
|
||||
|
||||
If you are using IntelliJ, please ensure that you select to use the SBT shell
|
||||
for both imports and builds.
|
||||
|
||||
## Commenting
|
||||
Comments are a tricky area to get right, as we have found that comments often
|
||||
expire quickly and, in absence of a way to validate them, remain incorrect for
|
||||
long periods of time. That is not to say, however, that we eschew comments
|
||||
entirely. Instead, we make keeping comments up to date an integral part of our
|
||||
programming practice, while also limiting the types of comments that we allow.
|
||||
|
||||
When we write comments, we try to follow one general guideline. A comment should
|
||||
explain _what_ and _why_, without mentioning _how_. The _how_ should be
|
||||
self-explanatory from reading the code, and if you find that it is not, that is
|
||||
a sign that the code in question needs refactoring.
|
||||
|
||||
Code should be written in such a way that it guides you over what it does, and
|
||||
comments should not be used as a crutch for badly-designed code.
|
||||
|
||||
### Documentation Comments
|
||||
One of the primary forms of comment that we allow across the Luna codebases is
|
||||
the doc comment. These are intended to be consumed by users of the API, and use
|
||||
the standard [scaladoc](https://docs.scala-lang.org/style/scaladoc.html) syntax.
|
||||
Doc comments should:
|
||||
|
||||
- Provide a short one-line explanation of the object being documented.
|
||||
- Provide a longer description of the object, including examples where relevant.
|
||||
- Explain the arguments to a function where relevant.
|
||||
|
||||
They should not reference internal implementation details, or be used to explain
|
||||
choices made in the function's implementation. See [Source Notes](#source-notes)
|
||||
below for how to indicate that kind of information.
|
||||
|
||||
### Source Notes
|
||||
Source Notes is a mechanism for moving detailed design information about a piece
|
||||
of code out of the code itself. In doing so, it retains the key information
|
||||
about the design while not impeding the flow of the code.
|
||||
|
||||
Source notes are detailed comments that, like all comments, explain both the
|
||||
_what_ and the _why_ of the code being described. In very rare cases, it may
|
||||
include some _how_, but only to refer to why a particular method was chosen to
|
||||
achieve the goals in question.
|
||||
|
||||
A source note comment is broken into two parts:
|
||||
|
||||
1. **Referrer:** This is a small comment left at the point where the explanation
|
||||
is relevant. It takes the following form: `// Note [Note Name]`, where
|
||||
`Note Name` is a unique identifier across the codebase. These names should be
|
||||
descriptive, and make sure you search for it before using it, in case it is
|
||||
already in use.
|
||||
2. **Source Note:** This is the comment itself, which is a large block comment
|
||||
placed after the first function in which it is referred to in the module. It
|
||||
uses the scala block-comment syntax `/* ... */`, and the first line names
|
||||
the note using the same referrer as above: `/* Note [Note Name]`. The name(s)
|
||||
in the note are underlined using a string of the `~` (tilde) character.
|
||||
|
||||
A source note may contain sections within it where necessary. These are titled
|
||||
using the following syntax: `== Note [Note Name (Section Name)]`, and can be
|
||||
referred to from a referrer much as the main source note can be.
|
||||
|
||||
Sometimes it is necessary to reference a source note in another module, but this
|
||||
should never be done in-line. Instead, a piece of code should reference a source
|
||||
note in the same module that references the other note while providing
|
||||
additional context to that reference.
|
||||
|
||||
An example, based on some code in the GHC codebase, can be seen below:
|
||||
|
||||
```scala
|
||||
{
|
||||
def prepRHS (env : SimplEnv, outExpr : OutExpr) : SimplM (SimplEnv, OutExpr) = {
|
||||
(ty1, _ty2) <- coercionKind env // Note [Float Coercions]
|
||||
|
||||
if (!isUnliftedType ty1) {
|
||||
newTy1 = convertTy ty1 // Note [Float Coercions (Unlifted)]
|
||||
|
||||
...more expressions defining prepRHS...
|
||||
}
|
||||
}
|
||||
|
||||
/* Note [Float Coercions]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
When we find the binding
|
||||
x = cast(e, co)
|
||||
we'd like to transform it to
|
||||
x' = e
|
||||
x = cast(x, co) // A trivial binding
|
||||
There's a chance that e will be a constructor application or function, or
|
||||
something like that, so moving the coercion to the usage site may well cancel
|
||||
the coercions and lead to further optimisation.
|
||||
...more stuff about coercion floating...
|
||||
|
||||
== Note [Float Coercions (Unlifted)]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
...explanations of floating for unlifted types...
|
||||
*/
|
||||
}
|
||||
```
|
||||
|
||||
A source note like this is useful whenever you have design decisions to explain,
|
||||
but can also be used for:
|
||||
|
||||
- **Formulae and Algorithms:** If your code makes use of a mathematical formula,
|
||||
or algorithm, it should note where the design element came from, preferably
|
||||
with a link.
|
||||
- **Safety:** Sometimes it is necessary to use an unsafe API in a context where
|
||||
it is trivially made safe. You should always use a source note to explain why
|
||||
its usage is safe in this context.
|
||||
|
||||
### TODO Comments
|
||||
We follow a simple convention for `TODO` comments in our codebases:
|
||||
|
||||
- The line starts with `TODO` or `FIXME`.
|
||||
- It is then followed by the author's initials `[ARA]`, or for multiple people
|
||||
`[ARA, WD]`, in square brackets.
|
||||
- It is then followed by an explanation of what needs to be done.
|
||||
|
||||
For example:
|
||||
|
||||
```scala
|
||||
{
|
||||
// TODO [ARA] This is a bit of a kludge. Instead of X it should to Y, accounting
|
||||
// for the fact that Z.
|
||||
}
|
||||
```
|
||||
|
||||
### Other Comment Usage
|
||||
There are, of course, a few other situations where commenting is very useful:
|
||||
|
||||
- **Commenting Out:** You may comment out code while developing it, but if you
|
||||
commit any commented out code, it should be accompanied by an explanation of
|
||||
why said code can't just be deleted.
|
||||
- **Bugs:** You can use comments to indicate bugs in our code, as well as
|
||||
third-party bugs. In both cases, the comment should link to the issue tracker
|
||||
where the bug has been reported.
|
||||
|
||||
## Program Design
|
||||
Any good style guide goes beyond purely stylistic rules, and also talks about
|
||||
design styles to use in code.
|
||||
|
||||
### Safety
|
||||
It is incredibly important that we can trust the code that we use, and hence we
|
||||
tend to disallow the definition of unsafe functions in our public API. When
|
||||
defining an unsafe function, you must account for the following:
|
||||
|
||||
- It must be named `unsafeX`.
|
||||
- Unsafe functions should only be used in the minimal scope in which it can be
|
||||
shown correct, not in larger pieces of code.
|
||||
- Unsafe function definition must be accompanied by a source note explaining why
|
||||
it is not defined safely (e.g. performance).
|
||||
- Unsafe function usage must be accompanied by a source note explaining why this
|
||||
usage of it is safe.
|
||||
|
||||
Furthermore, we do not allow for code containing pattern matches that can fail.
|
||||
|
||||
### Testing and Benchmarking
|
||||
New code should always be accompanied by tests. These can be unit, integration,
|
||||
or some combination of the two, and they should always aim to test the new code
|
||||
in a rigorous fashion.
|
||||
|
||||
- We tend to use ScalaTest, but also make use of ScalaCheck for property-based
|
||||
testing.
|
||||
- Tests should be declared in the project configuration so they can be trivially
|
||||
run.
|
||||
- A test file should be named after the module it tests.
|
||||
|
||||
Any performance-critical code should also be accompanied by a set of benchmarks.
|
||||
These are intended to allow us to catch performance regressions as the code
|
||||
evolves, but also ensure that we have some idea of the code's performance in
|
||||
general.
|
||||
|
||||
- We use Caliper for our benchmarks.
|
||||
- We measure time, but also memory usage and CPU time where possible.
|
||||
- Where relevant, benchmarks may set thresholds which, when surpassed, cause the
|
||||
benchmark to fail. These thresholds should be set for a release build, and not
|
||||
for a development build.
|
||||
|
||||
_Do not benchmark a development build_ as the data you get will often be
|
||||
entirely useless.
|
||||
|
||||
### Warnings, and Lints
|
||||
In general, we aim for a codebase that is free of warnings and lints, and we do
|
||||
this using the following ideas:
|
||||
|
||||
#### Warnings
|
||||
New code should introduce no new warnings onto master. You may build with
|
||||
warnings on your own branch, but the code that is submitted as part of a PR
|
||||
should not introduce new warnings. You should also endeavour to fix any warnings
|
||||
that you come across during development.
|
||||
|
||||
Sometimes it is impossible to fix a warning (often in situations involving the
|
||||
use of macros). In such cases, you are allowed to suppress the warning locally,
|
||||
but this must be accompanied by a source note explaining why.
|
Loading…
Reference in New Issue
Block a user