Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move Builtin Types and Methods to stdlib #3363

Merged
merged 80 commits into from
May 5, 2022
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
38a2da7
Dynamically replace builtin methods with functions
hubertp Mar 25, 2022
374a94c
Deal with Polyglot split by selectively importing
hubertp Mar 29, 2022
6afa443
Move Array type out of Builtins
hubertp Apr 4, 2022
02ab5b1
Move Ref type + basic test
hubertp Apr 4, 2022
6938b2d
Move Boolean out of Builtins to std library
hubertp Apr 5, 2022
75cd43d
Drop reflection requirement for builtin methods
hubertp Apr 6, 2022
0f89f44
Use constant values to avoid typos
hubertp Apr 6, 2022
91c6432
Move Meta out of builtins
hubertp Apr 7, 2022
43840f2
Revert "Move Boolean out of Builtins to std library"
hubertp Apr 8, 2022
9822d76
wip
hubertp Apr 9, 2022
e561565
Move Any to stdlib
hubertp Apr 11, 2022
9dbfa06
Move Boolean to stdlib
hubertp Apr 11, 2022
c42b092
Missing Booleans.enso from last commit
hubertp Apr 11, 2022
fb10830
Simplify builtins metadata generation
hubertp Apr 11, 2022
fb666c1
Cleanup
hubertp Apr 12, 2022
1dc9594
Simplify resource reading
hubertp Apr 12, 2022
8ca36e8
Merge branch 'develop' into wip/hubert/shadow-definition-builtins-181…
hubertp Apr 12, 2022
a588c80
Move List to stdlib
hubertp Apr 12, 2022
d771a7f
WIP: remove hardcoded builtin types in Builtins
hubertp Apr 13, 2022
d529ad8
Workaround separate compilation problems
hubertp Apr 13, 2022
3cfdedd
Address PR review
hubertp Apr 14, 2022
8ee6654
CamelCase to Snake_Case for builtin types
hubertp Apr 14, 2022
c04f11e
Move DataflowError to stdlib
hubertp Apr 15, 2022
20f8be4
typo
hubertp Apr 15, 2022
fd094e1
Move all error types + text
hubertp Apr 19, 2022
1a2a80a
Move IO stuff
hubertp Apr 19, 2022
8e76ba8
Add missing shared test class
hubertp Apr 19, 2022
d261608
Improve runtime of tests
hubertp Apr 19, 2022
d3e5fa8
Add IO to stdlib
hubertp Apr 19, 2022
75ba97c
DRY
hubertp Apr 19, 2022
870aacd
nit
hubertp Apr 19, 2022
67dafaa
Final AtomConstructor
hubertp Apr 19, 2022
f75be8a
Move Nothing and Function to stdlib
hubertp Apr 20, 2022
f0b45a7
Nits
hubertp Apr 21, 2022
8e7e15f
Cons/Nil are no longer Builtin_Types
hubertp Apr 21, 2022
b6ae3f0
Adapt benchmark fixtures
hubertp Apr 21, 2022
870ef1a
Remove unused imports
hubertp Apr 21, 2022
70d558d
Rename local 'reverse' method in List benchmarks
hubertp Apr 21, 2022
4f1fe32
Amend benchmark with missing import
hubertp Apr 21, 2022
6cfeca0
Make benchmarks happy again
hubertp Apr 21, 2022
b6fe9cc
fix typo
hubertp Apr 21, 2022
f17d3cb
Move runtime builtin types to stdlib
hubertp Apr 22, 2022
e4037b4
Move Prim_Warning to stdlib
hubertp Apr 22, 2022
1a586d9
Builtins is dead, long live builtins
hubertp Apr 25, 2022
da040f8
Missed some test adaptation
hubertp Apr 25, 2022
4e4535e
Getting rid of Standard.Builtins mentions
hubertp Apr 25, 2022
10d1a52
Remove empty Builtins.enso references
hubertp Apr 25, 2022
5ae3289
Automatic formatting
hubertp Apr 25, 2022
69ad669
Remove extension method for unimplemented error
hubertp Apr 25, 2022
966c2f1
Merge branch 'develop' into wip/hubert/shadow-definition-builtins-181…
hubertp Apr 25, 2022
1372387
Minor adjustments to expectations
hubertp Apr 25, 2022
9a703a3
Update Changelog
hubertp Apr 25, 2022
2ddcf9f
More docs for annotation processors
hubertp Apr 25, 2022
c927582
More Standard.Builtins purge
hubertp Apr 25, 2022
f7145e8
Merge branch 'develop' into wip/hubert/shadow-definition-builtins-181…
hubertp Apr 28, 2022
1ecd317
Follow up on merge with develop
hubertp Apr 28, 2022
a384ed0
PR review re IO and Prim_Io modules
hubertp Apr 28, 2022
40ad2c7
PR review Numbers
hubertp Apr 28, 2022
23e9298
Remove builtin Ordering type
hubertp Apr 28, 2022
a33b45d
Move FIXME comment on Ref to pivotal ticket
hubertp Apr 28, 2022
0c5c19c
Remove leftover comment
hubertp Apr 28, 2022
3417b66
More cleanups, as per PR comments
hubertp Apr 28, 2022
7dc9a34
Formatting
hubertp Apr 28, 2022
3adc0ef
Remove logic to handle Any/Nothing methods
hubertp Apr 29, 2022
dc11b5a
Auto-generate Builtins Constants
hubertp Apr 29, 2022
9414fce
Test adjustments to the previous commit
hubertp May 4, 2022
fa4ca5b
Update distribution/lib/Standard/Base/0.0.0-dev/src/Error/Common.enso
hubertp May 4, 2022
cba36f3
Make formatter happy again
hubertp May 4, 2022
7bf6261
DRY
hubertp May 4, 2022
fe89bc1
Add a requested compiler assert
hubertp May 4, 2022
1c40d25
Merge branch 'develop' into wip/hubert/shadow-definition-builtins-181…
hubertp May 4, 2022
6ba1bc4
Fix tests
hubertp May 4, 2022
4fde6ba
Increase timeout to avoid FPs
hubertp May 4, 2022
b10bb8c
Turn on IR caches for tests
hubertp May 5, 2022
6f27d5e
Merge branch 'develop' into wip/hubert/shadow-definition-builtins-181…
hubertp May 5, 2022
aeeef17
Fix tests
hubertp May 5, 2022
670cad6
Merge branch 'develop' into wip/hubert/shadow-definition-builtins-181…
hubertp May 5, 2022
6c06032
Make disabling IR cache in tests configurable
hubertp May 5, 2022
c90836d
More formatting
hubertp May 5, 2022
884a7d1
Merge branch 'develop' into wip/hubert/shadow-definition-builtins-181…
hubertp May 5, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
x ->
result = Builtins.Ref.new '{ message: ""}'
result = Ref.new '{ message: ""}'
x.catch err->
message = err.to_display_text
Builtins.Ref.put result ('{ "kind": "Dataflow", "message": ' + message.to_json.to_text + '}')
Builtins.Ref.get result
Ref.put result ('{ "kind": "Dataflow", "message": ' + message.to_json.to_text + '}')
Ref.get result

