Merge branch 'master' of github.com:luna/enso

This commit is contained in:
Wojciech Danilo 2019-06-12 12:48:42 +02:00
commit 6f84b8a772
23 changed files with 7024 additions and 10 deletions

53
.github/ISSUE_TEMPLATE/bug-report.md vendored Normal file
View 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
View 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.
-->

View 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
View 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
View 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
View File

@ -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

View File

@ -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
View 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
View 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
View 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
View 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 developers 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.

View File

@ -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

Binary file not shown.

BIN
doc/design/.DS_Store vendored Normal file

Binary file not shown.

View 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.

View 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.

View 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

File diff suppressed because it is too large Load Diff

BIN
doc/design/type-system/.DS_Store vendored Normal file

Binary file not shown.

File diff suppressed because it is too large Load Diff

7
doc/graphmod/run.sh Executable file
View 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

File diff suppressed because it is too large Load Diff

306
doc/scala-style-guide.md Normal file
View 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.