Skip to content

Commit

Permalink
Adding "Warnings note" to suspicious sections in types documentation. (
Browse files Browse the repository at this point in the history
  • Loading branch information
JaroslavTulach authored Dec 7, 2024
1 parent 7b4d46e commit 81b0fcc
Show file tree
Hide file tree
Showing 16 changed files with 636 additions and 725 deletions.
19 changes: 19 additions & 0 deletions docs/semantics/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,31 @@ users to deal with errors at runtime in the language.

## Asynchronous Exceptions

> [!WARNING]
> The actionables for this section are:
>
> - Why do we call it asynchronous, when they are synchronous!?
> - Specify the semantics of Enso's async exceptions.
## Broken Values

There is a special [dynamic dispatch](../types/dynamic-dispatch.md) for `Error`
values. A dataflow error dispatch first checks if it may call a method on
`Error` type.

> [!WARNING]
> The actionables for this section are:
>
> - Specify the semantics of Enso's broken values.
## Warnings

> [!WARNING]
> TODO
>
> - Values in Enso may have warnings attached
There is a special [dynamic dispatch](../types/dynamic-dispatch.md) for _values
with warnings_. Before we pass the dispatch to the underlying value,
we check if warning has a method 'overridden' - this is used for `remove_warnings`,
etc.
7 changes: 5 additions & 2 deletions docs/types/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,18 @@ as well as formal specifications where necessary. It discusses the impact of
many syntactic language features upon inference and type checking, and is
instrumental for ensuring that we build the right language.

> [!NOTE]
>
> #### A Note on Syntax
>
> In the aid of precision, this document will use syntax that _may not_ be
> exposed to users. The appearance of a piece of syntax here that is not
> described in the [syntax](../syntax/README.md) document makes no promises as
> to whether said syntax will be exposed in the surface language.
> **Please Note:** The designs in this section are currently very exploratory as
> the type system is not slated from implementation until after 2.0.
> [!WARNING]
> The specification in this section is very outdated and far from
> reality. Sections that are known to be _"off"_ are marked as _warning_.
Information on the type system is broken up into the following sections:

Expand Down
97 changes: 34 additions & 63 deletions docs/types/access-modifiers.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,83 +8,54 @@ order: 4

# Access Modifiers

While we don't usually like making things private in a programming language, it
sometimes the case that it is necessary to indicate that certain fields should
not be touched (as this might break invariants and such like). To this end, Enso
provides an explicit mechanism for access modification.
> [!WARNING]
> Everybody who ever maintained a large system knows [encapsulation is essential](../semantics/encapsulation.md).
>
> While we don't usually like making things private in a programming language, it
> sometimes the case that it is necessary to indicate that certain fields should
> not be touched (as this might break invariants and such like). To this end, Enso
> provides an explicit mechanism for access modification.
Enso targets large user base of _non-programmers_. They are mostly focused on
getting their job done and [encapsulation](../semantics/encapsulation.md) of their own code is the last thing
that comes to their mind.

On the other hand, Enso supports and encourages creation of *sharable libraries*.
Maintainers of such libraries are likely to treat API design and its
backward compatibility seriously. As such they need a way to [encapsulate](../semantics/encapsulation.md)
internals of their libraries and clearly *differentiate public API* and
implementations details.

<!-- MarkdownTOC levels="2,3" autolink="true" -->

- [Access Modification](#access-modification)
- [Private](#private)
- [Unsafe](#unsafe)

<!-- /MarkdownTOC -->

## Access Modification

Access modifiers in Enso work as follows:

- We have a set of access modifiers, namely `private` and `unsafe`.
- We can place these modifiers before a top-level definition.

```ruby
type MyAtomType
type MyAtom a

is_foo : Boolean
is_foo = ...

private private_method a b = ...

unsafe unsafe_method a b = ...
```

- By default, accessing any member under an access modifier is an error when
performed from another module.
- To use members protected by an access modifier, you must _import_ that access
modifier from the file in which you want to access those elements.
*By default* Enso elements (functions, types, methods) are *public*.
One has to use an access modifier to hide and [encapsulate](../semantics/encapsulation.md) them. The
reasoning is: those who don't care can access everything they create without
any restriction. Those who care can make things `private` with an additional
effort.

```ruby
import private Base.Data.Vector
import unsafe Base.Data.Atom
```

- These modified imports are available in _all_ scopes, so it is possible to
limit the scope in which you have access to the modified definitions.
Accessing any member under an access modifier is an error when performed from another project.
Such a check is enforced during runtime.

```ruby
function_using_modifiers v x =
import private Base.Data.Vector
import unsafe Base.Data.Atom

v.mutate_at_index 0 (_ -> x)
x = MyAtom.mutate_field name="sum" (with = x -> x + 20)
x + 20
```

> The actionables for this section are:
>
> - How do we type this?
There is a command line switch to _disable access modifier check_.
It maybe be useful for experimentation. However the general suggestion is:
Avoid using it in production.

## Private

The `private` modifier acts to hide implementation details from clients of the
API. It is:

- Available by default in the `Base` library.
- Able to be avoided using the above-described mechanism.
Encapsulation is an effective _communication mechanism_ among _distributed
groups_ of developers. The `private` modifier hides implementation details from clients of the API.
The primary groups in the Enso case are those who *publish a library*
and those who *consume such a library*.

## Unsafe

While `private` works as you might expect, coming from other languages, the
`unsafe` annotation has additional restrictions:

- It must be explicitly imported from `Base.Unsafe`.
- When you use `unsafe`, you must write a documentation comment on its usage
that contains a section `Safety` that describes why this usage of unsafe is
valid.

> The actionables for this section are:
>
> - Specify `unsafe` properly.
As such Enso supports _library private_ encapsulation.
To hide any element (module, type, constructor, function) away
from *library consumers* prefix such an element with `private` keyword.
115 changes: 64 additions & 51 deletions docs/types/contexts.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@ order: 8

# Monadic Contexts

Coming from a Haskell background, we have found that Monads provide a great
abstraction with which to reason about program behaviour, but they have some
severe usability issues. The main one of these is the lack of automatic lifting,
requiring users to explicitly lift computations through their monad transformer
stack.

For a language as focused on usability as Enso is this really isn't feasible. To
> [!WARNING]
> Reword for people without Haskell background who don't know what _lifting_ is.
>
> Coming from a Haskell background, we have found that Monads provide a great
> abstraction with which to reason about program behaviour, but they have some
> severe usability issues. The main one of these is the lack of automatic lifting,
> requiring users to explicitly lift computations through their monad transformer
> stack.
For a language as focused on usability as Enso is importing all the _complexity
of Haskell monads_ really isn't feasible. To
that end, we have created the notion of a 'Monadic Context', which is a monad
transformer based on Supermonads (see
[references](./references.md#monadic-contexts)). These have special support in
Expand All @@ -33,8 +37,6 @@ the compiler, and hence can be automatically lifted to aid usability.

- [Context Syntax](#context-syntax)
- [Monadic Bind](#monadic-bind)
- [Context Definitions](#context-definitions)
- [Context Lifting](#context-lifting)
- [Inbuilt Contexts](#inbuilt-contexts)
- [IO](#io)
- [State](#state)
Expand All @@ -43,59 +45,70 @@ the compiler, and hence can be automatically lifted to aid usability.

## Context Syntax

There are three main notes about the syntax of contexts:

1. Monadic contexts are defined using the `in` keyword (e.g. `Int in IO`).
2. We have a symbol `!`, which is short-hand for putting something into the
`Exception` monadic context. This is related to broken values.
3. Contexts can be combined by using the standard typeset operators, or nested
through repeated uses of `in`.
> [!WARNING]
> There used to be three main notes about the syntax of contexts:
>
> 1. Monadic contexts are defined using the `in` keyword (e.g. `Int in IO`).
> 2. We have a symbol `!`, which is short-hand for putting something into the
> `Exception` monadic context. This is related to broken values.
> 3. Contexts can be combined by using the standard typeset operators, or nested
> through repeated uses of `in`.
There is no special syntax for contexts anymore.
Since [#3828](https://github.com/enso-org/enso/pull/3828)
Enso is no longer relaying on a haskelly solution.
Rather than that _contexts_ are being manupulated by
_standard library_ functions grouped around
`Standard.Base.Runtime.Context` & co.
```ruby
Runtime.Context.Output.with_enabled <|
File.new "c:\trash.txt" . delete
```

There is still the `!` symbol signaling [presence of errors](./errors.md)
- e.g. _broken values_. However the runtime can handle _broken values_
even without presence of these _exception type signatures_. Thus the
compiler only verifies the referenced types are valid.

## Monadic Bind

It is also important to note that Enso has no equivalent to `<-` in Haskell.
Instead, pure computations are implicitly placed in the `Pure` monadic context,
and `=` acts to 'peel off' the outermost layer of contexts. As such, this means
that `=` _always_ acts as `bind`, greatly simplifying how the type-checker has
to work.

## Context Definitions

Contexts can be defined by users.

> The actionables for this section are:
>
> - How, what, when and why?
## Context Lifting

> The actionables for this section are:
>
> - Specify and explain how automated lifting of monadic contexts works.
> - It depends on the order of `runCtx`
> [!WARNING]
> Who knows what `<-` means in Haskell?
>
> It is also important to note that Enso has no equivalent to `<-` in Haskell.
> Instead, pure computations are implicitly placed in the `Pure` monadic context,
> and `=` acts to 'peel off' the outermost layer of contexts. As such, this means
> that `=` _always_ acts as `bind`, greatly simplifying how the type-checker has
> to work.
## Inbuilt Contexts

Enso includes a set of commonly-used monadic contexts as part of `Base`, its
standard library. These are listed below.
Enso standard library defines `Input`, `Output` and `Dataflow_Stack_Trace`
contects as of Enso 2024.5.1 version. Users cannot define their own.

> The actionables for this section are:
>
> - Determine the full set of contexts that Enso should provide by default.
### State

### IO
The _state_ concept is implement by standard libraries with _no support in the type system_.

> The actionables for this section are:
>
> - Determine the granularity of IO (it's not one context, but a lot).
> - Explain how there is no `runIO`, and IO is just run at the program boundary,
> as well as the impacts of this.
State acts as a [thread local](https://en.wikipedia.org/wiki/Thread-local_storage) variable
of operating system:
<!-- (well, it will when #7117 gets fixed) -->
- an _initializing code_ can set `State` up
- execute some code
- a code somewhere deep the stack (while _initializing code_ is still on the stack)
- may pick the state up
- once the _initializing code_ finishes execution
- the state is gone

### State
It is an example of _tunnelling a value_ from one side (e.g. code) of the "tunnel" to another,
without the "tunnel" (e.g. thee code in between) knowing about it.

> The actionables for this section are:
<!--
> There has to be some Haskell monad concept for it all... but we don't need it
> as Enso is dynamicly typed language.
>
> - Determine exactly how state works (the fact that the 'keys' are preset by
> the `runState`)
> - Describe how dependently-typed maps allow us to provide more flexible
> interfaces in future.
-->

See `Standard.Base.Runtime.State` for more details.
Loading

0 comments on commit 81b0fcc

Please sign in to comment.