373 changes: 373 additions & 0 deletions distribution/lib/Standard/Base/0.0.0-dev/src/Data/Any.enso
Original file line number Diff line number Diff line change
@@ -0,0 +1,373 @@
from Standard.Base import all

# The type that subsumes all types.
type Any

## Any is the universal top-type, with all other types being subsumed by it.

If a value of type Any is expected in a given location, _any value_ can
be used in that position.
@Builtin_Type
type Any

## PRIVATE

Executes the provided handler on a dataflow error, or executes as
identity on a non-error value.

Arguments:
- handler: The function to call on this if it is an error value.
catch_primitive : (Error -> Any) -> Any
catch_primitive handler = @Builtin_Method "Any.catch"

## Generic conversion of an arbitrary Enso value to a corresponding textual
representation.

> Example
Getting a textual representation of the number 7.

7.to_text
to_text : Text
to_text = @Builtin_Method "Any.to_text"

## ALIAS Equality

Checks if `this` is equal to `that`.

Arguments:
- that: The object to compare `this` with.

Two values are considered to be equal in Enso when they obey the following
recursive properties:
- At each level, they have the same structure.
- The value of each field in `this` is equal (by this definition) to the
corresponding field in `that`.

! Implementing Your Own Equality
Equality in Enso is defined to allow comparison of any two values
(universal equality), no matter if they are not directly comparable. When
implementing equality for your own types, keep in mind that it needs to
work with any Enso value as the `that` argument.

? Generic Equality and Performance
While the generic equality provided here will work for _all_ values in
Enso, its performance may often be suboptimal. Many types can implement
their own equality operations that will be more efficient than these.

> Example
Checking if the variable `a` is equal to `147`.

from Standard.Base import all

example_equality =
a = 7 * 21
a == 147
== : Any -> Boolean
== that = if Meta.is_same_object this that then True else
this_meta = Meta.meta this
that_meta = Meta.meta that
case Cons this_meta that_meta of
Cons (Meta.Atom _) (Meta.Atom _) ->
c_1 = this_meta.constructor
c_2 = that_meta.constructor
if Meta.is_same_object c_1 c_2 . not then False else
f_1 = this_meta.fields
f_2 = that_meta.fields
0.up_to f_1.length . all i-> (f_1.at i) == (f_2.at i)
Cons (Meta.Error _) (Meta.Error _) -> this_meta.payload == that_meta.payload
Cons (Meta.Polyglot o_1) (Meta.Polyglot o_2) ->
langs_match = (this_meta.get_language == Meta.Java) && (that_meta.get_language == Meta.Java)
if langs_match.not then False else o_1.equals o_2
Cons (Meta.Unresolved_Symbol _) (Meta.Unresolved_Symbol _) ->
(this_meta.name == that_meta.name) && (this_meta.scope == that_meta.scope)
## Constructor comparison is covered by the identity equality.
Primitive objects should define their own equality.
Therefore, there are no more cases to handle in this method.
_ -> False

## ALIAS Inequality

Checks if `this` is not equal to `that`.

Arguments:
- that: The object to compare `this` against.

! Implementing Your Own Inequality
We recommend that you do not implement your own inequality, instead relying
on the default definition given here. If you do, please ensure that you
satisfy universal equality, as described in the documentation for `Any.==`.

> Example
Checking if the variable `a` is not equal to `147`.

from Standard.Base import all

example_inequality =
a = 7 * 21
a != 147
!= : Any -> Boolean
!= that = (this == that).not

## ALIAS Greater Than

Checks if `this` is greater than `that`.

Arguments:
- that: The value to compare `this` against.

To have `>` defined, a type must define `compare_to`, returning an Ordering.

! Implementing Greater Than
Many types can admit a definition of greater than that is more efficient
than the generic one given here. When implementing this for your own types
please ensure that it is semantically equivalent to using `.compare_to`.

> Example
Checking if the variable `a` is greater than `147`.

from Standard.Base import all

example_greater =
a = 7 * 28
a > 147
> : Any -> Boolean
> that = this.compare_to that == Ordering.Greater

## ALIAS Greater Than or Equal

Checks if `this` is greater than or equal to `that`.

Arguments:
- that: The value to compare `this` against.

To have `>=` defined, a type must define both `>` and `==`.

! Implementing Greater Than or Equal
While it is often possible to implement a more efficient version of this
operation for complex types, care must be taken to ensure that your
implementation is semantically equivalent to the disjunction of the
greater than and equal to operations.

> Example
Checking if the variable `a` is greater than or equal to `147`.

from Standard.Base import all

example_greater_eq =
a = 6 * 21
a >= 147
>= : Any -> Boolean
>= that = (this > that) || (this == that)

## ALIAS Less Than

Checks if `this` is less than `that`.

Arguments:
- that: The value to compare `this` against.

To have `<` defined, a type must define `compare_to`, returning an Ordering.

! Implementing Less Than
Many types can admit a definition of less than that is more efficient than
the generic one given here. When implementing this for your own types
please ensure that it is semantically equivalent to using `.compare_to`.

> Example
Checking if the variable `a` is less than `147`.

from Standard.Base import all

example_less =
a = 7 * 21
a < 147
< : Any -> Boolean
< that = this.compare_to that == Ordering.Less

## ALIAS Less Than or Equal

Checks if `this` is less than or equal to `that`.

Arguments:
- that: The value to compare `this` against.

To have `<=` defined, a type must define both `<` and `==`.

! Implementing Less Than or Equal
While it is often possible to implement a more efficient version of this
operation for complex types, care must be taken to ensure that your
implementation is semantically equivalent to the disjunction of the
less than than and equal to operations.

> Example
Checking if the variable `a` is less than or equal to `147`.

from Standard.Base import all

example_less_eq =
a = 7 * 21
a < 147
<= : Any -> Boolean
<= that = (this < that) || (this == that)

## Checks if the type is an instance of `Nothing`.

Nothing in Enso is used as a universal value to indicate the lack of presence
of a value. This function is primarily useful in the IDE.

> Example
Checking if the value 1 is nothing.

1.is_nothing
is_nothing : Boolean
is_nothing = case this of
Nothing -> True
_ -> False

## Executes the provided handler on an error, or returns a non-error value
unchanged.

Arguments:
- handler: The function to call on this if it is an error value. By default
this is identity.

> Example
Catching an erroneous value and getting the length of its message.

from Standard.Base import all

example_catch =
error = Error.throw "My message"
error.catch (err -> err.length)
catch : (Error -> Any) -> Any
catch (handler = x->x) = this.catch_primitive handler

## Transforms an error.

Arguments:
- f: The function used to transform the error.

If `this` is a non-error value it is returned unchanged. However, if `this`
is an error, the error is transformed using the provided function.

> Example
Transforming an error value to provide more information.

from Standard.Base import all
from Standard.Examples import Example_Error_Type

example_map_error =
my_map = Map.empty
error = my_map.get "x"
error.map_error (_ -> Example_Error_Type "x is missing")
map_error : (Error -> Error) -> Any
map_error _ = this

## Checks if `this` is an error.

> Example
Checking if the provided value is an error.

1.is_error
is_error : Boolean
is_error = False

## Applies the provided function to `this` unless `this` is `Nothing`, which is
returned unchanged.

Arguments:
- f: The function to apply to `this` if `this` is not `Nothing`.

> Example
Applying a function over a value 10.

10.map_nothing *2
map_nothing : (a -> b) -> b | Nothing
map_nothing f = case this of
Nothing -> Nothing
a -> f a

## Applies the function `this` to the provided argument.

Arguments:
- argument: The argument to apply `this` to.

? Piping Blocks to Functions
This construction is particularly useful for passing a block as an argument
to a function. This means that you can compute more sophisticated values
in-line, as shown in the example below.

> Example
Applying a function to a block.

(x -> x + 1) <|
y = 1 ^ 3
3 + y
<| : Any -> Any
<| ~argument = this argument

## Applies the function on the right hand side to the argument on the left.

Arguments
- function: The function to apply to `this`.

? `|>` or `.`?
The eagle-eyed reader will notice that the operator dot (`.`) is very
similar to the operator `|>`. In Enso, with the variable precedence of
operators, this makes perfect sense. In general, we recommend using `.`.
However, there are some contexts where variable precedence might be unclear
or confusing, or where the function being applied is not a method. In these
contexts we recommend using `|>`.

> Example
Applying multiple functions in a pipeline to compute a number and transform
it to text.

1 |> (* 2) |> (/ 100) |> .to_text
|> : (Any -> Any) -> Any
|> ~function = function this

## Composes two functions together, for `f << g` creating the function
composition `f ∘ g` (equivalent to `x -> f (g x)`).

Arguments:
- that: The function to compose with `this`.

> Example
Multiply by 2 and then add 1 as a function applied to 2.

(+1 << *2) 2
<< : (Any -> Any) -> (Any -> Any) -> Any -> Any
<< ~that = x -> this (that x)

## Composes two functions together in the forward direction, for `f >> g`
creating the function composition `g ∘ f` (equivalent to `x -> g (f (x))`).

Arguments:
- that: The function to compose with `this`.

> Example
Add one and then multiply by two as a function applied to 2.

(+1 >> *2) 2
>> : (Any -> Any) -> (Any -> Any) -> Any -> Any
>> ~that = x -> that (this x)

## UNSTABLE
ADVANCED

Returns a Text used to display this value in the IDE.

The particular representation is left unspecified and subject to change in
the future. The current implementation uses JSON serialization as the
default.

Types defining their own versions of this method should ensure that the
result is reasonably small and that the operation is quick to compute.

> Example
Converting the number `2` into visualization data.

2.to_default_visualization_data
to_default_visualization_data : Text
to_default_visualization_data = this.to_json.to_text
Loading