Clean up the standard library docs (#1641)

This commit is contained in:
Ara Adkins 2021-04-01 12:20:36 +01:00 committed by GitHub
parent 8d77a565eb
commit 9585080ab8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
90 changed files with 4955 additions and 1632 deletions

62
.github/CODEOWNERS vendored
View File

@ -2,52 +2,52 @@
* @iamrecursion @kustosz @radeusgd * @iamrecursion @kustosz @radeusgd
# Distribution # Distribution
/distribution @iamrecursion @kustosz @radeusgd /distribution @iamrecursion @kustosz @radeusgd @4e6
/distribution/std-lib @iamrecursion @kustosz @wdanilo /distribution/std-lib @iamrecursion @kustosz @wdanilo @4e6
# Scala Libraries # Scala Libraries
/lib/scala/cli @iamrecursion @kustosz @radeusgd /lib/scala/cli @iamrecursion @kustosz @radeusgd @4e6
/lib/scala/core-definition @iamrecursion @kustosz /lib/scala/core-definition @iamrecursion @kustosz @4e6
/lib/scala/flexer @iamrecursion @kustosz /lib/scala/flexer @iamrecursion @kustosz @4e6
/lib/scala/graph @iamrecursion @kustosz /lib/scala/graph @iamrecursion @kustosz @4e6
/lib/scala/interpreter-dsl @iamrecursion @kustosz /lib/scala/interpreter-dsl @iamrecursion @kustosz @4e6
/lib/scala/json-rpc-server @radeusgd @4e6 @iamrecursion @kustosz /lib/scala/json-rpc-server @radeusgd @4e6 @iamrecursion @kustosz
/lib/scala/json-rpc-server-test @radeusgd @4e6 @iamrecursion @kustosz /lib/scala/json-rpc-server-test @radeusgd @4e6 @iamrecursion @kustosz
/lib/scala/logger @kustosz @iamrecursion /lib/scala/logger @kustosz @iamrecursion @4e6
/lib/scala/parser-service @kustosz @iamrecursion /lib/scala/parser-service @kustosz @iamrecursion @4e6
/lib/scala/pkg @iamrecursion @kustosz /lib/scala/pkg @iamrecursion @kustosz @4e6
/lib/scala/project-manager @radeusgd @4e6 @kustosz /lib/scala/project-manager @radeusgd @4e6 @kustosz
/lib/scala/searcher @4e6 @radeusgd @kustosz /lib/scala/searcher @4e6 @radeusgd @kustosz @iamrecursion
/lib/scala/syntax @iamrecursion @kustosz /lib/scala/syntax @iamrecursion @kustosz @4e6
/lib/scala/testkit @4e6 @kustosz @iamrecursion /lib/scala/testkit @4e6 @kustosz @iamrecursion
/lib/scala/text-buffer @iamrecursion @kustosz /lib/scala/text-buffer @iamrecursion @kustosz @4e6
/lib/scala/version-output @iamrecursion @kustosz @radeusgd /lib/scala/version-output @iamrecursion @kustosz @radeusgd @4e6
# Rust Libraries # Rust Libraries
/lib/rust/ @iamrecursion @wdanilo @radeusgd /lib/rust/ @iamrecursion @wdanilo @radeusgd
# Main Project # Main Project
/engine/language-server @radeusgd @4e6 @kustosz /engine/language-server @radeusgd @4e6 @kustosz @iamrecursion
/engine/launcher @iamrecursion @kustosz @radeusgd /engine/launcher @iamrecursion @kustosz @radeusgd @4e6
/engine/polyglot-api @iamrecursion @kustosz /engine/polyglot-api @iamrecursion @kustosz @4e6
/engine/runner @iamrecursion @kustosz @radeusgd /engine/runner @iamrecursion @kustosz @radeusgd @4e6
/engine/runtime @iamrecursion @kustosz @radeusgd /engine/runtime @iamrecursion @kustosz @radeusgd @4e6
# Documentation # Documentation
/docs @iamrecursion @kustosz /docs @iamrecursion @kustosz @4e6
/.gitignore @iamrecursion @kustosz /.gitignore @iamrecursion @kustosz @4e6
/.jvmopts @iamrecursion @kustosz /.jvmopts @iamrecursion @kustosz @4e6
/.scalafmt.conf @iamrecursion @kustosz /.scalafmt.conf @iamrecursion @kustosz @4e6
/CODE_OF_CONDUCT.md @iamrecursion @kustosz /CODE_OF_CONDUCT.md @iamrecursion @kustosz @4e6
/LICENSE @iamrecursion @kustosz /LICENSE @iamrecursion @kustosz @4e6
README.md @iamrecursion @kustosz README.md @iamrecursion @kustosz @4e6
# Config # Config
/.github @iamrecursion @kustosz /.github @iamrecursion @kustosz @4e6
/.github/workflows @iamrecursion @kustosz @radeusgd /.github/workflows @iamrecursion @kustosz @radeusgd @4e6
/tools @iamrecursion @kustosz @radeusgd /tools @iamrecursion @kustosz @radeusgd @4e6
/project @iamrecursion @kustosz @radeusgd /project @iamrecursion @kustosz @radeusgd @4e6
/build.sbt @iamrecursion @kustosz @radeusgd /build.sbt @iamrecursion @kustosz @radeusgd @4e6
# Repo Configuration # Repo Configuration
/.github/settings.yml @iamrecursion /.github/settings.yml @iamrecursion

View File

@ -1,6 +1,6 @@
license: APLv2 license: APLv2
name: Standard name: Standard
enso-version: default enso-version: default
version: "0.0.1" version: "0.1.0"
author: "Enso Team <contact@enso.org>" author: "Enso Team <contact@enso.org>"
maintainer: "Enso Team <contact@enso.org>" maintainer: "Enso Team <contact@enso.org>"

View File

@ -3,10 +3,24 @@ from Standard.Base import all
## Checks if `this` is equal to `that.` ## Checks if `this` is equal to `that.`
Arguments: Arguments:
- that: The object to compare `this` against. - that: The object to compare `this` with.
Two values are considered to be equal in Enso when they have the same Two values are considered to be equal in Enso when they obey the following
structure, and each of the values of their fields are recursively equal. 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 > Example
Checking if 1 is equal to 2. Checking if 1 is equal to 2.
@ -29,7 +43,7 @@ Any.== that = if Meta.is_same_object this that then True else
if langs_match.not then False else o_1.equals o_2 if langs_match.not then False else o_1.equals o_2
## Constructor comparison is covered by the identity equality. ## Constructor comparison is covered by the identity equality.
Primitive objects should define their own equality. Primitive objects should define their own equality.
Therefore, there is no more cases to handle in this method. Therefore, there are no more cases to handle in this method.
_ -> False _ -> False
## Checks if `this` is not equal to `that`. ## Checks if `this` is not equal to `that`.
@ -37,6 +51,11 @@ Any.== that = if Meta.is_same_object this that then True else
Arguments: Arguments:
- that: The object to compare `this` against. - 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 > Example
Checking if 1 is not equal to 2. Checking if 1 is not equal to 2.
1 != 2 1 != 2
@ -45,53 +64,111 @@ Any.!= that = (this == that).not
## Checks if `this` is greater than `that`. ## 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. 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 > Example
Compare two integers. Checking if 1 is greater than 10.
1 > 10 == False 1 > 10
Any.> : Any -> Boolean Any.> : Any -> Boolean
Any.> that = this.compare_to that == Ordering.Greater Any.> that = this.compare_to that == Ordering.Greater
## 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 1 is greater than or equal to 10.
1 >= 10
Any.>= : Any -> Boolean
Any.>= that = (this > that) || (this == that)
## Checks if `this` is less than `that`. ## 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. 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 > Example
Compare two integers. Checking if 1 is less than 10.
1 < 10 == True 1 < 10
Any.< : Any -> Boolean Any.< : Any -> Boolean
Any.< that = this.compare_to that == Ordering.Less Any.< that = this.compare_to that == Ordering.Less
## Checks if the type is an instance of `Nothing`. ## 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 > Example
Checking if a variable `a` is nothing. Checking if 1 is less than or equal to 10.
a.is_nothing 1 <= 10
Any.<= : Any -> Boolean
Any.<= 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
Any.is_nothing : Boolean Any.is_nothing : Boolean
Any.is_nothing = case this of Any.is_nothing = case this of
Nothing -> True Nothing -> True
_ -> False _ -> False
## Executes the provided handler on a dataflow error, or executes as identity on ## Executes the provided handler on a dataflow error, or returns a non-error
a non-error value. value unchanged.
Arguments: Arguments:
- handler: The function to call on this if it is an error value. By default - handler: The function to call on this if it is an error value. By default
this is identity. this is identity.
> Example > Example
Catching an erroneous value to perform some operation on it. Catching an erroneous value and getting the length of its message.
(Time.Time_Error "Message").catch (err -> IO.println err) (Time.Time_Error "Message").catch (err -> err.error_message.length)
Any.catch : (Error -> Any) -> Any Any.catch : (Error -> Any) -> Any
Any.catch (handler = x->x) = this.catch_primitive handler Any.catch (handler = x->x) = this.catch_primitive handler
## Maps a dataflow error. ## Transforms an error.
If the original value was a non-error value, it is not affected, but if it
was an error, the error is mapped through the provided function.
Arguments: Arguments:
- f: The function to transform the error. - 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 > Example
Wrapping an error value. Wrapping an error value.
@ -99,7 +176,7 @@ Any.catch (handler = x->x) = this.catch_primitive handler
Any.map_error : (Error -> Error) -> Any Any.map_error : (Error -> Error) -> Any
Any.map_error _ = this Any.map_error _ = this
## Checks if the underlying value is an error. ## Checks if `this` is an error.
Any.is_error : Boolean Any.is_error : Boolean
Any.is_error = False Any.is_error = False
@ -108,6 +185,11 @@ Any.is_error = False
Arguments: Arguments:
- argument: The argument to apply `this` to. - 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 > Example
Applying a function to a block. Applying a function to a block.
(x -> x + 1) <| (x -> x + 1) <|
@ -121,28 +203,35 @@ Any.<| ~argument = this argument
Arguments Arguments
- function: The function to apply to `this`. - 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 > Example
Applying a function in a pipeline. Applying multiple functions in a pipeline to compute a number and transform
1 |> (* 2) it to text.
1 |> (* 2) |> (/ 100) |> .to_text
Any.|> : (Any -> Any) -> Any Any.|> : (Any -> Any) -> Any
Any.|> function = function this Any.|> ~function = function this
## Composes two functions together. ## Composes two functions together, for `f << g` creating the function
composition `f ∘ g` (equivalent to `x -> f (g x)`).
For `f << g`, this creates the function composition `f ∘ g`.
Arguments: Arguments:
- that: The function to compose with `this`. - that: The function to compose with `this`.
> Example > Example
Compose the functions +1 and *2 and apply it to 2 Multiply by 2 and then add 1 as a function applied to 2.
(+1 << *2) 2 (+1 << *2) 2
Any.<< : (Any -> Any) -> (Any -> Any) -> Any -> Any Any.<< : (Any -> Any) -> (Any -> Any) -> Any -> Any
Any.<< that = x -> this (that x) Any.<< ~that = x -> this (that x)
## Composes two functions together in the forward direction. ## Composes two functions together in the forward direction, for `f >> g`
creating the function composition `g ∘ f` (equivalent to `x -> g (f (x))`).
For `f >> g`, this creates the function composition `g ∘ f`.
Arguments: Arguments:
- that: The function to compose with `this`. - that: The function to compose with `this`.
@ -151,16 +240,22 @@ Any.<< that = x -> this (that x)
Add one and then multiply by two as a function applied to 2. Add one and then multiply by two as a function applied to 2.
(+1 >> *2) 2 (+1 >> *2) 2
Any.>> : (Any -> Any) -> (Any -> Any) -> Any -> Any Any.>> : (Any -> Any) -> (Any -> Any) -> Any -> Any
Any.>> that = x -> that (this x) Any.>> ~that = x -> that (this x)
## UNSTABLE ## UNSTABLE
ADVANCED ADVANCED
Returns a Text used to display this value in the IDE. The particular Returns a Text used to display this value in the IDE.
representation is left unspecified and subject to change in the future.
The current implementation uses a JSON serialization as the default. 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 Types defining their own versions of this method should ensure that the
result is reasonably small and the operation is quick to compute. 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
Any.to_default_visualization_data : Text Any.to_default_visualization_data : Text
Any.to_default_visualization_data = this.to_json.to_text Any.to_default_visualization_data = this.to_json.to_text

View File

@ -1,8 +1,18 @@
from Standard.Base import all from Standard.Base import all
## Transform the array into text for displaying as part of its default ## UNSTABLE
visualization. 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.
> Example
Converting an array to its default visualization representation.
[1, 2, 3, 4].to_array.to_default_visualization_data
Array.to_default_visualization_data : Text Array.to_default_visualization_data : Text
Array.to_default_visualization_data = Array.to_default_visualization_data =
Vector.Vector this . to_default_visualization_data Vector.Vector this . to_default_visualization_data

View File

@ -38,10 +38,19 @@ inclusive start end = Interval (Bound.Inclusive start) (Bound.Inclusive end)
## An interval type ## An interval type
type Interval type Interval
## A type representing an interval over orderable types.
Arguments:
- start: The start of the interval.
- end: The end of the interval.
type Interval start end type Interval start end
## Checks if the interval contains `that`. ## Checks if the interval contains `that`.
Arguments:
- that: The item to check if it is contained in the interval.
> Example > Example
Checking if the interval 1 to 5 contains 7. Checking if the interval 1 to 5 contains 7.
(Interval.inclusive 1 5) . contains 7 (Interval.inclusive 1 5) . contains 7
@ -56,6 +65,10 @@ type Interval
Bound.Inclusive e -> that <= e Bound.Inclusive e -> that <= e
## Check if this interval is empty. ## Check if this interval is empty.
> Example
Check if the interval from 0 to 0 is empty.
Interval.inclusive 0 0 . is_empty
is_empty : Boolean is_empty : Boolean
is_empty = case this.start of is_empty = case this.start of
Bound.Exclusive s -> case this.end of Bound.Exclusive s -> case this.end of
@ -66,6 +79,10 @@ type Interval
Bound.Inclusive e -> s > e Bound.Inclusive e -> s > e
## Check if this interval is not empty. ## Check if this interval is not empty.
> Example
Check if the interval from 0 to 1 is not empty.
Interval.inclusive 0 1 . not_empty
not_empty : Boolean not_empty : Boolean
not_empty = this.is_empty.not not_empty = this.is_empty.not

View File

@ -2,10 +2,25 @@ from Standard.Base import all
## A type representing an interval bound over any orderable type. ## A type representing an interval bound over any orderable type.
An orderable type is one that An orderable type is one that has a
[total order](https://en.wikipedia.org/wiki/Total_order) defined for it.
type Bound type Bound
## A bound that includes `n`. ## A bound that includes the value `n`.
Arguments:
- n: The value defining the inclusive bound.
> Example
Create a bound that includes the value 2.
Inclusive 2
type Inclusive n type Inclusive n
## A bound that excludes `n`. ## A bound that excludes the value `n`.
Arguments:
- n: The value defining the exclusive bound.
> Example
Create a bound that excludes the value 2.
Exclusive 2
type Exclusive n type Exclusive n

View File

@ -4,19 +4,47 @@ import Standard.Base.Data.Json.Internal
## Represents a JSON structure. ## Represents a JSON structure.
type Json type Json
## A representation of a JSON object.
Arguments:
- fields: The fields of the JSON object.
type Object fields type Object fields
## A representation of a JSON array.
Arguments:
- items: The items in the JSON array.
type Array items type Array items
## A representation of a JSON string.
Arguments:
- value: The text contained in the JSON string.
type String value type String value
## A representation of a JSON number.
Arguments:
- value: The number contained in the JSON number.
type Number value type Number value
## A representation of a JSON boolean.
Arguments:
- value: The boolean contained in a JSON boolean.
type Boolean value type Boolean value
## A representation of a JSON null.
type Null type Null
## Marshalls this JSON into an arbitrary value described by ## Marshalls this JSON into an arbitrary value described by
`type_descriptor`. `type_descriptor`.
The type descriptor is a fully-applied type, describing all required Arguments:
sub-types. It can either be an Atom or one of the primitive types - `type_dscriptor`: The type descriptor is a fully-applied type,
(`Number`, `Text`, `Boolean`, `Vector`). describing all required sub-types. It can either be an Atom or one of
the primitive types (`Number`, `Text`, `Boolean`, `Vector`).
> Example > Example
The following shows an example of reading a nested JSON into a desired The following shows an example of reading a nested JSON into a desired
@ -63,10 +91,18 @@ type Json
to_json = this to_json = this
## Renders this JSON into an RFC-8259 compliant text. ## Renders this JSON into an RFC-8259 compliant text.
> Example
Convert a JSON number to text.
Json.Number 3 . to_text
to_text : Text to_text : Text
to_text = Internal.render_helper "" this to_text = Internal.render_helper "" this
## Recursively unwraps the JSON value into primitive values. ## Recursively unwraps the JSON value into primitive values.
> Example
Unwrap the JSON number 3 to the primitive number 3.
Json.Number 3 . unwrap
unwrap : Any unwrap : Any
unwrap = case this of unwrap = case this of
Json.Array its -> its.map .unwrap Json.Array its -> its.map .unwrap
@ -76,21 +112,36 @@ type Json
Json.Null -> Nothing Json.Null -> Nothing
Json.Object f -> f.map .unwrap Json.Object f -> f.map .unwrap
## A failure indicating malformed text input into the JSON parser. ## UNSTABLE
A failure indicating malformed text input into the JSON parser.
Check the `message` field for detailed information on the specific failure. Check the `message` field for detailed information on the specific failure.
type Parse_Error message type Parse_Error message
## Converts the error to a display representation. ## UNSTABLE
Converts the error to a display representation.
Parse_Error.to_display_text : Text Parse_Error.to_display_text : Text
Parse_Error.to_display_text = "Parse error in parsing JSON: " + this.message.to_text + "." Parse_Error.to_display_text = "Parse error in parsing JSON: " + this.message.to_text + "."
## Gets the value associated with the given key in this object. Returns ## Gets the value associated with the given key in this object.
`Nothing` if the associated key is not defined.
Object.get : Text -> Json | Nothing Arguments:
- field: The name of the field from which to get the value.
Throws `Nothing` if the associated key is not defined.
Object.get : Text -> Json ! Nothing
Object.get field = this.fields.get field Object.get field = this.fields.get field
## Parses an RFC-8259 compliant JSON text into a `Json` structure. ## Parses an RFC-8259 compliant JSON text into a `Json` structure.
Arguments:
- json_text: The RFC-8259-compliant JSON text.
> Example
Convert some text representing a JSON object into JSON.
"{ "a": 1 }".parse
parse : Text -> Json ! Parse_Error parse : Text -> Json ! Parse_Error
parse json_text = parse json_text =
r = Panic.recover (Internal.parse_helper json_text) r = Panic.recover (Internal.parse_helper json_text)
@ -98,22 +149,41 @@ parse json_text =
Polyglot_Error err -> Error.throw (Parse_Error err.getMessage) Polyglot_Error err -> Error.throw (Parse_Error err.getMessage)
p -> Panic.throw p p -> Panic.throw p
## A failure indicating the inability to marshall a `Json` object into the ## UNSTABLE
A failure indicating the inability to marshall a `Json` object into the
specified format. specified format.
type Marshalling_Error type Marshalling_Error
## The `json` object could not be converted into `format`, due to a type
## UNSTABLE
The `json` object could not be converted into `format`, due to a type
mismatch. mismatch.
Arguments:
- json: The JSON that could not be marshalled.
- format: The type format that did not match.
This can occur e.g. when trying to reinterpret a number as a `Text`, etc. This can occur e.g. when trying to reinterpret a number as a `Text`, etc.
type Type_Mismatch_Error json format type Type_Mismatch_Error json format
## The `json` object could not be converted into `format`, due to a field ## UNSTABLE
The `json` object could not be converted into `format`, due to a field
missing in the `json` structure. missing in the `json` structure.
Arguments:
- json: The json that had a missing field.
- field: The field name that was missing.
- format: The type format that diud not match.
This can occure when trying to reinterpret a JSON object into an atom, This can occure when trying to reinterpret a JSON object into an atom,
when the JSON does not contain all the fields required by the atom. when the JSON does not contain all the fields required by the atom.
type Missing_Field_Error json field format type Missing_Field_Error json field format
## UNSTABLE
Convert the marshalling error into a human-readable format.
to_display_text : Text to_display_text : Text
to_display_text = case this of to_display_text = case this of
Type_Mismatch_Error json format -> Type_Mismatch_Error json format ->
@ -128,6 +198,10 @@ type Marshalling_Error
The input atom is converted into a JSON object, with a `"type"` field set to The input atom is converted into a JSON object, with a `"type"` field set to
the atom's type name and all other fields serialized with their name as the atom's type name and all other fields serialized with their name as
object key and the value as the object value. object key and the value as the object value.
> Example
Convert a vector to JSON.
[1, 2, 3, 4].to_json
Any.to_json = Any.to_json =
m = Meta.meta this m = Meta.meta this
case m of case m of
@ -147,20 +221,35 @@ Any.to_json =
Meta.Primitive _ -> Null Meta.Primitive _ -> Null
## Method used by object builders to convert a value into a valid JSON key. ## Method used by object builders to convert a value into a valid JSON key.
> Example
Ensure that the text "foo" is a JSON key.
"foo".to_json_key
Text.to_json_key : Text Text.to_json_key : Text
Text.to_json_key = this Text.to_json_key = this
## Boolean to JSON conversion. ## Convert a boolean to JSON.
> Example
Convert `True` to JSON.
True.to_json
Base.Boolean.to_json : Boolean Base.Boolean.to_json : Boolean
Base.Boolean.to_json = Boolean this Base.Boolean.to_json = Boolean this
## Nothing to JSON conversion. ## Convert `Nothing` to JSON.
> Example
Convert `Nothing` to JSON.
Nothing.to_json
Nothing.to_json : Null Nothing.to_json : Null
Nothing.to_json = Null Nothing.to_json = Null
## A smart constructor, building an object representation based on a vector ## A smart constructor, building an object representation based on a vector
of key-value pairs. of key-value pairs.
Arguments:
- contents: A vector of key-value pairs.
All values used as keys must define a `to_json_key : Text` method. All values used as keys must define a `to_json_key : Text` method.
> Example > Example

View File

@ -5,19 +5,40 @@ from Standard.Base.Data.Json import all
polyglot java import org.enso.base.json.Parser polyglot java import org.enso.base.json.Parser
polyglot java import org.enso.base.json.Printer polyglot java import org.enso.base.json.Printer
## A JSON parser event consumer, passed to the Java parser backend. ## PRIVATE
A JSON parser event consumer, passed to the Java parser backend.
Conforms to the `org.enso.base.json.Parser.JsonConsumer` Java interface. Conforms to the `org.enso.base.json.Parser.JsonConsumer` Java interface.
type Consumer type Consumer
## PRIVATE
A JSON parser event consumer, passed to the Java parser backend.
Arguments:
- child_consumer: The child consumer of this.
- value: The value being consumed.
Conforms to the `org.enso.base.json.Parser.JsonConsumer` Java interface.
type Consumer child_consumer value type Consumer child_consumer value
## Helper for handling "value emitted" events. ## PRIVATE
A helper for handling "value emitted" events.
Arguments:
- v: The value to act upon.
on_value : Any -> Nothing
on_value v = case Ref.get this.child_consumer of on_value v = case Ref.get this.child_consumer of
Nil -> Ref.put this.value v Nil -> Ref.put this.value v
cons -> cons.on_value v cons -> cons.on_value v
## Closes the child consumer and either sets the current consumer to its ## PRIVATE
Closes the child consumer and either sets the current consumer to its
parent, or takes its returned value as the final result of parsing. parent, or takes its returned value as the final result of parsing.
seal_child : Nothing
seal_child = seal_child =
child = Ref.get this.child_consumer child = Ref.get this.child_consumer
val = child.seal val = child.seal
@ -28,92 +49,202 @@ type Consumer
Ref.put this.child_consumer p Ref.put this.child_consumer p
p.on_value val p.on_value val
## Consumes the `start_object` event. ## PRIVATE
Consumes the `start_object` event.
on_start_object : Nothing
on_start_object = on_start_object =
parent = Ref.get this.child_consumer parent = Ref.get this.child_consumer
Ref.put this.child_consumer (here.mk_object_consumer parent) Ref.put this.child_consumer (here.mk_object_consumer parent)
## Consumes the `key` event. ## PRIVATE
Consumes the `key` event.
Arguments:
- k: The key to act upon.
on_key : Text -> Nothing
on_key k = Ref.get this.child_consumer . on_key k on_key k = Ref.get this.child_consumer . on_key k
## Consumes the `end_object` event. ## PRIVATE
Consumes the `end_object` event.
on_end_object : Nothing
on_end_object = this.seal_child on_end_object = this.seal_child
## Consumes the `start_array` event. ## PRIVATE
Consumes the `start_array` event.
on_start_array : Nothing
on_start_array = on_start_array =
parent = Ref.get this.child_consumer parent = Ref.get this.child_consumer
Ref.put this.child_consumer (here.mk_array_consumer parent) Ref.put this.child_consumer (here.mk_array_consumer parent)
## Consumes the `end_array` event. ## PRIVATE
Consumes the `end_array` event.
on_end_array : Nothing
on_end_array = this.seal_child on_end_array = this.seal_child
## Consumes the `long` event. ## PRIVATE
Consumes the `long` event.
Arguments:
- n: The long value to process.
on_long : Integer -> Nothing
on_long n = this.on_value (Number n) on_long n = this.on_value (Number n)
## Consumes the `double` event. ## PRIVATE
Consumes the `double` event.
Arguments:
- n: The double value to process.
on_double : Decimal -> Nothing
on_double n = this.on_value (Number n) on_double n = this.on_value (Number n)
## Consumes the `string` event. ## PRIVATE
Consumes the `string` event.
Arguments:
- s: The string value to process.
on_string : Text -> Nothing
on_string s = this.on_value (String s) on_string s = this.on_value (String s)
## Consumes the `true` event. ## PRIVATE
Consumes the `true` event.
on_true : Nothing
on_true = this.on_value (Boolean True) on_true = this.on_value (Boolean True)
## Consumes the `false` event. ## PRIVATE
Consumes the `false` event.
on_false : Nothing
on_false = this.on_value (Boolean False) on_false = this.on_value (Boolean False)
## Consumes the `null` event. ## PRIVATE
Consumes the `null` event.
on_null : Nothing
on_null = this.on_value Null on_null = this.on_value Null
## A child consumer, used to process events inside arrays. ## PRIVATE
A child consumer, used to process events inside arrays.
type Array_Consumer type Array_Consumer
## PRIVATE
A child consumer, used to process events inside arrays.
Arguments:
- builder: The builder for array values.
- parent: The parent consumer.
type Array_Consumer builder parent type Array_Consumer builder parent
## Consumes a value. ## PRIVATE
Consumes a value.
Arguments:
- v: The value to process.
on_value : Any -> Nothing
on_value v = this.builder.append v on_value v = this.builder.append v
## Returns the final value built by this consumer. ## PRIVATE
Returns the final value built by this consumer.
seal : Array
seal = seal =
vec = this.builder.to_vector vec = this.builder.to_vector
Array vec Array vec
## A child consumer, used to process events inside objects. ## PRIVATE
A child consumer, used to process events inside objects.
type Object_Consumer type Object_Consumer
## PRIVATE
A child consumer, used to process events inside objects.
Arguments:
- last_key: The last object key that has been seen.
- map: The map representing the object.
- parent: The parent consumer.
type Object_Consumer last_key map parent type Object_Consumer last_key map parent
## Consumes a key. ## PRIVATE
Consumes a key.
Arguments:
- k: The key to process.
on_key : Text -> Nothing
on_key k = Ref.put this.last_key k on_key k = Ref.put this.last_key k
## Consumes a value. ## PRIVATE
Consumes a value.
Arguments:
- v: The value to process.
on_value : Any -> Nothing
on_value v = on_value v =
k = Ref.get this.last_key k = Ref.get this.last_key
m = Ref.get this.map m = Ref.get this.map
new_m = m.insert k v new_m = m.insert k v
Ref.put this.map new_m Ref.put this.map new_m
## Returns the final value built by this consumer. ## PRIVATE
Returns the final value built by this consumer.
seal : Object
seal = seal =
m = Ref.get this.map m = Ref.get this.map
Object m Object m
## Creates a new object consumer with the given parent. ## PRIVATE
Creates a new object consumer with the given parent.
Arguments:
- parent: The parent of the new consumer.
mk_object_consumer : Any -> Object_Consumer
mk_object_consumer parent = mk_object_consumer parent =
k = Ref.new "" k = Ref.new ""
m = Ref.new Map.empty m = Ref.new Map.empty
Object_Consumer k m parent Object_Consumer k m parent
## Creates a new array consumer with the given parent. ## PRIVATE
Creates a new array consumer with the given parent.
Arguments:
- parent: The parent of the new consumer.
mk_array_consumer : Any -> Array_Consumer
mk_array_consumer parent = mk_array_consumer parent =
bldr = Vector.new_builder bldr = Vector.new_builder
Array_Consumer bldr parent Array_Consumer bldr parent
## Creates a new top-level consumer. ## PRIVATE
Creates a new top-level consumer.
mk_consumer : Consumer
mk_consumer = mk_consumer =
child = Ref.new Nil child = Ref.new Nil
val = Ref.new Nothing val = Ref.new Nothing
Consumer child val Consumer child val
## Helper method for printing JSON values to Text. ## PRIVATE
A helper method for printing JSON values to Text.
Arguments:
- builder: An accumulator for text.
- json: The json value being converted to text.
render_helper : Text -> Json -> Text
render_helper builder json = case json of render_helper builder json = case json of
Object fields -> Object fields ->
r = Ref.new "" r = Ref.new ""
@ -143,9 +274,16 @@ render_helper builder json = case json of
Null -> Null ->
builder + "null" builder + "null"
## Helper method for converting JSON objects into arbitrary types. ## PRIVATE
A helper method for converting JSON objects into arbitrary types.
Arguments:
- fmt: The format to convert the JSON into.
- json: The JSON being converted.
See `Json.into` for semantics documentation. See `Json.into` for semantics documentation.
into_helper : Any -> Json -> Any
into_helper fmt json = case fmt of into_helper fmt json = case fmt of
Base.Vector.Vector field -> case json of Base.Vector.Vector field -> case json of
Array items -> items.map (here.into_helper field) Array items -> items.map (here.into_helper field)
@ -175,7 +313,12 @@ into_helper fmt json = case fmt of
_ -> Panic.throw (Type_Mismatch_Error json fmt) _ -> Panic.throw (Type_Mismatch_Error json fmt)
_ -> Panic.throw (Type_Mismatch_Error json fmt) _ -> Panic.throw (Type_Mismatch_Error json fmt)
## Helper used to parse text into a JSON value. ## PRIVATE
A helper used to parse text into a JSON value.
Arguments:
- json_text: The textual representation of the JSON.
parse_helper : Text -> Json parse_helper : Text -> Json
parse_helper json_text = parse_helper json_text =
consumer = here.mk_consumer consumer = here.mk_consumer

View File

@ -4,6 +4,11 @@ from Builtins export Nil, Cons
## PRIVATE ## PRIVATE
A helper for the `map` function. A helper for the `map` function.
Arguments:
- list: The list to map over.
- cons: The current field to set.
- f: The function to apply to the value.
Uses unsafe field mutation under the hood, to rewrite `map` in Uses unsafe field mutation under the hood, to rewrite `map` in
a tail-recursive manner. The mutation is purely internal and does not leak a tail-recursive manner. The mutation is purely internal and does not leak
to the user-facing API. to the user-facing API.
@ -16,7 +21,7 @@ map_helper list cons f = case list of
## The basic cons-list type. ## The basic cons-list type.
A cons-list allows to store an arbitrary number of elements. A cons-list allows storage of an arbitrary number of elements.
Prepending to the list can be achieved by using the `Cons` constructor, Prepending to the list can be achieved by using the `Cons` constructor,
while an empty list is represented by `Nil`. while an empty list is represented by `Nil`.
@ -29,12 +34,20 @@ type List
Cons Cons
## Computes the number of elements in the list. ## Computes the number of elements in the list.
> Example
Get the length of a two item list.
(Cons 1 (Cons 2 Nil)).length
length : Number length : Number
length = this.fold 0 (acc -> _ -> acc + 1) length = this.fold 0 (acc -> _ -> acc + 1)
## Combines all the elements of the list, by iteratively applying the ## Combines all the elements of the list, by iteratively applying the
passed function with next elements of the list. passed function with next elements of the list.
Arguments:
- init: The initial value for the fold.
- f: The binary function used to combine elements of the list.
In general, the result of In general, the result of
(Cons l0 <| Cons l1 <| ... <| Cons ln) . fold init f (Cons l0 <| Cons l1 <| ... <| Cons ln) . fold init f
is the same as is the same as
@ -54,8 +67,10 @@ type List
## Checks whether any element of the list matches the given predicate. ## Checks whether any element of the list matches the given predicate.
A predicate is a function that takes a list element and returns Arguments:
a Boolean value. - predicate: A function that takes a list element and returns a boolean
value that says whether that value satisfies the conditions of the
function.
> Example > Example
In the following example, we'll check if any element of the list is In the following example, we'll check if any element of the list is
@ -72,6 +87,11 @@ type List
## Checks whether any element of the list matches the given predicate. ## Checks whether any element of the list matches the given predicate.
Arguments:
- predicate: A function that takes a list element and returns a boolean
value that says whether that value satisfies the conditions of the
function.
A predicate is a function that takes a list element and returns A predicate is a function that takes a list element and returns
a Boolean value. a Boolean value.
@ -84,6 +104,11 @@ type List
## Checks whether a predicate holds for all elements in this list. ## Checks whether a predicate holds for all elements in this list.
Arguments:
- predicate: A function that takes a list element and returns a boolean
value that says whether that value satisfies the conditions of the
function.
> Example > Example
Check if all elements in the list are less than zero. Check if all elements in the list are less than zero.
(Cons 1 (Cons 2 Nil)).all (< 0) (Cons 1 (Cons 2 Nil)).all (< 0)
@ -92,6 +117,9 @@ type List
## Checks whether this list contains a given value as an element. ## Checks whether this list contains a given value as an element.
Arguments:
- elem: The element to check if it is in the list.
> Example > Example
Checking if the list contains the number 72. Checking if the list contains the number 72.
(Cons 1 (Cons 72 Nil)).contains 72 (Cons 1 (Cons 72 Nil)).contains 72
@ -118,9 +146,14 @@ type List
## Selects all elements of this list which satisfy a predicate. ## Selects all elements of this list which satisfy a predicate.
Arguments:
- predicate: A function that takes a list element and returns a boolean
value that says whether that value satisfies the conditions of the
function.
> Example > Example
Selecting all elements that are greater than 3. Selecting all elements that are greater than 3.
(Cons 1 Nil).filter (> 3) (Cons 1 Nil).filter (> 3)
filter : (Any -> Boolean) -> List filter : (Any -> Boolean) -> List
filter predicate = filter predicate =
case this of case this of
@ -132,11 +165,12 @@ type List
## Applies a function to each element of the list, returning the list of ## Applies a function to each element of the list, returning the list of
results. results.
Arguments:
- f: The function to apply to each element of the list.
> Example > Example
In the following example, we add `1` to each element of the list: Add `1` to each element of the list:
(Cons 0 <| Cons 1 <| Cons 2 <| Nil) . map +1 (Cons 0 <| Cons 1 <| Cons 2 <| Nil) . map +1
The result of running the code above is:
Cons 1 <| Cons 2 <| Cons 3 <| Nil
map : (Any -> Any) -> List map : (Any -> Any) -> List
map f = case this of map f = case this of
Nil -> Nil Nil -> Nil
@ -147,12 +181,14 @@ type List
## Applies a function to each element of the list. ## Applies a function to each element of the list.
Arguments:
- f: The function to apply to each element of the list.
Unlike `map`, this method does not return the individual results, Unlike `map`, this method does not return the individual results,
therefore it is only useful for side-effecting computations. therefore it is only useful for side-effecting computations.
> Example > Example
In the following example, we're printing each element of the list Print each of the list elements to the standard output.
to the standard output:
(Cons 0 <| Cons 1 <| Cons 2 <| Nil) . each IO.println (Cons 0 <| Cons 1 <| Cons 2 <| Nil) . each IO.println
each : (Any -> Any) -> Nothing each : (Any -> Any) -> Nothing
each f = each f =
@ -176,6 +212,9 @@ type List
## Creates a new list with the first `count` elements at the start of `this` ## Creates a new list with the first `count` elements at the start of `this`
removed. removed.
Arguments:
- count: The number of elements to take drop the start of `this`.
> Example > Example
Removing the first element from a list. Removing the first element from a list.
(Cons 1 (Cons 2 (Nil))).drop_start 1 (Cons 1 (Cons 2 (Nil))).drop_start 1
@ -187,6 +226,9 @@ type List
## Creates a new list consisting of the first `count` elements at the start ## Creates a new list consisting of the first `count` elements at the start
of `this`. of `this`.
Arguments:
- count: The number of elements to take from the start of `this`.
> Example > Example
Obtaining the first 2 elements of a list. Obtaining the first 2 elements of a list.
(Cons 1 (Cons 2 (Cons 3 Nil))).take_start 2 (Cons 1 (Cons 2 (Cons 3 Nil))).take_start 2

View File

@ -15,89 +15,171 @@ default : Locale
default = here.from_java JavaLocale.ROOT default = here.from_java JavaLocale.ROOT
## A locale representing Bangladesh. ## A locale representing Bangladesh.
> Example
Get the Bangladeshi locale.
Locale.bangladesh
bangladesh : Locale bangladesh : Locale
bangladesh = here.from_language_tag "bn-BD" bangladesh = here.from_language_tag "bn-BD"
## A locale representing Brazil. ## A locale representing Brazil.
> Example
Get the Brazilian locale.
Locale.brazil
brazil : Locale brazil : Locale
brazil = here.from_language_tag "pt-BR" brazil = here.from_language_tag "pt-BR"
## A locale representing Canada with language English. ## A locale representing Canada with language English.
> Example
Get the Canadian english locale.
Locale.canada_english
canada_english : Locale canada_english : Locale
canada_english = here.from_language_tag "en-CA" canada_english = here.from_language_tag "en-CA"
## A locale representing Canada with language French. ## A locale representing Canada with language French.
> Example
Get the Canadian french locale.
Locale.canada_french
canada_french : Locale canada_french : Locale
canada_french = here.from_language_tag "fr-CA" canada_french = here.from_language_tag "fr-CA"
## A locale representing the PRC. ## A locale representing the PRC.
> Example
Get the PRC locale.
Locale.china
china : Locale china : Locale
china = here.from_language_tag "zh-CN" china = here.from_language_tag "zh-CN"
## A locale representing France. ## A locale representing France.
> Example
Get the French locale.
Locale.france
france : Locale france : Locale
france = here.from_language_tag "fr-FR" france = here.from_language_tag "fr-FR"
## A locale representing Germany. ## A locale representing Germany.
> Example
Get the German locale.
Locale.germany
germany : Locale germany : Locale
germany = here.from_language_tag "de-DE" germany = here.from_language_tag "de-DE"
## A locale representing India with language Hindi. ## A locale representing India with language Hindi.
> Example
Get the Indian hindi locale.
Locale.india_hindi
india_hindi : Locale india_hindi : Locale
india_hindi = here.from_language_tag "hi-IN" india_hindi = here.from_language_tag "hi-IN"
## A locale representing India with language English. ## A locale representing India with language English.
> Example
Get the Indian english locale.
Locale.indian_english
india_english : Locale india_english : Locale
india_english = here.from_language_tag "en-IN" india_english = here.from_language_tag "en-IN"
## A locale representing Indonesia. ## A locale representing Indonesia.
> Example
Get the Indonesian locale.
Locale.indonesia
indonesia : Locale indonesia : Locale
indonesia = here.from_language_tag "id-ID" indonesia = here.from_language_tag "id-ID"
## A locale representing Italy. ## A locale representing Italy.
> Example
Get the Italian locale.
Locale.italy
italy : Locale italy : Locale
italy = here.from_language_tag "it-IT" italy = here.from_language_tag "it-IT"
## A locale representing Japan. ## A locale representing Japan.
> Example
Get the Japanese locale.
Locale.japan
japan : Locale japan : Locale
japan = here.from_language_tag "jp-JP" japan = here.from_language_tag "jp-JP"
## A locale representing Mexico. ## A locale representing Mexico.
> Example
Get the Mexican locale.
Locale.mexico
mexico : Locale mexico : Locale
mexico = here.from_language_tag "es-MX" mexico = here.from_language_tag "es-MX"
## A locale representing Nigeria. ## A locale representing Nigeria.
> Example
Get the Nigerian locale.
Locale.nigeria
nigeria : Locale nigeria : Locale
nigeria = here.from_language_tag "en-NG" nigeria = here.from_language_tag "en-NG"
## A locale representing paksitan with language Urdu. ## A locale representing paksitan with language Urdu.
> Example
Get the Pakistani urdu locale.
Locale.pakistan_urdu
pakistan_urdu : Locale pakistan_urdu : Locale
pakistan_urdu = here.from_language_tag "ur-PK" pakistan_urdu = here.from_language_tag "ur-PK"
## A locale representing paksitan with language English. ## A locale representing paksitan with language English.
> Example
Get the Pakistani english locale.
Locale.bangladesh
pakistan_english : Locale pakistan_english : Locale
pakistan_english = here.from_language_tag "en-PK" pakistan_english = here.from_language_tag "en-PK"
## A locale representing Russia. ## A locale representing Russia.
> Example
Get the Russian locale.
Locale.russia
russia : Locale russia : Locale
russia = here.from_language_tag "ru-RU" russia = here.from_language_tag "ru-RU"
## A locale representing South Korea. ## A locale representing South Korea.
> Example
Get the South Korean locale.
Locale.south_korea
south_korea : Locale south_korea : Locale
south_korea = here.from_language_tag "ko-KR" south_korea = here.from_language_tag "ko-KR"
## A locale representing the UK. ## A locale representing the UK.
> Example
Get the british locale.
Locale.uk
uk : Locale uk : Locale
uk = here.from_language_tag "en-GB" uk = here.from_language_tag "en-GB"
## A locale representing the United States. ## A locale representing the United States.
> Example
Get the US locale.
Locale.us
us : Locale us : Locale
us = here.from_language_tag "en-US" us = here.from_language_tag "en-US"
## Construct a new locale. ## Construct a new locale.
In addition to the basic constructors, it can take a vector containing locale Arguments:
properties. - language: The language tag for the locale.
- country: The country tag for the locale.
- variant: The variant for the locale.
> Example > Example
A locale representing en-GB.UTF-8. A locale representing en-GB.UTF-8.
@ -111,27 +193,28 @@ new language country=Nothing variant=Nothing =
## Returns the locale specified by the provided IETF BCP47 language tag string. ## Returns the locale specified by the provided IETF BCP47 language tag string.
If the specified language tag contains any ill-formed subtags, the first such ? Language Tag Syntax
subtag and all following subtags are ignored. If the specified language tag contains any ill-formed subtags, the first
such subtag and all following subtags are ignored.
The following conversions are performed: The following conversions are performed:
- The language code "und" is mapped to language "". - The language code "und" is mapped to language "".
- The language codes "he", "yi", and "id" are mapped to "iw", "ji", and "in" - The language codes "he", "yi", and "id" are mapped to "iw", "ji", and
respectively. "in" respectively.
- The portion of a private use subtag prefixed by "lvariant", if any, is - The portion of a private use subtag prefixed by "lvariant", if any, is
removed and appended to the variant field in the result locale (without removed and appended to the variant field in the result locale (without
case normalization). case normalization).
- When the languageTag argument contains an extlang subtag, the first such - When the languageTag argument contains an extlang subtag, the first such
subtag is used as the language, and the primary language subtag and other subtag is used as the language, and the primary language subtag and other
extlang subtags are ignored. extlang subtags are ignored.
- Case is normalized except for variant tags, which are left unchanged. - Case is normalized except for variant tags, which are left unchanged.
Language is normalized to lower case, script to title case, country to Language is normalized to lower case, script to title case, country to
upper case, and extensions to lower case. upper case, and extensions to lower case.
- If, after processing, the locale would exactly match either ja_JP_JP or - If, after processing, the locale would exactly match either ja_JP_JP or
th_TH_TH with no extensions, the appropriate extensions are added. th_TH_TH with no extensions, the appropriate extensions are added.
This implements the 'Language-Tag' production of BCP47, and so supports This implements the 'Language-Tag' production of BCP47, and so supports
grandfathered (regular and irregular) as well as private use language tags. grandfathered (regular and irregular) as well as private use language tags.
> Example > Example
Creating the locale en_US. Creating the locale en_US.
@ -148,21 +231,38 @@ from_language_tag tag =
- A country code, which is optional. - A country code, which is optional.
- A variant, which is optional. - A variant, which is optional.
type Locale type Locale
## A type representing a locale.
Arguments:
- java_locale: The Java locale representation used internally.
type Locale java_locale type Locale java_locale
## Gets the language from the locale. ## Gets the language from the locale.
> Example
Get the language tag from the default locale.
Locale.default.language
language : Text | Nothing language : Text | Nothing
language = language =
lang = this.java_locale.getLanguage lang = this.java_locale.getLanguage
if lang.is_empty then Nothing else lang if lang.is_empty then Nothing else lang
## Gets the country from the locale. ## Gets the country from the locale.
> Example
Get the country tag from the default locale.
Locale.default.country
country : Text | Nothing country : Text | Nothing
country = country =
place = this.java_locale.getCountry place = this.java_locale.getCountry
if place.is_empty then Nothing else place if place.is_empty then Nothing else place
## Gets the country from the locale. ## Gets the variant from the locale.
> Example
Get the variant tag from the default locale.
Locale.default.variant
variant : Text | Nothing variant : Text | Nothing
variant = variant =
var = this.java_locale.getVariant var = this.java_locale.getVariant
@ -170,6 +270,10 @@ type Locale
## Gets a representation of the language in the locale that can be shown to ## Gets a representation of the language in the locale that can be shown to
the user. the user.
> Example
Get the display language tag from the default locale.
Locale.default.display_language
display_language : Text | Nothing display_language : Text | Nothing
display_language = display_language =
disp = this.java_locale.getDisplayLanguage disp = this.java_locale.getDisplayLanguage
@ -177,6 +281,10 @@ type Locale
## Gets a representation of the country in the locale that can be shown to ## Gets a representation of the country in the locale that can be shown to
the user. the user.
> Example
Get the display country tag from the default locale.
Locale.default.display_country
display_country : Text | Nothing display_country : Text | Nothing
display_country = display_country =
disp = this.java_locale.getDisplayCountry disp = this.java_locale.getDisplayCountry
@ -184,16 +292,28 @@ type Locale
## Gets a representation of the variant in the locale that can be shown to ## Gets a representation of the variant in the locale that can be shown to
the user. the user.
> Example
Get the display variant tag from the default locale.
Locale.default.display_variant
display_variant : Text | Nothing display_variant : Text | Nothing
display_variant = display_variant =
disp = this.java_locale.getDisplayVariant disp = this.java_locale.getDisplayVariant
if disp.is_empty then Nothing else disp if disp.is_empty then Nothing else disp
## Converts the locale to text. ## Converts the locale to text.
> Example
Convert the default locale to text.
Locale.default.to_text
to_text : Text | Nothing to_text : Text | Nothing
to_text = this.java_locale.toLanguageTag to_text = this.java_locale.toLanguageTag
## A Locale to Json conversion ## A Locale to Json conversion
> Example
Convert the default locale to JSON.
Locale.default.to_json
to_json : Json.Object to_json : Json.Object
to_json = to_json =
b = Vector.new_builder b = Vector.new_builder
@ -204,6 +324,11 @@ type Locale
Json.from_pairs b.to_vector Json.from_pairs b.to_vector
## PRIVATE ## PRIVATE
Convert a java locale to an Enso locale.
Arguments:
- java: The java locale value.
from_java : JavaLocale -> Locale from_java : JavaLocale -> Locale
from_java java = Locale java from_java java = Locale java

View File

@ -2,19 +2,39 @@ from Standard.Base import all
import Standard.Base.Data.Map.Internal import Standard.Base.Data.Map.Internal
## An error for getting a missing value from a map. ## UNSTABLE
An error for getting a missing value from a map.
Arguments:
- key: The key that was asked for.
type No_Value_For_Key key type No_Value_For_Key key
## Returns an empty map. ## Returns an empty map.
> Example
Create an empty map.
Map.empty
empty : Map empty : Map
empty = Tip empty = Tip
## Returns a single-element map with the given key and value present. ## Returns a single-element map with the given key and value present.
Arguments:
- key: The key to update in the map.
- value: The value to store against 'key' in the map.
> Example
Create a single element map storing the key 1 and the value 2.
Map.singleton 1 2
singleton : Any -> Any -> Map singleton : Any -> Any -> Map
singleton key value = Bin 1 key value Tip Tip singleton key value = Bin 1 key value Tip Tip
## Builds a map from a vector of key-value pairs. ## Builds a map from a vector of key-value pairs.
Arguments:
- vec: A vector of key-value pairs.
> Example > Example
Building a map containing two key-value pairs. Building a map containing two key-value pairs.
Map.from_vector [[1, 2], [3, 4]] Map.from_vector [[1, 2], [3, 4]]
@ -24,27 +44,59 @@ from_vector vec = vec.fold Map.empty (m -> el -> m.insert (el.at 0) (el.at 1))
## A key-value store. This type assumes all keys are pairwise comparable, ## A key-value store. This type assumes all keys are pairwise comparable,
using the `<`, `>` and `==` operators. using the `<`, `>` and `==` operators.
type Map type Map
## PRIVATE
A key-value store. This type assumes all keys are pairwise comparable,
using the `<`, `>` and `==` operators.
type Tip type Tip
## PRIVATE
A key-value store. This type assumes all keys are pairwise comparable,
using the `<`, `>` and `==` operators.
Arguments:
- s: The size of the tree at this node.
- key: The key stored at this node.
- value: The value stored at this node.
- left: The left subtree.
- right: The right subtree.
type Bin s key value left right type Bin s key value left right
## Checks if the map is empty. ## Checks if the map is empty.
> Example
Check if a singleton map is empty.
Map.singleton 1 2 . is_empty
is_empty : Boolean is_empty : Boolean
is_empty = case this of is_empty = case this of
Bin _ _ _ _ _ -> False Bin _ _ _ _ _ -> False
Tip -> True Tip -> True
## Checks if the map is not empty. ## Checks if the map is not empty.
> Example
Check if a singleton map is not empty.
Map.singleton 1 2 . not_empty
not_empty : Boolean not_empty : Boolean
not_empty = this.is_empty.not not_empty = this.is_empty.not
## Returns the number of entries in this map. ## Returns the number of entries in this map.
> Example
Get the size of a singleton map.
Map.singleton 1 2 . size
size : Integer size : Integer
size = case this of size = case this of
Bin s _ _ _ _ -> s Bin s _ _ _ _ -> s
Tip -> 0 Tip -> 0
## Converts the map into a vector of `[key, value]` pairs. ## Converts the map into a vector of `[key, value]` pairs.
The returned vector is sorted in the increasing order of keys. The returned vector is sorted in the increasing order of keys.
> Example
Convert a singleton map to a vector.
Map.singleton 1 2 . to_vector
to_vector : Vector.Vector to_vector : Vector.Vector
to_vector = to_vector =
builder = Vector.new_builder builder = Vector.new_builder
@ -60,23 +112,49 @@ type Map
result result
## Returns a text representation of this map. ## Returns a text representation of this map.
> Example
Convert an empty map to text.
Map.empty.to_text
to_text : Text to_text : Text
to_text = this.to_vector.to_text to_text = this.to_vector.to_text
## Checks if this map is equal to another map. ## Checks if this map is equal to another map.
Arguments:
- that: The map to compare `this` to.
Maps are equal when they contained the same keys and the values Maps are equal when they contained the same keys and the values
associated with each key are pairwise equal. associated with each key are pairwise equal.
> Example
Checking two singleton maps for equality.
(Map.singleton 1 2) == (Map.singleton 2 3)
== : Map -> Boolean == : Map -> Boolean
== that = this.to_vector == that.to_vector == that = this.to_vector == that.to_vector
## Inserts a key-value mapping into this map. If `key` is already present, ## Inserts a key-value mapping into this map, overriding any existing
it will be overriden with the new `value`. instance of `key` with the new `value`.
Arguments:
- key: The key to insert the value for.
- value: The value to associate with `key`.
> Example
Insert the value 3 into a map for the key 1.
Map.empty.insert 1 3
insert : Any -> Any -> Map insert : Any -> Any -> Map
insert key value = Internal.insert this key value insert key value = Internal.insert this key value
## Gets the value associated with `key` in this map, or returns a ## Gets the value associated with `key` in this map, or throws a `Nothing`,
`Nothing`, if `key` is not present. if `key` is not present.
Arguments:
- key: The key to look up in the map.
> Example
Get the value for the key 2 in a map.
Map.empty.get 2
get : Any -> Any ! Nothing get : Any -> Any ! Nothing
get key = get key =
go map = case map of go map = case map of
@ -89,12 +167,25 @@ type Map
## Gets the value associated with `key` in this map, or returns `other` if ## Gets the value associated with `key` in this map, or returns `other` if
it isn't present. it isn't present.
Arguments:
- key: The key to look up in the map.
- other: The value to use if the key isn't present.
> Example
Get the value for the key 2 in a map or instead return 10 if it isn't
present.
Map.empty.get_or_else 2 10
get_or_else : Any -> Any -> Any get_or_else : Any -> Any -> Any
get_or_else key ~other = get_or_else key ~other =
this.get key . catch (_ -> other) this.get key . catch (_ -> other)
## Transforms the map's keys and values to create a new map. ## Transforms the map's keys and values to create a new map.
Arguments:
- function: The function used to transform the map, taking a key and a
value and returning a pair of `[key, value]`.
> Example > Example
Turn all keys into `Text` and double the values for a map `m`. Turn all keys into `Text` and double the values for a map `m`.
m.transform (k -> v -> [k.to_text, v*2]) m.transform (k -> v -> [k.to_text, v*2])
@ -106,6 +197,10 @@ type Map
## Maps a function over each value in this map. ## Maps a function over each value in this map.
Arguments:
- function: The function to apply to each value in the map, taking a
value and returning a value.
> Example > Example
Turn all values into `Text` for a map `m`. Turn all values into `Text` for a map `m`.
m.map (v -> v.to_text) m.map (v -> v.to_text)
@ -117,6 +212,10 @@ type Map
## Maps a function over each key-value pair in the map, transforming the ## Maps a function over each key-value pair in the map, transforming the
value. value.
Arguments:
- function: The function to apply to each key and value in the map,
taking a key and a value and returning a value.
> Example > Example
Adding the key to the value in a map `m`. Adding the key to the value in a map `m`.
m.map_with_key (k -> v -> k + v) m.map_with_key (k -> v -> k + v)
@ -130,6 +229,10 @@ type Map
## Maps a function over each key in this map. ## Maps a function over each key in this map.
Arguments:
- function: The function to apply to each key in the map, taking a key
and returning a key.
> Example > Example
Doubling all keys in the map `m`. Doubling all keys in the map `m`.
m.map_keys (k -> k*2) m.map_keys (k -> k*2)
@ -140,6 +243,10 @@ type Map
## Applies a function to each value in the map. ## Applies a function to each value in the map.
Arguments:
- function: The function to apply to each value in the map, taking a
value and returning anything.
This method does not return the results, so is only useful for performing This method does not return the results, so is only useful for performing
computations with side-effects. computations with side-effects.
@ -153,6 +260,10 @@ type Map
## Applies a function to each key-value pair in the map. ## Applies a function to each key-value pair in the map.
Arguments:
- function: The function to apply to each key-value pair in the map,
taking a key and a value and returning anything.
This method does not return the results, so is only useful for performing This method does not return the results, so is only useful for performing
computations with side-effects. computations with side-effects.
@ -172,6 +283,10 @@ type Map
## Combines the values in the map. ## Combines the values in the map.
Arguments:
- init: The initial value for the fold.
- function: A binary function to apply to pairs of values in the map.
> Example > Example
Summing all of the values in the map `m`. Summing all of the values in the map `m`.
m.fold 0 (+) m.fold 0 (+)
@ -187,6 +302,11 @@ type Map
## Combines the key-value pairs in the map. ## Combines the key-value pairs in the map.
Arguments:
- init: The initial value for the fold.
- function: A function taking the left value, the current key, and the
current value, and combining them to yield a single value.
> Example > Example
Sum the keys and values in the map `m`. Sum the keys and values in the map `m`.
m.fold_with_key 0 (l -> k -> v -> l + k + v) m.fold_with_key 0 (l -> k -> v -> l + k + v)

View File

@ -4,14 +4,32 @@ from Standard.Base.Data.Map import all
## PRIVATE ## PRIVATE
Helper used in the insert operation. A helper used in the insert operation to insert into the left subtree.
Arguments:
- key: The key to insert.
- value: The value to insert.
- k: The previous top key of the left subtree.
- v: The previous top value of the left subtree.
- l: The left subtree.
- r: The right subtree.
insert_l : Any -> Any -> Any -> Any -> Tree -> Tree -> Tree
insert_l key value k v l r = insert_l key value k v l r =
new_left = here.insert l key value new_left = here.insert l key value
here.balance_left k v new_left r here.balance_left k v new_left r
## PRIVATE ## PRIVATE
Helper used in the insert operation. A helper used in the insert operation to insert into the right subtree.
Arguments:
- key: The key to insert.
- value: The value to insert.
- k: The previous top key of the right subtree.
- v: The previous top value of the right subtree.
- l: The left subtree.
- r: The right subtree.
insert_r : Any -> Any -> Any -> Any -> Tree -> Tree -> Tree
insert_r key value k v l r = insert_r key value k v l r =
new_right = here.insert r key value new_right = here.insert r key value
here.balance_right k v l new_right here.balance_right k v l new_right
@ -20,10 +38,15 @@ insert_r key value k v l r =
Helper for inserting a new key-value pair into a map. Helper for inserting a new key-value pair into a map.
Arguments:
- map: The map into which the insertion is performed.
- key: The key for which to insert the value into the map.
- value: The value to insert into the map at the given key.
The algorithm used here is based on the paper "Implementing Sets Efficiently The algorithm used here is based on the paper "Implementing Sets Efficiently
in a Functional Language" by Stephen Adams. in a Functional Language" by Stephen Adams. The implementation is based on
Implementation is based on Haskell's `Data.Map.Strict` implemented in the Haskell's `Data.Map.Strict` as implemented in the `containers` package.
`containers` package. insert : Map -> Any -> Any -> Map
insert map key value = case map of insert map key value = case map of
Bin s k v l r -> Bin s k v l r ->
if key > k then @Tail_Call here.insert_r key value k v l r else if key > k then @Tail_Call here.insert_r key value k v l r else
@ -34,6 +57,13 @@ insert map key value = case map of
## PRIVATE ## PRIVATE
Rebalances the map after the left subtree grows. Rebalances the map after the left subtree grows.
Arguments:
- k: The old top key of the left subtree.
- x: The old top value of the left subtree.
- l: The left subtree.
- r: The right subtree.
balance_left : Any -> Any -> Tree -> Tree -> Tree
balance_left k x l r = case r of balance_left k x l r = case r of
Bin rs _ _ _ _ -> case l of Bin rs _ _ _ _ -> case l of
Bin ls lk lx ll lr -> Bin ls lk lx ll lr ->
@ -62,6 +92,12 @@ balance_left k x l r = case r of
## PRIVATE ## PRIVATE
Rebalances the map after the right subtree grows. Rebalances the map after the right subtree grows.
Arguments:
- k: The old top key of the right subtree.
- x: The old top value of the right subtree.
- l: The left subtree.
- r: The right subtree.
balance_right k x l r = case l of balance_right k x l r = case l of
Bin ls _ _ _ _ -> case r of Bin ls _ _ _ _ -> case r of
Bin rs rk rx rl rr -> Bin rs rk rx rl rr ->
@ -109,6 +145,10 @@ delta = 3
## PRIVATE ## PRIVATE
Gets the size of a map. Gets the size of a map.
Arguments:
- m: The map to get the size of.
size: Map -> Integer
size m = case m of size m = case m of
Bin s _ _ _ _ -> s Bin s _ _ _ _ -> s
_ -> 0 _ -> 0

View File

@ -7,6 +7,9 @@ type Maybe
Nothing Nothing
## A value. ## A value.
Arguments:
- value: The contained value in the maybe.
type Some value type Some value
## Applies the provided function to the contained value if it exists, ## Applies the provided function to the contained value if it exists,

View File

@ -4,6 +4,10 @@ from Standard.Base.Data.Noise.Generator import all
## Generate noise based on the input number. ## Generate noise based on the input number.
Arguments:
- interval: An interval in which the noise should be generated.
- gen: The generator to use for generating noise.
The output of the noise generator will depend on the input and the range over The output of the noise generator will depend on the input and the range over
which the noise is being generated. which the noise is being generated.

View File

@ -6,16 +6,24 @@ import Standard.Base.Error.Extensions
polyglot java import java.lang.Long polyglot java import java.lang.Long
polyglot java import java.util.Random polyglot java import java.util.Random
## The interface for the noise generator abstraction. ## PRIVATE
The interface for the noise generator abstraction.
To be a valid generator, it must provide the `step` method as described To be a valid generator, it must provide the `step` method as described
below. below.
type Generator type Generator
## PRIVATE
The basic generator type.
type Generator type Generator
## Step the generator to produce the next value.. ## PRIVATE
The parameters are as follows: Step the generator to produce the next value..
Arguments:
- The input number, which is intended for use as a seed. - The input number, which is intended for use as a seed.
- A range for output values, which should range over the chosen output - A range for output values, which should range over the chosen output
type. type.
@ -31,9 +39,23 @@ type Generator
It produces what is commonly termed "white" noise, where any value in the It produces what is commonly termed "white" noise, where any value in the
range has an equal chance of occurring. range has an equal chance of occurring.
type Deterministic_Random type Deterministic_Random
## A determinstic random noise generator that performs a peterbation of the
input
It produices what is commonly termed as "white" noise, where any value in
the range has an equal chance of occurring.
type Deterministic_Random type Deterministic_Random
## Step the generator to produce the next value. ## Step the generator to produce the next value.
Arguments:
- input: The seed number to perturb.
- interval: The interval over which the noise should be generated.
> Example
Step the generator with the input 1 and range 0 to 1
Deterministic_Random.step 1 (Interval.inclusive 0 1)
step : Number -> Interval -> Number step : Number -> Interval -> Number
step input interval = step input interval =
max_long = Long.MAX_VALUE max_long = Long.MAX_VALUE

View File

@ -7,99 +7,209 @@ polyglot java import java.lang.String
## Computes the inverse of the sine function ## Computes the inverse of the sine function
Selects a value in the -pi/2 through pi/2 range. Selects a value in the -pi/2 through pi/2 range.
> Example
Calculate the inverse sine of 1.
1.asin
Number.asin : Decimal Number.asin : Decimal
Number.asin = Math.asin this.to_decimal Number.asin = Math.asin this.to_decimal
## Computes the inverse of the cosine function. ## Computes the inverse of the cosine function.
Selects a value in the -pi/2 through pi/2 range. Selects a value in the -pi/2 through pi/2 range.
> Example
Calculate the inverse cosine of 1.
1.acos
Number.acos : Decimal Number.acos : Decimal
Number.acos = Math.acos this.to_decimal Number.acos = Math.acos this.to_decimal
## Computes the inverse of the tangent function. ## Computes the inverse of the tangent function.
Selects a value in the -pi/2 through pi/2 range. Selects a value in the -pi/2 through pi/2 range.
> Example
Calculate the inverse tangent of 1.
1.acos
Number.atan : Decimal Number.atan : Decimal
Number.atan = Math.atan this.to_decimal Number.atan = Math.atan this.to_decimal
## Computes the argument (angle) in the conversion from cartesian ## Computes the argument (angle) in the conversion from cartesian
to polar coordinates. to polar coordinates, taking `this` as the x coordinate.
Arguments:
- y: The y coordinate.
The returned angle is in the -pi through pi range. The returned angle is in the -pi through pi range.
> Example
Convert the coordinates 1 and 2 to polar form.
1.atan_2 2
Number.atan_2 : Number -> Decimal Number.atan_2 : Number -> Decimal
Number.atan_2 y = Math.atan2 this.to_decimal y.to_decimal Number.atan_2 y = Math.atan2 this.to_decimal y.to_decimal
## Computes the sine function. ## Computes the sine function.
> Example
Calculate the sine of 2.
2.sin
Number.sin : Decimal Number.sin : Decimal
Number.sin = Math.sin this.to_decimal Number.sin = Math.sin this.to_decimal
## Computes the cosine function. ## Computes the cosine function.
> Example
Calculate the cosine of 2.
2.cos
Number.cos : Decimal Number.cos : Decimal
Number.cos = Math.cos this.to_decimal Number.cos = Math.cos this.to_decimal
## Computes the tangent function. ## Computes the tangent function.
> Example
Calculate the tangent of 2.
2.tan
Number.tan : Decimal Number.tan : Decimal
Number.tan = Math.tan this.to_decimal Number.tan = Math.tan this.to_decimal
## Computes the hyperbolic sine function. ## Computes the hyperbolic sine function.
> Example
Calculate the hyperbolic sine of 1.
1.sinh
Number.sinh : Decimal Number.sinh : Decimal
Number.sinh = Math.sinh this.to_decimal Number.sinh = Math.sinh this.to_decimal
## Computes the hyperbolic cosine function. ## Computes the hyperbolic cosine function.
> Example
Calcualte the hyperbolic cosine of 1.
1.cosh
Number.cosh : Decimal Number.cosh : Decimal
Number.cosh = Math.cosh this.to_decimal Number.cosh = Math.cosh this.to_decimal
## Computes the hyperbolic tangent function. ## Computes the hyperbolic tangent function.
> Example
Calculate the hyperbolic tangent of 1.
1.tanh
Number.tanh : Decimal Number.tanh : Decimal
Number.tanh = Math.tanh this.to_decimal Number.tanh = Math.tanh this.to_decimal
## Computes the exponential function. ## Computes the exponential function, raising Euler's number `r` to the power of
`this`.
> Example
Calculate e to the 4th power.
4.exp
Number.exp : Decimal Number.exp : Decimal
Number.exp = Math.exp this.to_decimal Number.exp = Math.exp this.to_decimal
## Computes the natural logarithm function. ## Computes the natural logarithm function.
> Example
Calculate the natural logarithm of 2.
2.ln
Number.ln : Decimal Number.ln : Decimal
Number.ln = Math.log this.to_decimal Number.ln = Math.log this.to_decimal
## Computes the square root of `this`. ## Computes the square root of `this`.
> Example
Calculate the square root of 8.
8.sqrt
Number.sqrt : Decimal Number.sqrt : Decimal
Number.sqrt = Math.sqrt this.to_decimal Number.sqrt = Math.sqrt this.to_decimal
## Computes the `base`-log of `this`. ## Computes the `base`-log of `this`.
Arguments:
- base: The base for the logarithm.
> Example
Calculate log 2 of 4.
4.log 2
Number.log : Number -> Decimal Number.log : Number -> Decimal
Number.log base = this.ln / base.ln Number.log base = this.ln / base.ln
# TODO this should expose a more-user friendly API in the future. ## UNSTABLE The API will become more user-friendly in future.
## Converts a decimal value to a string, using the Java string formatting
Converts a decimal value to a string, using the Java string formatting
syntax. syntax.
Arguments:
- fmt: The java-style formatting specifier.
> Example
Convert the value 5 to a string.
5.fmt "%d"
Decimal.format : Text -> Text Decimal.format : Text -> Text
Decimal.format fmt = String.format fmt this Decimal.format fmt = String.format fmt this
## Creates a new right-exclusive range of integers from `this` to `n`. ## Creates a new right-exclusive range of integers from `this` to `n`.
Arguments:
- n: The end of the range.
> Example
Create a range from 1 to 5.
1.up_to 5
Integer.up_to : Integer -> Range Integer.up_to : Integer -> Range
Integer.up_to n = Range this n Integer.up_to n = Range this n
## Checks equality of numbers, using an `epsilon` value. ## Checks equality of numbers, using an `epsilon` value.
Returns `True` when `this` and `that` are at most `epsilon` apart. Arguments:
- that: The number to check equality against.
- epsilon: The value by which `this` and `that` can be separated by before
counting as not equal.
> Example
Check if 1 is equal to 1.0000001 within 0.001.
1.equals 1.0000001 epsilon=0.001
Number.equals : Number -> Number -> Boolean Number.equals : Number -> Number -> Boolean
Number.equals that epsilon=0.0 = (this - that).abs <= epsilon Number.equals that epsilon=0.0 = (this - that).abs <= epsilon
## Returns the smaller value of `this` and `that`. ## Returns the smaller value of `this` and `that`.
Arguments:
- that: The number to compare `this` against.
> Example
Find the minimum of 2 and 5.
2.min 5
Number.min : Number -> Number Number.min : Number -> Number
Number.min that = if this < that then this else that Number.min that = if this < that then this else that
## Returns the larger value of `this` and `that`. ## Returns the larger value of `this` and `that`.
Arguments:
- that: The number to compare `this` against.
> Example
Find the maximum of 2 and 5.
2.max 5
Number.max : Number -> Number Number.max : Number -> Number
Number.max that = if this > that then this else that Number.max that = if this > that then this else that
## Number to JSON conversion. ## Number to JSON conversion.
> Example
Convert the number 8 to JSON.
8.to_json
Number.to_json : Json.Number Number.to_json : Json.Number
Number.to_json = Json.Number this Number.to_json = Json.Number this
## Parses a textual representation of a decimal into a decimal number. ## Parses a textual representation of a decimal into a decimal number, returning
Returns `Nothing` if the text does not represent a valid decimal. `Nothing` if the text does not represent a valid decimal.
Decimal.parse : Text -> Decimal | Nothing
Decimal.parse text = Arguments:
Panic.recover (Double.parseDouble text) . catch (_ -> Nothing) - text: The text to parse into a decimal.
> Example
Parse the text "7.6" into a decimal number.
Decimal.parse 7.6
Decimal.parse : Text -> Decimal ! Nothing
Decimal.parse text =
Panic.recover (Double.parseDouble text) . catch (_ -> Error.throw Nothing)

View File

@ -12,14 +12,15 @@ from Builtins export Less, Equal, Greater
The result should be returned in terms of how `this` orders in comparison to The result should be returned in terms of how `this` orders in comparison to
`that`. So, if `this` is greater than `that`, you should return `Greater.` `that`. So, if `this` is greater than `that`, you should return `Greater.`
type Ordering type Ordering
## An ordering where a compared value is less than another.
Less Less
## An ordering where a compared value is equal to another.
Equal Equal
## An ordering where a compared value is greater than another.
Greater Greater
## Converts the ordering to the signed notion of ordering based on integers. ## Converts the ordering to the signed notion of ordering based on integers.
> Example
Converting equal ordering to a signed number.
Ordering.Equal.to_sign
to_sign : Integer to_sign : Integer
to_sign = case this of to_sign = case this of
Less -> -1 Less -> -1

View File

@ -2,8 +2,10 @@ from Standard.Base import all
## A descriptor for a sort ordering. ## A descriptor for a sort ordering.
type Sort_Order type Sort_Order
## Elements should be sorted in ascending order. ## Elements should be sorted in ascending order.
type Ascending type Ascending
## Elements should be sorted in descending order. ## Elements should be sorted in descending order.
type Descending type Descending

View File

@ -2,4 +2,12 @@ from Standard.Base import all
## A pair of elements. ## A pair of elements.
type Pair type Pair
## UNSTABLE
A simple pair of elements.
Arguments:
- first: The first element.
- second: The second element.
type Pair first second type Pair first second

View File

@ -2,6 +2,13 @@ from Standard.Base import all
## Represents a right-exclusive range of integer values. ## Represents a right-exclusive range of integer values.
type Range type Range
## UNSTABLE
A representation of a right-exclusive range of integer values.
Arguments:
- start: The left boundary of the range. Its value is included.
- end: The right boundary of the range. Its value is excluded.
type Range start end type Range start end
## Get the number of elements in the range. ## Get the number of elements in the range.
@ -30,6 +37,9 @@ type Range
## Applies a function for each element in the range. ## Applies a function for each element in the range.
Arguments:
- function: The function to apply to each integer in the range.
> Example > Example
To print all the numbers from 1 to 100 use: To print all the numbers from 1 to 100 use:
1.up_to 101 . each IO.println 1.up_to 101 . each IO.println
@ -44,6 +54,11 @@ type Range
## Combines all the elements of the range, by iteratively applying the ## Combines all the elements of the range, by iteratively applying the
passed function with next elements of the range. passed function with next elements of the range.
Arguments:
- init: The initial integral value for the fold.
- function: A binary function taking an item and a number, and returning
an item.
In general, the result of In general, the result of
Range start end . fold init f Range start end . fold init f
is the same as is the same as
@ -53,18 +68,20 @@ type Range
In the following example, we'll compute the sum of all elements of a In the following example, we'll compute the sum of all elements of a
range: range:
Range 0 100 . fold 0 (+) Range 0 100 . fold 0 (+)
fold : Any -> (Number -> Any) -> Any fold : Any -> (Any -> Number -> Any) -> Any
fold initial function = fold init function =
it acc start end = if start == end then acc else it acc start end = if start == end then acc else
new_acc = function acc start new_acc = function acc start
@Tail_Call it new_acc start+1 end @Tail_Call it new_acc start+1 end
res = it initial this.start this.end res = it init this.start this.end
res res
## Checks whether `predicate` is satisfied for all numbers in this range. ## Checks whether `predicate` is satisfied for all numbers in this range.
A predicate is a function that takes an element in the range and returns Arguments:
a boolean. - predicate: A function that takes a list element and returns a boolean
value that says whether that value satisfies the conditions of the
function.
> Example > Example
Checking that all numbers in the range are greater than 5. Checking that all numbers in the range are greater than 5.
@ -79,8 +96,10 @@ type Range
## Checks whether `predicate` is satisfied for any number in this range. ## Checks whether `predicate` is satisfied for any number in this range.
A predicate is a function that takes an element in the range and returns Arguments:
a boolean. - predicate: A function that takes a list element and returns a boolean
value that says whether that value satisfies the conditions of the
function.
> Example > Example
Checking that at least one number in the range is greater than 10. Checking that at least one number in the range is greater than 10.
@ -94,8 +113,10 @@ type Range
## Checks whether `predicate` is satisfied for any number in this range. ## Checks whether `predicate` is satisfied for any number in this range.
A predicate is a function that takes an element in the range and returns Arguments:
a boolean. - predicate: A function that takes a list element and returns a boolean
value that says whether that value satisfies the conditions of the
function.
> Example > Example
Checking that at least one number in the range is greater than 10. Checking that at least one number in the range is greater than 10.

View File

@ -13,11 +13,14 @@ polyglot java import org.enso.base.Text_Utils
## Computes the number of characters in the text. ## Computes the number of characters in the text.
A character is defined as an Extended Grapheme Cluster, see ! What is a Character?
Unicode Standard Annex 29. A character is defined as an Extended Grapheme Cluster, see Unicode
Standard Annex 29. This is the smallest unit that still has semantic
meaning in most text-processing applications.
This is the smallest unit that still has semantic meaning in most > Example
text-processing applications. Getting the length of the string "건반(Korean)".
"건반(Korean)".length
Text.length : Integer Text.length : Integer
Text.length = Text.length =
iterator = BreakIterator.getCharacterInstance iterator = BreakIterator.getCharacterInstance
@ -30,13 +33,19 @@ Text.length =
@Tail_Call count counter next_nxt @Tail_Call count counter next_nxt
count 0 nxt count 0 nxt
## Applies `function` to each character in `this`. ## Applies the provided `function` to each character in `this`.
A character is defined as an Extended Grapheme Cluster, see Arguments:
Unicode Standard Annex 29. - function: The operation to apply to each character in the text.
This is the smallest unit that still has semantic meaning in most ! What is a Character?
text-processing applications. A character is defined as an Extended Grapheme Cluster, see Unicode
Standard Annex 29. This is the smallest unit that still has semantic
meaning in most text-processing applications.
> Example
Print each character in the text "aaa".
"aaa".each IO.println
Text.each : (Text -> Any) -> Nothing Text.each : (Text -> Any) -> Nothing
Text.each function = Text.each function =
iterator = BreakIterator.getCharacterInstance iterator = BreakIterator.getCharacterInstance
@ -54,11 +63,14 @@ Text.each function =
## Returns a vector containing all characters in the given text. ## Returns a vector containing all characters in the given text.
A character is defined as an Extended Grapheme Cluster, see ! What is a Character?
Unicode Standard Annex 29. A character is defined as an Extended Grapheme Cluster, see Unicode
Standard Annex 29. This is the smallest unit that still has semantic
meaning in most text-processing applications.
This is the smallest unit that still has semantic meaning in most > Example
text-processing applications. Get the individual characters in the text "건반(Korean)".
"건반(Korean)".characters
Text.characters : Vector.Vector Text.characters : Vector.Vector
Text.characters = Text.characters =
bldr = Vector.new_builder bldr = Vector.new_builder
@ -68,12 +80,16 @@ Text.characters =
## Takes a separator string and returns a vector resulting from splitting ## Takes a separator string and returns a vector resulting from splitting
`this` on each occurence of `separator`. `this` on each occurence of `separator`.
Arguments:
- separator: The separator to use to split the text.
> Example > Example
In the following example, we'll split the text into a vector of Split the comma-separated text into a vector of items.
comma-separated items:
"ham,eggs,cheese,tomatoes".split "," "ham,eggs,cheese,tomatoes".split ","
The code above returns:
["ham", "eggs", "cheese", "tomatoes"] > Example
Split the string on whitespace into a vector of items.
"ham eggs cheese tomatoes".split Split_Kind.Whitespace
Text.split : Split_Kind -> Vector.Vector Text.split : Split_Kind -> Vector.Vector
Text.split (separator = Split_Kind.Whitespace) = Text.split (separator = Split_Kind.Whitespace) =
result = case separator of result = case separator of
@ -85,12 +101,15 @@ Text.split (separator = Split_Kind.Whitespace) =
## Returns a vector containing all words in the given text. ## Returns a vector containing all words in the given text.
A word is defined based on the definition of Word Boundaries in the Unicode Arguments:
Standard Annex 29, supplemented by language-specific dictionaries for - keep_whitespace: Whether or not the whitespace around the words should be
Chinese, Japanese, Thai, and Khmer. preserved. If set to `True`, the whitespace will be included as a "word" in
the output.
By default, the function doesn't include the whitespace between words, but ! What is a Word?
this can be enabled. A word is defined based on the definition of Word Boundaries in the Unicode
Standard Annex 29, supplemented by language-specific dictionaries for
Chinese, Japanese, Thai, and Khmer.
> Example > Example
Getting the words in the sentence "I have not one, but two cats." Getting the words in the sentence "I have not one, but two cats."
@ -119,44 +138,53 @@ Text.words keep_whitespace=False =
## Checks whether `this` is equal to `that`. ## Checks whether `this` is equal to `that`.
The definition of equality includes Unicode canonicalization. I.e. two texts Arguments:
are equal if they are identical after canonical decomposition. This ensures - that: The text to compare `this` for equality with.
that different ways of expressing the same character in the underlying
binary representation are considered equal. ! Unicode Equality
The definition of equality includes Unicode canonicalization. I.e. two
texts are equal if they are identical after canonical decomposition. This
ensures that different ways of expressing the same character in the
underlying binary representation are considered equal.
> Example > Example
The string 'é' (i.e. the character U+00E9, LATIN SMALL LETTER E WITH The string 'é' (i.e. the character U+00E9, LATIN SMALL LETTER E WITH ACUTE)
ACUTE) is canonically the same as the string 'e\u0301' (i.e. the letter is canonically the same as the string 'e\u0301' (i.e. the letter `e`
`e` followed by U+0301, COMBINING ACUTE ACCENT). Therefore: followed by U+0301, COMBINING ACUTE ACCENT). Therefore:
('é' == 'e\u0301') == True ('é' == 'e\u0301') == True
Text.== : Any -> Boolean Text.== : Any -> Boolean
Text.== that = if Meta.is_same_object this Text then Meta.is_same_object that Text else Text.== that = if Meta.is_same_object this Text then Meta.is_same_object that Text else
Text_Utils.equals this that Text_Utils.equals this that
## Checks whether `this` is equal to `that`, ignoring case considerations. ## Checks whether `this` is equal to `that`, ignoring the case of the texts.
Arguments:
- that: The text to compare `this` for case-insensitive equality with.
Two texts are considered equal ignoring case if they are of the same length Two texts are considered equal ignoring case if they are of the same length
and corresponding characters are equal ignoring case. and corresponding characters are equal ignoring case.
The definition of equality includes Unicode canonicalization. I.e. two texts ! Unicode Equality
are equal if they are identical after canonical decomposition. This ensures The definition of equality includes Unicode canonicalization. I.e. two
that different ways of expressing the same character in the underlying texts are equal if they are identical after canonical decomposition. This
binary representation are considered equal. ensures that different ways of expressing the same character in the
underlying binary representation are considered equal.
> Example > Example
The string 'É' (i.e. the character U+00C9, LATIN CAPITAL LETTER E WITH The string 'É' (i.e. the character U+00C9, LATIN CAPITAL LETTER E WITH
ACUTE) is equal ignore case to the string 'é' (i.e. the character U+00E9, ACUTE) is equal ignore case to the string 'é' (i.e. the character U+00E9,
LATIN SMALL LETTER E WITH ACUTE), which is canonically the same as the LATIN SMALL LETTER E WITH ACUTE), which is canonically the same as the
string 'e\u0301' (i.e. the letter `e` followed by U+0301, COMBINING ACUTE string 'e\u0301' (i.e. the letter `e` followed by U+0301, COMBINING ACUTE
ACCENT). Therefore: ACCENT). Therefore:
(('É' . equals_ignore_case 'é') && ('é' == 'e\u0301')) == True (('É' . equals_ignore_case 'é') && ('é' == 'e\u0301')) == True
Text.equals_ignore_case : Text -> Boolean Text.equals_ignore_case : Text -> Boolean
Text.equals_ignore_case that = Text_Utils.equals_ignore_case this that Text.equals_ignore_case that = Text_Utils.equals_ignore_case this that
## Compare two texts to discover their ordering. ## Compare two texts to discover their ordering.
Arguments:
- that: The text to order `this` with respect to.
> Example > Example
Checking how "a" orders in relation to "b". Checking how "a" orders in relation to "b".
"a".compare_to "b" "a".compare_to "b"
@ -165,10 +193,24 @@ Text.compare_to that = if this == that then Ordering.Equal else
if Text_Utils.lt this that then Ordering.Less else Ordering.Greater if Text_Utils.lt this that then Ordering.Less else Ordering.Greater
## Check if `this` is empty. ## Check if `this` is empty.
! What is Empty?
Text is considered to be empty when its length is zero.
> Example
Check if the text "aaa" is empty.
"aaa".is_empty
Text.is_empty : Boolean Text.is_empty : Boolean
Text.is_empty = this == "" Text.is_empty = this == ""
## Check if `this` is not empty. ## Check if `this` is not empty.
! What is Not Empty?
Text is considered to be not empty when its length is greater than zero.
> Example
Check if the text "aaa" is not empty.
"aaa".not_empty
Text.not_empty : Boolean Text.not_empty : Boolean
Text.not_empty = this.is_empty.not Text.not_empty = this.is_empty.not
@ -177,14 +219,24 @@ Text.not_empty = this.is_empty.not
This is useful for low-level operations, such as binary data encoding and This is useful for low-level operations, such as binary data encoding and
decoding. decoding.
> Example
Get the UTF-8 bytes of the text "Hello".
"Hello".utf_8
Text.utf_8 : Vector.Vector Text.utf_8 : Vector.Vector
Text.utf_8 = Vector.from_polyglot_array (Text_Utils.get_bytes this) Text.utf_8 = Vector.from_polyglot_array (Text_Utils.get_bytes this)
## Takes an array of bytes and returns Text resulting from decoding it as ## Takes a vector of bytes and returns Text resulting from decoding it as UTF-8.
UTF-8.
Arguments:
- bytes: The vector of UTF-8 bytes.
This is useful for low-level operations, such as binary data encoding and This is useful for low-level operations, such as binary data encoding and
decoding. decoding.
> Example
Decoding the bytes to get a text.
Text.from_utf_8 [-32, -92, -107, -32, -91, -115, -32, -92, -73, -32, -92, -65]
Text.from_utf_8 : Vector.Vector -> Text Text.from_utf_8 : Vector.Vector -> Text
Text.from_utf_8 bytes = Text_Utils.from_utf_8 bytes.to_array Text.from_utf_8 bytes = Text_Utils.from_utf_8 bytes.to_array
@ -193,6 +245,10 @@ Text.from_utf_8 bytes = Text_Utils.from_utf_8 bytes.to_array
This is useful for low-level operations, such as binary data encoding and This is useful for low-level operations, such as binary data encoding and
decoding. decoding.
> Example
Get the codepoints of the text "Hello".
"Hello".codepoints
Text.codepoints : Vector.Vector Text.codepoints : Vector.Vector
Text.codepoints = Text.codepoints =
Vector.from_polyglot_array (Text_Utils.get_codepoints this) Vector.from_polyglot_array (Text_Utils.get_codepoints this)
@ -202,43 +258,115 @@ Text.codepoints =
This is useful for low-level operations, such as binary data encoding and This is useful for low-level operations, such as binary data encoding and
decoding. decoding.
> Example
Converting a vector of codepoints back into a text.
Text.from_codepoints [129318, 127996, 8205, 9794, 65039]
Text.from_codepoints : Vector.Vector -> Text Text.from_codepoints : Vector.Vector -> Text
Text.from_codepoints codepoints = Text_Utils.from_codepoints codepoints.to_array Text.from_codepoints codepoints = Text_Utils.from_codepoints codepoints.to_array
## Checks whether `this` starts with `prefix`. ## Checks whether `this` starts with `prefix`.
Arguments:
- prefix: The prefix to see if `this` starts with.
! Unicode Equality
The definition of equality includes Unicode canonicalization. I.e. two
texts are equal if they are identical after canonical decomposition. This
ensures that different ways of expressing the same character in the
underlying binary representation are considered equal.
> Example
See if the text "Hello" starts with the prefix "hi".
"Hello".starts_with "hi"
Text.starts_with : Text -> Boolean Text.starts_with : Text -> Boolean
Text.starts_with prefix = Text_Utils.starts_with this prefix Text.starts_with prefix = Text_Utils.starts_with this prefix
## Checks whether `this` ends with `suffix`. ## Checks whether `this` ends with `suffix`.
Arguments:
- suffix: The suffix to see if `this` ends with.
! Unicode Equality
The definition of equality includes Unicode canonicalization. I.e. two
texts are equal if they are identical after canonical decomposition. This
ensures that different ways of expressing the same character in the
underlying binary representation are considered equal.
> Example
See if the text "Hello" ends with the suffix "low".
"Hello".ends_with "low"
Text.ends_with : Text -> Boolean Text.ends_with : Text -> Boolean
Text.ends_with suffix = Text_Utils.ends_with this suffix Text.ends_with suffix = Text_Utils.ends_with this suffix
## Checks whether `this` contains `sequence` as its substring. ## Checks whether `this` contains `sequence` as its substring.
Arguments:
- sequence: The text to see if it is contained in `this`.
! Unicode Equality
The definition of equality includes Unicode canonicalization. I.e. two
texts are equal if they are identical after canonical decomposition. This
ensures that different ways of expressing the same character in the
underlying binary representation are considered equal.
> Example
See if the text "Hello" contains the text "ell".
"Hello".contains "ell"
Text.contains : Text -> Boolean Text.contains : Text -> Boolean
Text.contains sequence = Text_Utils.contains this sequence Text.contains sequence = Text_Utils.contains this sequence
## Replaces each occurrences of `old_sequence` within `this` with `new_sequence`. ## Replaces each occurrences of `old_sequence` within `this` with `new_sequence`.
Arguments:
- old_sequence: The text to search for in `this`.
- new_sequence: The text to replace any occurrence of `old_sequence` with.
The replacement from the beginning of the text, as shown in the example below. The replacement from the beginning of the text, as shown in the example below.
> Example > Example
Replace letters in the text "aaa".
'aaa'.replace 'aa' 'b' == 'ba' 'aaa'.replace 'aa' 'b' == 'ba'
Text.replace : Text -> Text -> Text Text.replace : Text -> Text -> Text
Text.replace old_sequence new_sequence = Text_Utils.replace this old_sequence new_sequence Text.replace old_sequence new_sequence = Text_Utils.replace this old_sequence new_sequence
## Text to JSON conversion. ## Text to JSON conversion.
> Example
Convert the text "cześć" to JSON.
"cześć".to_json
Text.to_json : Json.String Text.to_json : Json.String
Text.to_json = Json.String this Text.to_json = Json.String this
## Takes a non-negative integer and returns a new text, consisting of `count` ## Takes a non-negative integer and returns a new text, consisting of `count`
concatenated copies of `this`. concatenated copies of `this`.
Arguments:
- count: The number of times that the text `this` should be repeated to make
the new text.
> Example
Repeat the string "ABBA" five times.
"ABBA".repeat 5
Text.repeat : Integer -> Text Text.repeat : Integer -> Text
Text.repeat count = Text.repeat count =
0.up_to count . fold "" acc-> _-> acc + this 0.up_to count . fold "" acc-> _-> acc + this
## Creates a new text by removing the first `count` characters of `this`. ## Creates a new text by removing the first `count` characters of `this`,
If `count` is greater than the number of characters in `this`, an empty text returning an empty text if `count` is greater than or equal to the length of
is returned. `this`.
Arguments:
- count: The number of characters to remove from the start of `this`.
! What is a Character?
A character is defined as an Extended Grapheme Cluster, see Unicode
Standard Annex 29. This is the smallest unit that still has semantic
meaning in most text-processing applications.
> Example
Removing the first three characters from the text "ABBA".
"ABBA".drop_first 3
Text.drop_first : Integer -> Text Text.drop_first : Integer -> Text
Text.drop_first count = Text.drop_first count =
iterator = BreakIterator.getCharacterInstance iterator = BreakIterator.getCharacterInstance
@ -247,9 +375,21 @@ Text.drop_first count =
boundary = iterator.next count boundary = iterator.next count
if boundary == -1 then '' else Text_Utils.drop_first this boundary if boundary == -1 then '' else Text_Utils.drop_first this boundary
## Creates a new text by removing the last `count` characters of `this`. ## Creates a new text by removing the last `count` characters of `this`,
If `count` is greater than the number of characters in `this`, an empty text returning an empty text if `count` is greater than or equal to the length of
is returned. `this`.
Arguments:
- count: The number of characters to remove from the end of `this`.
! What is a Character?
A character is defined as an Extended Grapheme Cluster, see Unicode
Standard Annex 29. This is the smallest unit that still has semantic
meaning in most text-processing applications.
> Example
Removing the last three characters from the text "ABBA".
"ABBA".drop_last 3
Text.drop_last : Integer -> Text Text.drop_last : Integer -> Text
Text.drop_last count = Text.drop_last count =
iterator = BreakIterator.getCharacterInstance iterator = BreakIterator.getCharacterInstance
@ -258,9 +398,20 @@ Text.drop_last count =
boundary = iterator.next -count boundary = iterator.next -count
if boundary == -1 then '' else Text_Utils.substring this 0 boundary if boundary == -1 then '' else Text_Utils.substring this 0 boundary
## Creates a new text by selecting the first `count` characters of `this`. ## Creates a new text by selecting the first `count` characters of `this`,
If `count` is greater than the number of characters in `this`, the whole returning `this` if `count` is greater than or equal to the length of `this`.
`this` is returned.
Arguments:
- count: The number of characters to take from the start of `this`.
! What is a Character?
A character is defined as an Extended Grapheme Cluster, see Unicode
Standard Annex 29. This is the smallest unit that still has semantic
meaning in most text-processing applications.
> Example
Make a new text from the first two characters of "boo".
"boo".take_first 2
Text.take_first : Integer -> Text Text.take_first : Integer -> Text
Text.take_first count = Text.take_first count =
iterator = BreakIterator.getCharacterInstance iterator = BreakIterator.getCharacterInstance
@ -269,9 +420,20 @@ Text.take_first count =
boundary = iterator.next count boundary = iterator.next count
if boundary == -1 then this else Text_Utils.substring this 0 boundary if boundary == -1 then this else Text_Utils.substring this 0 boundary
## Creates a new text by selecting the last `count` characters of `this`. ## Creates a new text by selecting the last `count` characters of `this`,
If `count` is greater than the number of characters in `this`, the whole returning `this` if `count` is greater than or equal to the length of `this`.
`this` is returned.
Arguments:
- count: The number of characters to take from the end of `this`.
! What is a Character?
A character is defined as an Extended Grapheme Cluster, see Unicode
Standard Annex 29. This is the smallest unit that still has semantic
meaning in most text-processing applications.
> Example
Make a new text from the last two characters of "boo".
"boo".take_last 2
Text.take_last : Integer -> Text Text.take_last : Integer -> Text
Text.take_last count = Text.take_last count =
iterator = BreakIterator.getCharacterInstance iterator = BreakIterator.getCharacterInstance
@ -283,8 +445,13 @@ Text.take_last count =
## Converts each character in `this` to lower case. ## Converts each character in `this` to lower case.
Arguments: Arguments:
- locale: specifies the locale for charater case mapping. Defaults to the - locale: specifies the locale for charater case mapping. Defaults to the
`Locale.default` locale. `Locale.default` locale.
! What is a Character?
A character is defined as an Extended Grapheme Cluster, see Unicode
Standard Annex 29. This is the smallest unit that still has semantic
meaning in most text-processing applications.
> Example > Example
Converting a text to lower case in the default locale: Converting a text to lower case in the default locale:
@ -300,8 +467,13 @@ Text.to_lower_case locale=Locale.default =
## Converts each character in `this` to upper case. ## Converts each character in `this` to upper case.
Arguments: Arguments:
- locale: specifies the locale for charater case mapping. Defaults to - locale: specifies the locale for charater case mapping. Defaults to
`Locale.default`. `Locale.default`.
! What is a Character?
A character is defined as an Extended Grapheme Cluster, see Unicode
Standard Annex 29. This is the smallest unit that still has semantic
meaning in most text-processing applications.
> Example > Example
Converting a text to upper case in the default locale: Converting a text to upper case in the default locale:

View File

@ -2,12 +2,16 @@ from Standard.Base import all
## The type of split for splitting text. ## The type of split for splitting text.
type Split_Kind type Split_Kind
## Split on unicode whitespace. ## Split on unicode whitespace.
type Whitespace type Whitespace
## Split into lines. ## Split into lines.
type Lines type Lines
## Split into words. ## Split into words.
type Words type Words
## Split on a literal.
## Split on a literal text value.
Text Text

View File

@ -12,8 +12,12 @@ polyglot java import org.enso.base.Time_Utils
type Date type Date
## This type represents a date, often viewed as year-month-day. For example, ## This type represents a date, often viewed as year-month-day.
the value "2nd October 2007" can be stored in a `Date`.
Arguments:
- internal_local_date: The internal date representation.
For example, the value "2nd October 2007" can be stored in a `Date`.
This class does not store or represent a time or timezone. Instead, it This class does not store or represent a time or timezone. Instead, it
is a description of the date, as used for birthdays. It cannot represent is a description of the date, as used for birthdays. It cannot represent
@ -22,56 +26,93 @@ type Date
type Date internal_local_date type Date internal_local_date
## Get the year field. ## Get the year field.
> Example
Get the current year.
Date.now.year
year : Integer year : Integer
year = this . internal_local_date . getYear year = this . internal_local_date . getYear
## Get the month of year field, as a number from 1 to 12. ## Get the month of year field, as a number from 1 to 12.
> Example
Get the current month.
Date.now.month
month : Integer month : Integer
month = this . internal_local_date . getMonthValue month = this . internal_local_date . getMonthValue
## Get the day of month field. ## Get the day of month field.
> Example
Get the current day.
Date.now.day
day : Integer day : Integer
day = this . internal_local_date . getDayOfMonth day = this . internal_local_date . getDayOfMonth
## Combine this date with time of day to create a point in time. ## Combine this date with time of day to create a point in time.
Arguments:
- time_of_day: The time to combine with the date to create a time.
- zone: The time-zone in which to create the time.
> Example > Example
Convert this date to midnight UTC time. Convert this date to midnight UTC time.
Day.new 2020 2 3 . to_time Time_Of_Day.new Zone.utc Day.new 2020 2 3 . to_time Time_Of_Day.new Zone.utc
to_time : Time_Of_Day -> Zone -> Time to_time : Time_Of_Day -> Zone -> Time
to_time daytime (zone = Zone.system) = Time.time (this . internal_local_date . atTime daytime.internal_local_time . atZone zone.internal_zone_id) to_time time_of_day (zone = Zone.system) = Time.time (this . internal_local_date . atTime time_of_day.internal_local_time . atZone zone.internal_zone_id)
## Add specified amount of time to this instant. ## Add the specified amount of time to this instant to get another date.
Arguments:
- amount: The time duration to add to this instant.
> Example > Example
Add 6 months to a local date. Add 6 months to a local date.
Date.new 2020 + 6.months Date.new 2020 + 6.months
+ : Duration -> Date + : Duration -> Date
+ amount = if amount.is_time then Error.throw (Time.Time_Error "Date does not support time intervals") else Date (this . internal_local_date . plus amount.internal_period) + amount = if amount.is_time then Error.throw (Time.Time_Error "Date does not support time intervals") else
Date (this . internal_local_date . plus amount.internal_period)
## Subtract specified amount of time to this instant. ## Subtract the specified amount of time from this instant to get another
date.
Arguments:
- amount: The time duration to subtract from this date.
> Example > Example
Subtract 7 days from a local date. Subtract 7 days from a local date.
Date.new 2020 - 7.days Date.new 2020 - 7.days
- : Duration -> Date - : Duration -> Date
- amount = if amount.is_time then Error.throw (Time.Time_Error "Date does not support time intervals") else Date (this . internal_local_date . minus amount.internal_period) - amount = if amount.is_time then Error.throw (Time.Time_Error "Date does not support time intervals") else
Date (this . internal_local_date . minus amount.internal_period)
## Format this date using the default formatter. ## Format this date using the default formatter.
> Example
Convert the current date to text.
Date.now.to_text
to_text : Text to_text : Text
to_text = Time_Utils.default_date_formatter . format this.internal_local_date to_text = Time_Utils.default_date_formatter . format this.internal_local_date
## A Date to Json conversion. ## A Date to Json conversion.
> Example
Convert the current date to JSON.
Date.now.to_json
to_json : Json.Object to_json : Json.Object
to_json = Json.from_pairs [["type", "Date"], ["day", this.day], ["month", this.month], ["year", this.year]] to_json = Json.from_pairs [["type", "Date"], ["day", this.day], ["month", this.month], ["year", this.year]]
## Format this date using formatter text. ## Format this date using the provided format specifier.
Patterns are based on a simple sequence of letters and symbols. For Arguments:
example, "d MMM yyyy" will format "2011-12-03" as "3 Dec 2011". - pattern: The text specifying the format for formatting the date.
For the list of accepted symbols in pattern refer to ? Pattern Syntax
`Base.Data.Time.Time.format` doc. Patterns are based on a simple sequence of letters and symbols. For
example, "d MMM yyyy" will format "2011-12-03" as "3 Dec 2011".
For the list of accepted symbols in pattern refer to the
`Base.Data.Time.Time.format` doc.
> Example > Example
Format "2020-06-02" as "2 June 2020" Format "2020-06-02" as "2 June 2020"
@ -95,33 +136,34 @@ type Date
format : Text -> Text format : Text -> Text
format pattern = DateTimeFormatter.ofPattern pattern . format this.internal_local_date format pattern = DateTimeFormatter.ofPattern pattern . format this.internal_local_date
## Obtains an instance of `Date` from a text, such as "2007-12-03". ## Converts text containing a date into a Date object.
Arguments: Arguments:
- text: The textual content to parse as a date. - text: The text to try and parse as a date.
Returns a `Time_Error` if the provided `text` cannot be parsed using the Returns a `Time_Error` if the provided `text` cannot be parsed using the
provided `pattern`. provided `pattern`.
The text must represent a valid date and is parsed using the ISO-8601 ? Date Formatting
extended local date format. The format consists of: The text must represent a valid date and is parsed using the ISO-8601
extended local date format. The format consists of:
- Four digits or more for the year. Years in the range 0000 to 9999 - Four digits or more for the year. Years in the range 0000 to 9999
will be pre-padded by zero to ensure four digits. Years outside will be pre-padded by zero to ensure four digits. Years outside
that range will have a prefixed positive or negative symbol. that range will have a prefixed positive or negative symbol.
- A dash - A dash
- Two digits for the month-of-year. This is pre-padded by zero to ensure two - Two digits for the month-of-year. This is pre-padded by zero to ensure
digits. two digits.
- A dash - A dash
- Two digits for the day-of-month. This is pre-padded by zero to ensure two - Two digits for the day-of-month. This is pre-padded by zero to ensure two
digits. digits.
> Example > Example
Parse the date of 23rd December 2020. Parse the date of 23rd December 2020.
Date.parse "2020-12-23" Date.parse "2020-12-23"
> Example > Example
Recover from the parse error. Recover from an error due to a wrong format.
Date.parse "my birthday" . catch e-> case e of Date.parse "my birthday" . catch e-> case e of
Time.Error _ -> Date.new 2000 1 1 Time.Error _ -> Date.new 2000 1 1
parse : Text -> Date ! Time.Time_Error parse : Text -> Date ! Time.Time_Error
@ -130,18 +172,19 @@ parse text =
Polyglot_Error err -> Error.throw (Time.Time_Error err.getMessage) Polyglot_Error err -> Error.throw (Time.Time_Error err.getMessage)
x -> x x -> x
## Obtains an instance of `Date` from a text using custom format. ## Converts text containing a date into a Date object using a custom format.
Arguments: Arguments:
- text: The textual content to parse as a time. - text: The textual content to parse as a time.
- pattern: The pattern describing how to parse the text. - pattern: The pattern describing how to parse the text.
For the list of accepted symbols in pattern refer to
`Base.Data.Time.Time.format` doc.
Returns a `Time_Error` if the provided `text` cannot be parsed using the Returns a `Time_Error` if the provided `text` cannot be parsed using the
provided `pattern`. provided `pattern`.
? Pattern Syntax
For the list of accepted symbols in pattern refer to the
`Base.Data.Time.Time.format` doc.
> Example > Example
Parse "1999-1-1" as Date. Parse "1999-1-1" as Date.
Date.parse_format "1999-1-1" "yyyy-M-d" Date.parse_format "1999-1-1" "yyyy-M-d"
@ -159,18 +202,27 @@ parse_format text pattern =
x -> x x -> x
## Obtains the current date from the system clock in the system timezone. ## Obtains the current date from the system clock in the system timezone.
> Example
Get the current date.
Date.now
now : Date now : Date
now = Date LocalDate.now now = Date LocalDate.now
## Alias for `now`. ## Alias for `now`.
> Example
Get the current date.
Date.today
today : Date today : Date
today = here.now today = here.now
## Obtains an instance of `Date` from a year, month and day. ## Constructs a new Date from a year, month, and day.
- month - the month-of-year to represent, from 1 (January) to 12 (December) Arguments
- day - the day-of-month to represent, from 1 to 31 and must be valid for the - month: The month-of-year to represent, from 1 (January) to 12 (December).
year and month - day: The day-of-month to represent, from 1 to 31. It must be valid for the
year and month.
Returns a `Time_Error` if the provided time is not valid. Returns a `Time_Error` if the provided time is not valid.

View File

@ -9,9 +9,17 @@ type Duration
## An amount of time in terms of years, months, days, hours, minutes, ## An amount of time in terms of years, months, days, hours, minutes,
seconds and nanoseconds. seconds and nanoseconds.
Arguments:
- internal_period: The internal representation of the time as a period.
- internal_duration: The internal representation of the time as a
duration.
type Duration internal_period internal_duration type Duration internal_period internal_duration
## Add specified amount of time to this duration. ## Add the specified amount of time to this duration.
Arguments:
- that: The duration to add to `this`.
> Example > Example
Add 6 seconds to a duration of 3 minutes Add 6 seconds to a duration of 3 minutes
@ -21,9 +29,12 @@ type Duration
Add 12 hours to a duration of a month. Add 12 hours to a duration of a month.
1.month + 12.hours 1.month + 12.hours
+ : Duration -> Duration + : Duration -> Duration
+ other = Duration (this.internal_period . plus other.internal_period . normalized) (this.internal_duration . plus other.internal_duration) + that = Duration (this.internal_period . plus that.internal_period . normalized) (this.internal_duration . plus that.internal_duration)
## Subtract specified amount of time from this duration. ## Subtract the specified amount of time from this duration.
Arguments:
- that: The duration to subtract from `this`.
> Example > Example
Subtract 11 months from a duration of 3 years Subtract 11 months from a duration of 3 years
@ -33,37 +44,69 @@ type Duration
Substract 30 minutes from a duration of 7 months. Substract 30 minutes from a duration of 7 months.
7.months - 30.minutes 7.months - 30.minutes
- : Duration -> Duration - : Duration -> Duration
- other = Duration (this.internal_period . minus other.internal_period . normalized) (this.internal_duration . minus other.internal_duration) - that = Duration (this.internal_period . minus that.internal_period . normalized) (this.internal_duration . minus that.internal_duration)
## Get the amount of nanoseconds of this duration. ## Get the portion of the duration expressed in nanoseconds.
> Example
Get the portion of the duration expressed in nanoseconds.
1.nanosecond.nanoseconds
nanoseconds : Integer nanoseconds : Integer
nanoseconds = this.internal_duration . toNanosPart nanoseconds = this.internal_duration . toNanosPart
## Get the amount of milliseconds of this duration. ## Get the portion of the duration expressed in milliseconds.
> Example
Get the portion of the duration expressed in milliseconds.
1.millisecond.milliseconds
milliseconds : Integer milliseconds : Integer
milliseconds = this.internal_duration . toMillisPart milliseconds = this.internal_duration . toMillisPart
## Get the amount of minutes of this duration. ## Get the portion of the duration expressed in seconds.
> Example
Get the portion of the duration expressed in seconds.
1.second.seconds
seconds : Integer seconds : Integer
seconds = this.internal_duration . toSecondsPart seconds = this.internal_duration . toSecondsPart
## Get the amount of minutes of this duration. ## Get the portion of the duration expressed in minutes.
> Example
Get the portion of the duration expressed in minutes.
1.minute.minutes
minutes : Integer minutes : Integer
minutes = this.internal_duration . toMinutesPart minutes = this.internal_duration . toMinutesPart
## Get the amount of hours of this duration. ## Get the portion of the duration expressed in hours.
> Example
Get the portion of the duration expressed in hours.
1.hour.hours
hours : Integer hours : Integer
hours = this.internal_duration . toHours hours = this.internal_duration . toHours
## Get the amount of days of this duration. ## Get the portion of the duration expressed in days.
> Example
Get the portion of the duration expressed in days.
1.day.days
days : Integer days : Integer
days = this.internal_period . getDays days = this.internal_period . getDays
## Get the amount of months of this duration. ## Get the portion of the duration expressed in months.
> Example
Get the portion of the duration expressed in months.
1.month.months
months : Integer months : Integer
months = this.internal_period . getMonths months = this.internal_period . getMonths
## Get the amount of days of this duration. ## Get the portion of the duration expressed in years.
> Example
Get the portion of the duration expressed in years.
1.year.years
years : Integer years : Integer
years = this.internal_period . getYears years = this.internal_period . getYears
@ -81,6 +124,10 @@ type Duration
to_vector = [this.years, this.months, this.days, this.hours, this.minutes, this.seconds, this.nanoseconds] to_vector = [this.years, this.months, this.days, this.hours, this.minutes, this.seconds, this.nanoseconds]
## A Duration to Json conversion. ## A Duration to Json conversion.
> Example
Convert a duration of 10 seconds to Json.
10.seconds.to_json
to_json : Json.Object to_json : Json.Object
to_json = to_json =
b = Vector.new_builder b = Vector.new_builder
@ -95,18 +142,37 @@ type Duration
Json.from_pairs b.to_vector Json.from_pairs b.to_vector
## Check if this duration is date-based. ## Check if this duration is date-based.
> Example
Check if the duration of 10 seconds is date-based.
10.seconds.is_date
is_date : Boolean is_date : Boolean
is_date = (this.years==0 . not) || (this.months==0 . not) || (this.days==0 . not) is_date = (this.years==0 . not) || (this.months==0 . not) || (this.days==0 . not)
## Check if this duration is time-based. ## Check if this duration is time-based.
> Example
Check if the duration of 10 seconds is time-based.
10.seconds.is_time
is_time : Boolean is_time : Boolean
is_time = (this.hours==0 . not) || (this.minutes==0 . not) || (this.seconds==0 . not) || (this.nanoseconds==0 . not) is_time = (this.hours==0 . not) || (this.minutes==0 . not) || (this.seconds==0 . not) || (this.nanoseconds==0 . not)
## Check if this duration represents an empty time-span. ## Check if this duration represents an empty time-span.
> Example
Check if the duration of 10 seconds is empty.
10.seconds.is_empty
is_empty : Boolean is_empty : Boolean
is_empty = this.is_date.not && this.is_time.not is_empty = this.is_date.not && this.is_time.not
## Check the durations equality. ## Check two durations for equality.
Arguments:
- that: The duration to compare against `this`.
> Examples
Check if 60 seconds and 1 minute are equal.
60.seconds == 1.minute
== : Duration -> Boolean == : Duration -> Boolean
== that = this.to_vector == that.to_vector == that = this.to_vector == that.to_vector
@ -176,9 +242,14 @@ Integer.years = this.year
## Create an interval representing the duration between two points in time. ## Create an interval representing the duration between two points in time.
Arguments:
- start_inclusive: The start time of the duration.
- end_inclusife: The end time of the duration.
> Example > Example
An hour interval between two points in time. An hour interval between two points in time.
Duration.between Time.now (Time.new 2010 10 20) Duration.between Time.now (Time.new 2010 10 20)
between : Time -> Time -> Duration between : Time -> Time -> Duration
between start_inclusive end_exclusive = between start_inclusive end_exclusive =
Duration (Java_Period.ofDays 0 . normalized) (Java_Duration.between start_inclusive.internal_zoned_date_time end_exclusive.internal_zoned_date_time) Duration (Java_Period.ofDays 0 . normalized) (Java_Duration.between start_inclusive.internal_zoned_date_time end_exclusive.internal_zoned_date_time)

View File

@ -12,7 +12,12 @@ polyglot java import org.enso.base.Time_Utils
type Time_Error type Time_Error
## Error produced while working with time. ## UNSTABLE
An error produced while working with time.
Arguments:
- error_message: The message for the error.
type Time_Error error_message type Time_Error error_message
type Time type Time
@ -20,6 +25,9 @@ type Time
## A date-time with a timezone in the ISO-8601 calendar system, such as ## A date-time with a timezone in the ISO-8601 calendar system, such as
"2007-12-03T10:15:30+01:00 Europe/Paris". "2007-12-03T10:15:30+01:00 Europe/Paris".
Arguments:
- internal_zoned_date_time: The internal repreentation of the time.
Time is a representation of a date-time with a timezone. This class Time is a representation of a date-time with a timezone. This class
stores all date and time fields, to a precision of nanoseconds, and a stores all date and time fields, to a precision of nanoseconds, and a
timezone, with a zone offset used to handle ambiguous local timezone, with a zone offset used to handle ambiguous local
@ -29,55 +37,108 @@ type Time
the Europe/Paris timezone" can be stored as `Time`. the Europe/Paris timezone" can be stored as `Time`.
type Time internal_zoned_date_time type Time internal_zoned_date_time
## Get the year field. ## Get the year portion of the time.
> Example
Get the current year.
Time.now.year
year : Integer year : Integer
year = this . internal_zoned_date_time . getYear year = this . internal_zoned_date_time . getYear
## Get the month of year field from 1 to 12. ## Get the month portion of the time as a number from 1 to 12.
> Example
Get the current month.
Time.now.month
month : Integer month : Integer
month = this . internal_zoned_date_time . getMonthValue month = this . internal_zoned_date_time . getMonthValue
## Get the day of month field. ## Get the day portion of the time.
> Example
Get the current day.
Time.now.day
day : Integer day : Integer
day = this . internal_zoned_date_time . getDayOfMonth day = this . internal_zoned_date_time . getDayOfMonth
## Get the hour of day field. ## Get the hour portion of the time.
> Example
Get the current hour.
Time.now.hour
hour : Integer hour : Integer
hour = this . internal_zoned_date_time . getHour hour = this . internal_zoned_date_time . getHour
## Get the minute of hour field. ## Get the minute portion of the time.
> Example
Get the current minute.
Time.now.minute
minute : Integer minute : Integer
minute = this . internal_zoned_date_time . getMinute minute = this . internal_zoned_date_time . getMinute
## Get the second of minute field ## Get the second portion of the time.
> Example
Get the current second.
Time.now.second
second : Integer second : Integer
second = this . internal_zoned_date_time . getSecond second = this . internal_zoned_date_time . getSecond
## Get the nano-of-second field. ## Get the nanosecond portion of the time.
> Example
Get the current nanosecond.
Time.now.nanosecond
nanosecond : Integer nanosecond : Integer
nanosecond = this . internal_zoned_date_time . getNano nanosecond = this . internal_zoned_date_time . getNano
## Get the timezone. ## Get the timezone for the time.
> Example
Get the current timezone.
Time.now.zone
zone : Zone zone : Zone
zone = Zone.zone (this . internal_zoned_date_time . getZone) zone = Zone.zone (this . internal_zoned_date_time . getZone)
## Return the number of seconds from the Unix epoch. ## Return the number of seconds from the Unix epoch.
> Example
Get the current number of seconds from the Unix epoch.
Time.now.to_epoch_seconds
to_epoch_seconds : Integer to_epoch_seconds : Integer
to_epoch_seconds = this . internal_zoned_date_time . toEpochSecond to_epoch_seconds = this . internal_zoned_date_time . toEpochSecond
## Return the number of milliseconds from the Unix epoch. ## Return the number of milliseconds from the Unix epoch.
> Example
Get the current number of milliseconds from the unix epoch.
Time.now.to_epoch_milliseconds
to_epoch_milliseconds : Integer to_epoch_milliseconds : Integer
to_epoch_milliseconds = this . internal_zoned_date_time . toInstant . toEpochMilli to_epoch_milliseconds = this . internal_zoned_date_time . toInstant . toEpochMilli
## Convert this point in time to time of day. ## Convert this point in time to time of day, discarding the time zone
information.
> Example
Convert the current time to a time of day.
Time.now.time_of_day
time_of_day : Time_Of_Day time_of_day : Time_Of_Day
time_of_day = Time_Of_Day.time_of_day this.internal_zoned_date_time.toLocalTime time_of_day = Time_Of_Day.time_of_day this.internal_zoned_date_time.toLocalTime
## Convert this point in time to date. ## Convert this point in time to date, discarding the time of day
information.
> Example
Convert the current time to a date.
Time.now.date
date : Date date : Date
date = Date.date this.internal_zoned_date_time.toLocalDate date = Date.date this.internal_zoned_date_time.toLocalDate
## Convert the time instant to a provided timezone. ## Convert the time instant to the same instant in the provided time zone.
Arguments:
- zone: The time-zone to convert the time instant into.
> Example > Example
Convert time instance to -04:00 timezone. Convert time instance to -04:00 timezone.
@ -85,7 +146,10 @@ type Time
at_zone : Zone -> Time at_zone : Zone -> Time
at_zone zone = Time (this.internal_zoned_date_time . withZoneSameInstant zone.internal_zone_id) at_zone zone = Time (this.internal_zoned_date_time . withZoneSameInstant zone.internal_zone_id)
## Add specified amount of time to this instant. ## Add the specified amount of time to this instant to produce a new instant.
Arguments:
- amount: The amount of time to add to this instant.
> Example > Example
Add 1 hour to a zoned date time. Add 1 hour to a zoned date time.
@ -97,7 +161,11 @@ type Time
+ : Duration -> Time + : Duration -> Time
+ amount = Time (this . internal_zoned_date_time . plus amount.internal_period . plus amount.internal_duration) + amount = Time (this . internal_zoned_date_time . plus amount.internal_period . plus amount.internal_duration)
## Subtract specified amount of time to this instant. ## Subtract the specified amount of time from this instant to get a new
instant.
Arguments:
- amount: The amount of time to subtract from this instant.
> Example > Example
Subtract 10 days from a zoned date time. Subtract 10 days from a zoned date time.
@ -109,60 +177,72 @@ type Time
- : Duration -> Time - : Duration -> Time
- amount = Time (this . internal_zoned_date_time . minus amount.internal_period . minus amount.internal_duration) - amount = Time (this . internal_zoned_date_time . minus amount.internal_period . minus amount.internal_duration)
## Format this time using the default formatter. ## Convert this time to text using the default formatter.
> Example
Convert the current time to text.
Time.now.to_text
to_text : Text to_text : Text
to_text = Time_Utils.default_time_formatter . format this.internal_zoned_date_time to_text = Time_Utils.default_time_formatter . format this.internal_zoned_date_time
## A Time to Json conversion. ## Convert the time to JSON.
> Example
Convert the current time to JSON.
Time.now.to_json
to_json : Json.Object to_json : Json.Object
to_json = Json.from_pairs [["type", "Time"], ["year", this.year], ["month", this.month], ["day", this.day], ["hour", this.hour], ["minute", this.minute], ["second", this.second], ["nanosecond", this.nanosecond], ["zone", this.zone]] to_json = Json.from_pairs [["type", "Time"], ["year", this.year], ["month", this.month], ["day", this.day], ["hour", this.hour], ["minute", this.minute], ["second", this.second], ["nanosecond", this.nanosecond], ["zone", this.zone]]
## Format this time using formatter text. ## Format this time as text using the specified format specifier.
Patterns are based on a simple sequence of letters and symbols. For Arguments:
example, "d MMM uuuu" will format "2011-12-03" as "3 Dec 2011". - pattern: The pattern that specifies how to format the time.
The list of accepted symbols with examples: ? Pattern Syntax
Patterns are based on a simple sequence of letters and symbols. For
example, "d MMM uuuu" will format "2011-12-03" as "3 Dec 2011".
- 'G', era, "AD; Anno Domini" The list of accepted symbols with examples:
- 'u', year, "2004; 04"
- 'y', year-of-era, "2004; 04"
- 'D', day-of-year, "189"
- 'M/L', month-of-year, "7; 07; Jul; July; J"
- 'd', day-of-month, "10"
- 'g', modified-julian-day, "2451334"
- 'Q/q', quarter-of-year, "3; 03; Q3; 3rd quarter"
- 'Y', week-based-year, "1996; 96"
- 'w', week-of-week-based-year, "27"
- 'W', week-of-month, "4"
- 'E', day-of-week, "Tue; Tuesday; T"
- 'e/c', localized day-of-week, "2; 02; Tue; Tuesday; T"
- 'F', day-of-week-in-month, "3"
- 'a', am-pm-of-day, "PM"
- 'h', clock-hour-of-am-pm (1-12), "12"
- 'K', hour-of-am-pm (0-11), "0"
- 'k', clock-hour-of-day (1-24), "24"
- 'H', hour-of-day (0-23), "0"
- 'm', minute-of-hour, "30"
- 's', second-of-minute, "55"
- 'S', fraction-of-second, "978"
- 'A', milli-of-day, "1234"
- 'n', nano-of-second, "987654321"
- 'N', nano-of-day, "1234000000"
- 'V', time-zone ID, "America/Los_Angeles; Z; -08:30"
- 'v', generic time-zone name, "Pacific Time; PT"
- 'z', time-zone name, "Pacific Standard Time; PST"
- 'O', localized zone-offset, "GMT+8; GMT+08:00; UTC-08:00"
- 'X', zone-offset 'Z' for zero, "Z; -08; -0830; -08:30; -083015; -08:30:15"
- 'x', zone-offset, "+0000; -08; -0830; -08:30; -083015; -08:30:15"
- 'Z', zone-offset, "+0000; -0800; -08:00"
- 'p', pad next, "1"
- ''', (single quote) escape for text, "'Text'"
- '''', (double quote) single quote, "'"
- '[', optional section start
- ']', optional section end
The count of pattern letters determines the format. - 'G', era, "AD; Anno Domini"
- 'u', year, "2004; 04"
- 'y', year-of-era, "2004; 04"
- 'D', day-of-year, "189"
- 'M/L', month-of-year, "7; 07; Jul; July; J"
- 'd', day-of-month, "10"
- 'g', modified-julian-day, "2451334"
- 'Q/q', quarter-of-year, "3; 03; Q3; 3rd quarter"
- 'Y', week-based-year, "1996; 96"
- 'w', week-of-week-based-year, "27"
- 'W', week-of-month, "4"
- 'E', day-of-week, "Tue; Tuesday; T"
- 'e/c', localized day-of-week, "2; 02; Tue; Tuesday; T"
- 'F', day-of-week-in-month, "3"
- 'a', am-pm-of-day, "PM"
- 'h', clock-hour-of-am-pm (1-12), "12"
- 'K', hour-of-am-pm (0-11), "0"
- 'k', clock-hour-of-day (1-24), "24"
- 'H', hour-of-day (0-23), "0"
- 'm', minute-of-hour, "30"
- 's', second-of-minute, "55"
- 'S', fraction-of-second, "978"
- 'A', milli-of-day, "1234"
- 'n', nano-of-second, "987654321"
- 'N', nano-of-day, "1234000000"
- 'V', time-zone ID, "America/Los_Angeles; Z; -08:30"
- 'v', generic time-zone name, "Pacific Time; PT"
- 'z', time-zone name, "Pacific Standard Time; PST"
- 'O', localized zone-offset, "GMT+8; GMT+08:00; UTC-08:00"
- 'X', zone-offset 'Z' for zero, "Z; -08; -0830; -08:30; -083015; -08:30:15"
- 'x', zone-offset, "+0000; -08; -0830; -08:30; -083015; -08:30:15"
- 'Z', zone-offset, "+0000; -0800; -08:00"
- 'p', pad next, "1"
- ''', (single quote) escape for text, "'Text'"
- '''', (double quote) single quote, "'"
- '[', optional section start
- ']', optional section end
The count of pattern letters determines the format.
> Example > Example
Format "2020-10-08T16:41:13+03:00[Europe/Moscow]" as "2020-10-08T16:41:13+03:00[Europe/Moscow]" Format "2020-10-08T16:41:13+03:00[Europe/Moscow]" as "2020-10-08T16:41:13+03:00[Europe/Moscow]"
@ -184,17 +264,18 @@ type Time
Arguments: Arguments:
- text: The text representing the time to be parsed. - text: The text representing the time to be parsed.
The text must represent a valid date-time and is parsed using the ISO-8601 ? Valid Formatting
extended offset date-time format to add the timezone. The section in square The text must represent a valid date-time and is parsed using the ISO-8601
brackets is not part of the ISO-8601 standard. The format consists of: extended offset date-time format to add the timezone. The section in square
brackets is not part of the ISO-8601 standard. The format consists of:
- The ISO offset date time. - The ISO offset date time.
- If the zone ID is not available or is a zone offset then the format is - If the zone ID is not available or is a zone offset then the format is
complete. complete.
- An open square bracket '['. - An open square bracket '['.
- The zone ID. This is not part of the ISO-8601 standard. Parsing is case - The zone ID. This is not part of the ISO-8601 standard. Parsing is case
sensitive. sensitive.
- A close square bracket ']'. - A close square bracket ']'.
This method will return a `Time_Error` if the provided time cannot be parsed This method will return a `Time_Error` if the provided time cannot be parsed
using the above format. using the above format.
@ -225,7 +306,7 @@ parse text =
Polyglot_Error err -> Error.throw (Time_Error err.getMessage) Polyglot_Error err -> Error.throw (Time_Error err.getMessage)
x -> x x -> x
## Obtains an instance of Time from a text using custom format. ## Converts text to a time using a provided format specifier.
Arguments: Arguments:
- text: The text to parse as a time of day, using the specified pattern. - text: The text to parse as a time of day, using the specified pattern.
@ -234,8 +315,9 @@ parse text =
Returns a `Time_Error` if the provided text cannot be parsed using the Returns a `Time_Error` if the provided text cannot be parsed using the
provided pattern and locale. provided pattern and locale.
For the list of accepted symbols in pattern refer to `Time.format` doc. ? Pattern Syntax
For the list of accepted symbols in pattern refer to `Time.format` doc.
> Example > Example
Parse "2020-05-06 04:30:20" as Time Parse "2020-05-06 04:30:20" as Time
@ -251,6 +333,10 @@ parse_format text pattern locale=Locale.default =
x -> x x -> x
## Obtains the current date-time from the system clock in the system timezone. ## Obtains the current date-time from the system clock in the system timezone.
> Example
Get the current time
Time.now
now : Time now : Time
now = Time ZonedDateTime.now now = Time ZonedDateTime.now

View File

@ -14,39 +14,71 @@ polyglot java import org.enso.base.Time_Utils
type Time_Of_Day type Time_Of_Day
## This type is a date-time object that represents a time, often viewed ## This type is a date-time object that represents a time, often viewed
as hour-minute-second. Time is represented to nanosecond precision. For as hour-minute-second.
example, the value "13:45.30.123456789" can be stored in a `Time_Of_Day`.
Arguments:
- internal_local_time: The internal representation of the time of day.
Time is represented to nanosecond precision. For example, the value
"13:45.30.123456789" can be stored in a `Time_Of_Day`.
type Time_Of_Day internal_local_time type Time_Of_Day internal_local_time
## Get the hour of day field. ## Get the hour portion of the time of day.
> Example
Get the current hour.
Time_Of_Day.now.hour
hour : Integer hour : Integer
hour = this . internal_local_time . getHour hour = this . internal_local_time . getHour
## Get the minute of hour field. ## Get the minute portion of the time of day.
> Example
Get the current minute.
Time_Of_Day.now.minute
minute : Integer minute : Integer
minute = this . internal_local_time . getMinute minute = this . internal_local_time . getMinute
## Get the second of minute field. ## Get the second portion of the time of day.
> Example
Get the current second.
Time_Of_Day.now.second
second : Integer second : Integer
second = this . internal_local_time . getSecond second = this . internal_local_time . getSecond
## Get the nanosecond of second field. ## Get the nanosecond portion of the time of day.
> Example
Get the current nanosecond.
Time_Of_Day.now.nanosecond
nanosecond : Integer nanosecond : Integer
nanosecond = this . internal_local_time . getNano nanosecond = this . internal_local_time . getNano
## Extracts the time as the number of seconds, from 0 to 24 * 60 * 60 - 1. ## Extracts the time as the number of seconds, from 0 to 24 * 60 * 60 - 1.
> Example
Convert the current time to seconds of the day.
Time_Of_Day.now.to_seconds
to_seconds : Integer to_seconds : Integer
to_seconds = this . internal_local_time . toSecondOfDay to_seconds = this . internal_local_time . toSecondOfDay
## Combine this time of day with a date to create a point in time. ## Combine this time of day with a date to create a point in time.
Arguments:
- date: The date on which this time should occur.
- zone: The time-zone in which the time is specified.
> Example > Example
Convert local time to 1st January 2020 12:30 at system timezone. Convert local time to 1st January 2020 12:30 at system timezone.
Time_Of_Day.new 12 30 . to_time (Date.new 2020) Time_Of_Day.new 12 30 . to_time (Date.new 2020)
to_time : Date -> Zone -> Time to_time : Date -> Zone -> Time
to_time date (zone = Zone.system) = Time.time (this . internal_local_time . atDate date.internal_local_date . atZone zone.internal_zone_id) to_time date (zone = Zone.system) = Time.time (this . internal_local_time . atDate date.internal_local_date . atZone zone.internal_zone_id)
## Add specified amount of time to this instant. ## Add the specified amount of time to this instant to get a new instant.
Arguments:
- amount: The amount of time to add to this instant.
> Example > Example
Add 3 seconds to a local time. Add 3 seconds to a local time.
@ -54,7 +86,11 @@ type Time_Of_Day
+ : Duration -> Time_Of_Day + : Duration -> Time_Of_Day
+ amount = if amount.is_date then Error.throw (Time.Time_Error "Time_Of_Day does not support date intervals") else Time_Of_Day (this . internal_local_time . plus amount.internal_duration) + amount = if amount.is_date then Error.throw (Time.Time_Error "Time_Of_Day does not support date intervals") else Time_Of_Day (this . internal_local_time . plus amount.internal_duration)
## Subtract specified amount of time to this instant. ## Subtract the specified amount of time from this instant to get a new
instant.
Arguments:
- amount: The amount of time to subtract from this instant.
> Example > Example
Subtract 12 hours from a local time. Subtract 12 hours from a local time.
@ -62,21 +98,33 @@ type Time_Of_Day
- : Duration -> Time_Of_Day - : Duration -> Time_Of_Day
- amount = if amount.is_date then Error.throw (Time.Time_Error "Time_Of_Day does not support date intervals") else Time_Of_Day (this . internal_local_time . minus amount.internal_duration) - amount = if amount.is_date then Error.throw (Time.Time_Error "Time_Of_Day does not support date intervals") else Time_Of_Day (this . internal_local_time . minus amount.internal_duration)
## Format this time of day using the default formatter. ## Format this time of day as text using the default formatter.
> Example
Convert the current time to text.
Time_Of_Day.now.to_text
to_text : Text to_text : Text
to_text = Time_Utils.default_time_of_day_formatter . format this.internal_local_time to_text = Time_Utils.default_time_of_day_formatter . format this.internal_local_time
## A Time_Of_Day to Json conversion. ## A Time_Of_Day to Json conversion.
> Example
Convert the current time to JSON.
Time_Of_Day.now.to_text
to_json : Json.Object to_json : Json.Object
to_json = Json.from_pairs [["type", "Time_Of_Day"], ["hour", this.hour], ["minute", this.minute], ["second", this.second], ["nanosecond", this.nanosecond]] to_json = Json.from_pairs [["type", "Time_Of_Day"], ["hour", this.hour], ["minute", this.minute], ["second", this.second], ["nanosecond", this.nanosecond]]
## Format this time of day using formatter text. ## Format this time of day using the provided formatter pattern.
Patterns are based on a simple sequence of letters and symbols. For Arguments:
example, "HH-mm-ss.SSS" will format "16:21:10" as "16-21-10.323". - pattern: The pattern specifying how to format the time of day.
For the list of accepted symbols in pattern refer to ? Pattern Syntax
`Base.Data.Time.Time.format` doc. Patterns are based on a simple sequence of letters and symbols. For
example, "HH-mm-ss.SSS" will format "16:21:10" as "16-21-10.323".
For the list of accepted symbols in pattern refer to the
`Base.Data.Time.Time.format` doc.
> Example > Example
Format "16:21:10" as "16:21:00.1234" Format "16:21:10" as "16:21:00.1234"
@ -108,22 +156,24 @@ type Time_Of_Day
Returns a `Time_Error` if the provided text cannot be parsed using the Returns a `Time_Error` if the provided text cannot be parsed using the
default format. default format.
The text must represent a valid time and is parsed using the ISO-8601 ? Valid Time Format
extended local time format. The format consists of: The text must represent a valid time and is parsed using the ISO-8601
extended local time format. The format consists of:
- Two digits for the hour-of-day. This is pre-padded by zero to ensure two - Two digits for the hour-of-day. This is pre-padded by zero to ensure two
digits. digits.
- A colon - A colon
- Two digits for the minute-of-hour. This is pre-padded by zero to ensure two - Two digits for the minute-of-hour. This is pre-padded by zero to ensure
digits. two digits.
- If the second-of-minute is not available then the format is complete. - If the second-of-minute is not available then the format is complete.
- A colon - A colon
- Two digits for the second-of-minute. This is pre-padded by zero to ensure - Two digits for the second-of-minute. This is pre-padded by zero to ensure
two digits. two digits.
- If the nano-of-second is zero or not available then the format is complete. - If the nano-of-second is zero or not available then the format is
- A decimal point complete.
- One to nine digits for the nano-of-second. As many digits will be output as - A decimal point
required. - One to nine digits for the nano-of-second. As many digits will be output
as required.
> Example > Example
Get the time 15:05:30. Get the time 15:05:30.
@ -149,8 +199,9 @@ parse text =
Returns a `Time_Error` if the provided text cannot be parsed using the Returns a `Time_Error` if the provided text cannot be parsed using the
provided pattern and locale. provided pattern and locale.
For the list of accepted symbols in pattern refer to ? Pattern Syntax
`Base.Data.Time.Time.format` doc. For the list of accepted symbols in pattern refer to the
`Base.Data.Time.Time.format` doc.
> Example > Example
Parse "04:30:20" as Time_Of_Day. Parse "04:30:20" as Time_Of_Day.
@ -167,16 +218,21 @@ parse_format text pattern locale=Locale.default =
x -> x x -> x
## Obtains the current time from the system clock in the default time-zone. ## Obtains the current time from the system clock in the default time-zone.
> Example
Get the current time in the default time zone.
Time_Of_Day.now
now : Time_Of_Day now : Time_Of_Day
now = Time_Of_Day LocalTime.now now = Time_Of_Day LocalTime.now
## Obtains an instance of `Time_Of_Day` from an hour, minute, second ## Obtains an instance of `Time_Of_Day` from an hour, minute, second
and nanosecond. and nanosecond.
- hour - the hour-of-day to represent, from 0 to 23 Arguments:
- minute - the minute-of-hour to represent, from 0 to 59 - hour: The hour-of-day to represent, from 0 to 23.
- second - the second-of-minute to represent, from 0 to 59 - minute: The minute-of-hour to represent, from 0 to 59.
- nanosecond - the nano-of-second to represent, from 0 to 999,999,999 - second: The second-of-minute to represent, from 0 to 59.
- nanosecond: The nano-of-second to represent, from 0 to 999,999,999.
Returns a `Time_Error` if the provided time is not a valid time. Returns a `Time_Error` if the provided time is not a valid time.

View File

@ -7,20 +7,35 @@ type Zone
## A type representing a time zone. ## A type representing a time zone.
Arguments:
- internal_zone_id: The identifier for the internal zone of the
representation.
A time zone can be eiter offset-based like "-06:00" or id-based like A time zone can be eiter offset-based like "-06:00" or id-based like
"Europe/Paris". "Europe/Paris".
type Zone internal_zone_id type Zone internal_zone_id
## Get the unique timezone ID. ## Get the unique timezone ID.
> Example
Get the unique identifier for your system's current timezone.
Zone.system.zone_id
zone_id : Text zone_id : Text
zone_id = this.internal_zone_id . getId zone_id = this.internal_zone_id . getId
## A Zone to Json conversion ## Convert the time zone to JSON.
> Example
Convert your system's current timezone to JSON.
Zone.system.to_json
to_json : Json.Object to_json : Json.Object
to_json = Json.from_pairs [["type", "Zone"], ["id", this.zone_id]] to_json = Json.from_pairs [["type", "Zone"], ["id", this.zone_id]]
## This method parses the ID producing a `Zone`. ## This method parses the ID producing a `Zone`.
Arguments:
- text: The text representing a zone identifier.
> Example > Example
Get Central European Time. Get Central European Time.
Zone.parse "CET" Zone.parse "CET"
@ -40,27 +55,41 @@ parse : Text -> Zone
parse text = Zone (ZoneId.of text) parse text = Zone (ZoneId.of text)
## The system default timezone. ## The system default timezone.
> Example
Get the system default timezone.
Zone.system
system : Zone system : Zone
system = Zone ZoneId.systemDefault system = Zone ZoneId.systemDefault
## The system default timezone. ## The system's local timezone.
> Example
Get the system's local timezone.
Zone.local
local : Zone local : Zone
local = here.system local = here.system
## UTC time zone. ## The UTC timezone.
> Example
Get the UTC timezone.
Zone.utc
utc : Zone utc : Zone
utc = here.parse "UTC" utc = here.parse "UTC"
## Obtains an instance of `Zone` using an offset in hours, minutes and seconds. ## Obtains an instance of `Zone` using an offset in hours, minutes and seconds
from the UTC zone.
- the timezone offset in hours, from -18 to +18 Arguments:
- the timezone offset in minutes, from 0 to ±59, sign matches hours and - hours: The timezone offset in hours from UTC, from -18 to +18.
seconds - minutes: The timezone offset in minutes from the nearest hour, from 0 to
- the timezone offset in seconds, from 0 to ±59, sign matches hours and ±59. The sign must match that of the hours argument.
minutes - seconds: The timezone offset in seconds from the nearest minute, from 0 to
±59. The sign must match that of the minutes argument.
> Example > Example
Get time zone 1 hour 1 minute and 50 seconds of Greenwich/UTC. Get time zone 1 hour 1 minute and 50 seconds from UTC.
Zone.new 1 1 50 Zone.new 1 1 50
new : Integer -> Integer -> Integer -> Zone new : Integer -> Integer -> Integer -> Zone
new (hours = 0) (minutes = 0) (seconds = 0) = new (hours = 0) (minutes = 0) (seconds = 0) =

View File

@ -4,8 +4,10 @@ from Builtins import Array
## Creates a new vector of the given length, initializing elements using ## Creates a new vector of the given length, initializing elements using
the provided constructor function. the provided constructor function.
The constructor function is called with the consecutive indices Arguments:
(0-based) of the vector elements. - length: The length of the vector (>= 0).
- constructor: A function taking the index in the vector and returning an
item for that index in the vector.
> Example > Example
To create a vector containing the numbers 1 through 50: To create a vector containing the numbers 1 through 50:
@ -23,6 +25,10 @@ new length constructor =
## Creates a new vector of the given length, filling the elements with ## Creates a new vector of the given length, filling the elements with
the provided constant. the provided constant.
Arguments:
- length: The length of the vector (>= 0).
- constructor: A value fo be placed into each element of the vector.
> Example > Example
A vector containing 50 elements, each being the number `42`, can be A vector containing 50 elements, each being the number `42`, can be
created by: created by:
@ -58,8 +64,12 @@ fill length ~item =
new_builder : Builder new_builder : Builder
new_builder = Builder.new new_builder = Builder.new
## Converts a polyglot value representing an array into a vector. This is ## Converts a polyglot value representing an array into a vector.
useful when wrapping polyglot APIs for further use in Enso.
Arguments:
- arr: The array value to wrap into a vector.
This is useful when wrapping polyglot APIs for further use in Enso.
from_polyglot_array : Any -> Vector.Vector from_polyglot_array : Any -> Vector.Vector
from_polyglot_array arr = here.new arr.length (arr.at _) from_polyglot_array arr = here.new arr.length (arr.at _)
@ -89,6 +99,9 @@ type Vector
## Gets an element from the vector at a specified index (0-based). ## Gets an element from the vector at a specified index (0-based).
Arguments:
- index: The location in the vector to get the element from.
> Example > Example
To get the second element of the vector `[1, 2, 3]`, use: To get the second element of the vector `[1, 2, 3]`, use:
[1, 2, 3].at 1 [1, 2, 3].at 1
@ -98,6 +111,10 @@ type Vector
## Combines all the elements of the vector, by iteratively applying the ## Combines all the elements of the vector, by iteratively applying the
passed function with next elements of the vector. passed function with next elements of the vector.
Arguments:
- init: The initial value for the fold.
- function: A function taking two elements and combining them.
In general, the result of In general, the result of
[l0, l1, ..., ln] . fold init f [l0, l1, ..., ln] . fold init f
is the same as is the same as
@ -108,12 +125,16 @@ type Vector
vector: vector:
[0, 1, 2] . fold 0 (+) [0, 1, 2] . fold 0 (+)
fold : Any -> (Any -> Any -> Any) -> Any fold : Any -> (Any -> Any -> Any) -> Any
fold initial function = fold init function =
arr = this.to_array arr = this.to_array
f = acc -> ix -> function acc (arr.at ix) f = acc -> ix -> function acc (arr.at ix)
0.up_to this.length . fold initial f 0.up_to this.length . fold init f
## Combines all the elements of a non-empty vector using a binary operation. ## Combines all the elements of a non-empty vector using a binary operation.
Arguments:
- function: A binary operation that takes two items and combines them.
If the vector is empty, it throws Nothing. If the vector is empty, it throws Nothing.
> Example > Example
@ -128,8 +149,10 @@ type Vector
## Checks whether a predicate holds for at least one element of this vector. ## Checks whether a predicate holds for at least one element of this vector.
A predicate is a function that takes an element from the vector and Arguments:
returns a boolean value. - predicate: A function that takes a list element and returns a boolean
value that says whether that value satisfies the conditions of the
function.
> Example > Example
Checking if any element of the list is larger than 3. Checking if any element of the list is larger than 3.
@ -142,10 +165,12 @@ type Vector
go 0 False go 0 False
## Returns the first element of the vector that satisfies the predicate or ## Returns the first element of the vector that satisfies the predicate or
If no elements of the vector satisfy the predicate, it throws nothing. if no elements of the vector satisfy the predicate, it throws nothing.
A predicate is a function that takes an element from the vector and Arguments:
returns a boolean value. - predicate: A function that takes a list element and returns a boolean
value that says whether that value satisfies the conditions of the
function.
> Example > Example
Finding a first element of the list that is larger than 3. Finding a first element of the list that is larger than 3.
@ -162,8 +187,11 @@ type Vector
## Checks whether a predicate holds for at least one element of this vector. ## Checks whether a predicate holds for at least one element of this vector.
A predicate is a function that takes an element from the vector and
returns a boolean value. Arguments:
- predicate: A function that takes a list element and returns a boolean
value that says whether that value satisfies the conditions of the
function.
> Example > Example
Checking if any element of the list is larger than 3. Checking if any element of the list is larger than 3.
@ -173,6 +201,11 @@ type Vector
## Checks whether a predicate holds for all elements in this vector. ## Checks whether a predicate holds for all elements in this vector.
Arguments:
- predicate: A function that takes a list element and returns a boolean
value that says whether that value satisfies the conditions of the
function.
> Example > Example
Check if all elements in the vector are less than zero. Check if all elements in the vector are less than zero.
[-1, 1, 5, 8].all (< 0) [-1, 1, 5, 8].all (< 0)
@ -181,6 +214,9 @@ type Vector
## Checks whether this vector contains a given value as an element. ## Checks whether this vector contains a given value as an element.
Arguments:
- elem: The item to see if it exists in the vector.
> Example > Example
Checking if the vector contains the number 72. Checking if the vector contains the number 72.
[1, 383, 72, 301].contains 72 [1, 383, 72, 301].contains 72
@ -207,8 +243,10 @@ type Vector
## Selects all elements of this vector which satisfy a predicate. ## Selects all elements of this vector which satisfy a predicate.
A predicate is a function that takes an element from the vector and Arguments:
returns a boolean value. - predicate: A function that takes a list element and returns a boolean
value that says whether that value satisfies the conditions of the
function.
> Example > Example
Selecting all elements that are greater than 3. Selecting all elements that are greater than 3.
@ -221,6 +259,10 @@ type Vector
## Applies a function to each element of the vector, returning the vector of ## Applies a function to each element of the vector, returning the vector of
results. results.
Arguments:
- function: A function that takes an element in the vector and returns
some transformation of that element.
> Example > Example
In the following example, we add `1` to each element of the vector: In the following example, we add `1` to each element of the vector:
[1, 2, 3] . map +1 [1, 2, 3] . map +1
@ -233,12 +275,14 @@ type Vector
## Applies a function to each element of the vector, returning the vector ## Applies a function to each element of the vector, returning the vector
that contains all results concatenated. that contains all results concatenated.
Arguments:
- function: A function that takes an element in the vector, transforms
it, and returns a vector.
> Example > Example
In the following example, we replace each number `n` with itself In the following example, we replace each number `n` with itself
repeated `n` times: repeated `n` times:
[0, 1, 2] . flat_map (n -> Vector.fill n n) [0, 1, 2] . flat_map (n -> Vector.fill n n)
The result of running the code above is:
[1, 2, 2]
flat_map : (Any -> Vector) -> Vector flat_map : (Any -> Vector) -> Vector
flat_map function = flat_map function =
mapped = this.map function mapped = this.map function
@ -252,13 +296,24 @@ type Vector
## Applies a function to each element of the vector, returning the vector ## Applies a function to each element of the vector, returning the vector
of results. of results.
Arguments:
- function: A function that takes an index and an item and calculates a
new value for at that index.
The function is called with both the element index as well as the The function is called with both the element index as well as the
element itself. element itself.
map_with_index : (Int -> Any -> Any) -> Vector
> Example
Summing numbers with their indices in a vector.
[1, 2, 3].map_with_index (+)
map_with_index : (Integer -> Any -> Any) -> Vector
map_with_index function = here.new this.length i-> function i (this.at i) map_with_index function = here.new this.length i-> function i (this.at i)
## Applies a function to each element of the vector. ## Applies a function to each element of the vector.
Arguments:
- function: A function to apply to each element of the vector.
Unlike `map`, this method does not return the individual results, Unlike `map`, this method does not return the individual results,
therefore it is only useful for side-effecting computations. therefore it is only useful for side-effecting computations.
@ -273,6 +328,10 @@ type Vector
## Reverses the vector, returning a vector with the same elements, but in ## Reverses the vector, returning a vector with the same elements, but in
the opposite order. the opposite order.
> Example
Reversing a two-element vector.
[1, 2].reverse
reverse : Vector reverse : Vector
reverse = here.new this.length (i -> this.at (this.length - (1 + i))) reverse = here.new this.length (i -> this.at (this.length - (1 + i)))
@ -289,12 +348,17 @@ type Vector
tail_elems = 1.up_to this.length . fold "" folder tail_elems = 1.up_to this.length . fold "" folder
"[" + (this.at 0 . to_text) + tail_elems + "]" "[" + (this.at 0 . to_text) + tail_elems + "]"
## Checks whether this vector is equal to `that`. Two vectors are considered ## Checks whether this vector is equal to `that`.
equal, when they have the same length and their items are pairwise equal.
Arguments:
- that: The vector to compare this vector against.
Two vectors are considered equal, when they have the same length and
their items are pairwise equal.
> Example > Example
Comparing two vectors for equality (this case is false). Comparing two vectors for equality (this case is false).
[1, 2, 3] == [2, 3, 4 [1, 2, 3] == [2, 3, 4]
== : Vector -> Boolean == : Vector -> Boolean
== that = == that =
eq_at i = this.at i == that.at i eq_at i = this.at i == that.at i
@ -303,6 +367,9 @@ type Vector
## Concatenates two vectors, resulting in a new vector, containing all the ## Concatenates two vectors, resulting in a new vector, containing all the
elements of `this`, followed by all the elements of `that`. elements of `this`, followed by all the elements of `that`.
Arguments:
- that: The vector to concatenate to the end of `this`.
> Example > Example
Concatenating two single-element vectors. Concatenating two single-element vectors.
[1] + [2] == [1, 2] [1] + [2] == [1, 2]
@ -323,7 +390,7 @@ type Vector
> Example > Example
Add one element in front: Add one element in front:
[2, 3].prepend 1 == [1, 2, 3] [2, 3].prepend 1 == [1, 2, 3]
prepend : Any -> Vector prepend : Any -> Vector
prepend element = [element] + this prepend element = [element] + this
@ -334,13 +401,16 @@ type Vector
> Example > Example
Add one element to the end: Add one element to the end:
[1, 2].append 3 == [1, 2, 3] [1, 2].append 3 == [1, 2, 3]
append : Any -> Vector append : Any -> Vector
append element = this + [element] append element = this + [element]
## When `this` is a vector of text values, concatenates all the values by ## When `this` is a vector of text values, concatenates all the values by
interspersing them with `separator`. interspersing them with `separator`.
Arguments:
- separator: The text to use to join the textual elements of the vector.
> Example > Example
The following code returns "foo, bar, baz" The following code returns "foo, bar, baz"
["foo", "bar", "baz"].join ", " ["foo", "bar", "baz"].join ", "
@ -352,6 +422,9 @@ type Vector
## Creates a new vector with the first `count` elements in `this` removed. ## Creates a new vector with the first `count` elements in `this` removed.
Arguments:
- count: The number of elements to drop from the start of `this`.
> Example > Example
The following code returns [2, 3, 4, 5] The following code returns [2, 3, 4, 5]
[1, 2, 3, 4, 5].drop_start 1 [1, 2, 3, 4, 5].drop_start 1
@ -361,6 +434,9 @@ type Vector
## Creates a new vector with the last `count` elements in `this` removed. ## Creates a new vector with the last `count` elements in `this` removed.
Arguments:
- count: The number of elements to drop from the end of `this`.
> Example > Example
The following code returns [1, 2, 3] The following code returns [1, 2, 3]
[1, 2, 3, 4, 5].drop_end 2 [1, 2, 3, 4, 5].drop_end 2
@ -371,6 +447,9 @@ type Vector
## Creates a new vector, consisting of the first `count` elements on the ## Creates a new vector, consisting of the first `count` elements on the
left of `this`. left of `this`.
Arguments:
- count: The number of elements to take from the start of `this`.
> Example > Example
The following code returns [1, 2] The following code returns [1, 2]
[1, 2, 3, 4, 5].take_start 2 [1, 2, 3, 4, 5].take_start 2
@ -381,6 +460,9 @@ type Vector
## Creates a new vector, consisting of the last `count` elements on the ## Creates a new vector, consisting of the last `count` elements on the
right of `this`. right of `this`.
Arguments:
- count: The number of elements to take from the end of `this`.
> Example > Example
The following code returns [3, 4, 5] The following code returns [3, 4, 5]
[1, 2, 3, 4, 5].take_end 3 [1, 2, 3, 4, 5].take_end 3
@ -390,12 +472,20 @@ type Vector
## Performs a pair-wise operation passed in `function` on consecutive ## Performs a pair-wise operation passed in `function` on consecutive
elements of `this` and `that`. elements of `this` and `that`.
Arguments:
- that: The vector to zip with `this`.
- function: The function used to combine pairwise elements of `this` and
`that`.
The result of this function is a vector of length being the shorter of The result of this function is a vector of length being the shorter of
`this` and `that`, containing results of calling `function`. `this` and `that`, containing results of calling `function`.
> Example > Example
To pairwise-sum two vectors: To pairwise-sum two vectors:
[1, 2, 3].zip [4, 5, 6] (+) == [5, 7, 9] [1, 2, 3].zip [4, 5, 6] (+) == [5, 7, 9]
> Example
When the `function` is not provided, it defaults to creating a pair When the `function` is not provided, it defaults to creating a pair
of both elements: of both elements:
[1, 2, 3].zip [4, 5, 6] == [[1, 4], [2, 5], [3, 6]] [1, 2, 3].zip [4, 5, 6] == [[1, 4], [2, 5], [3, 6]]
@ -405,32 +495,41 @@ type Vector
here.new len i-> function (this.at i) (that.at i) here.new len i-> function (this.at i) (that.at i)
## Extend `this` vector to the length of `n` appending elements `elem` to ## Extend `this` vector to the length of `n` appending elements `elem` to
the end. If the new length `n` is less than existing length, `this` the end.
vector is returned.
Arguments:
- n: The length to pad `this` out to.
- elem: The element to fill the new padded slots with.
If the new length `n` is less than existing length, `this` vector is
returned.
> Example > Example
Extending vector to the length of 5 returns `[1, 2, 3, 0, 0]` Extending vector to the length of 5 returns `[1, 2, 3, 0, 0]`
[1, 2, 3].pad 5 0 [1, 2, 3].pad 5 0
> Example > Example
Extending vector to the length of 5 returns `[1, 2, 3, 4, 5]` Extending vector to the length of 5 returns `[1, 2, 3, 4, 5]`
[1, 2, 3, 4, 5].pad 5 0 [1, 2, 3, 4, 5].pad 5 0
pad : Integer -> Any -> Vector pad : Integer -> Any -> Vector
pad n elem = pad n elem =
if this.length >= n then this else if this.length >= n then this else
this + (here.fill n-this.length elem) this + (here.fill n-this.length elem)
## Vector to JSON conversion. ## Vector to JSON conversion.
> Example
Convert a vector of numbers to JSON.
[1, 2, 3].to_json
to_json : Json.Array to_json : Json.Array
to_json = Json.Array (this.map .to_json) to_json = Json.Array (this.map .to_json)
## Get the first element from the vector. ## Get the first element from the vector, or an error `Nothing` if the
vector is empty.
> Example > Example
The following code returns 1. The following code returns 1.
[1, 2, 3, 4].head [1, 2, 3, 4].head
> Example
Empty vectors return `Nothing`.
[].head == Nothing
head : Any ! Nothing head : Any ! Nothing
head = if this.length >= 1 then this.at 0 else Error.throw Nothing head = if this.length >= 1 then this.at 0 else Error.throw Nothing
@ -439,10 +538,6 @@ type Vector
> Example > Example
The following code returns [2, 3, 4]. The following code returns [2, 3, 4].
[1, 2, 3, 4].tail [1, 2, 3, 4].tail
> Example
Empty vectors return `Nothing`.
[].tail == Nothing
tail : Vector ! Nothing tail : Vector ! Nothing
tail = if this.length >= 1 then this.drop_start 1 else Error.throw Nothing tail = if this.length >= 1 then this.drop_start 1 else Error.throw Nothing
@ -451,38 +546,30 @@ type Vector
> Example > Example
The following code returns [1, 2, 3]. The following code returns [1, 2, 3].
[1, 2, 3, 4].init [1, 2, 3, 4].init
> Example
Empty vectors return `Nothing`.
[].init == Nothing
init : Vector ! Nothing init : Vector ! Nothing
init = if this.length >= 1 then this.drop_end 1 else Error.throw Nothing init = if this.length >= 1 then this.drop_end 1 else Error.throw Nothing
## Get the last element of the vector. ## Get the last element of the vector, or an error `Nothing` if the vector
is empty.
> Example > Example
The following code returns 4. The following code returns 4.
[1, 2, 3, 4].last [1, 2, 3, 4].last
> Example
Empty vectors return `Nothing`.
[].last == Nothing
last : Vector ! Nothing last : Vector ! Nothing
last = if this.length >= 1 then (this.take_end 1).at 0 else Error.throw Nothing last = if this.length >= 1 then (this.take_end 1).at 0 else Error.throw Nothing
## Get the first element from the vector. ## Get the first element from the vector, or an error `Nothing` if the
vector is empty.
> Example > Example
The following code returns 1. The following code returns 1.
[1, 2, 3, 4].first [1, 2, 3, 4].first
> Example
Empty vectors return `Nothing`.
[].first == Nothing
first : Vector ! Nothing first : Vector ! Nothing
first = this.head first = this.head
## Get the second element from the vector. ## Get the second element from the vector, or an error `Nothing` if the
vector doesn't have a second element.
Useful when tuples are implemented as vectors. Useful when tuples are implemented as vectors.
> Example > Example
@ -506,11 +593,11 @@ type Vector
## Sort the Vector. ## Sort the Vector.
Arguments: Arguments:
- `on`: A projection from the element type to the value of that element - on: A projection from the element type to the value of that element
being sorted on. being sorted on.
- `by`: A function that compares the result of applying `on` to two - by: A function that compares the result of applying `on` to two
elements, returning an Ordering to compare them. elements, returning an Ordering to compare them.
- `order`: The order in which the vector elements are sorted. - order: The order in which the vector elements are sorted.
By default, elements are sorted in ascending order, using the comparator By default, elements are sorted in ascending order, using the comparator
`compare_to`. A custom comparator may be passed to the sort function. `compare_to`. A custom comparator may be passed to the sort function.
@ -518,11 +605,12 @@ type Vector
This is a stable sort, meaning that items that compare the same will not This is a stable sort, meaning that items that compare the same will not
have their order changed by the sorting process. have their order changed by the sorting process.
The complexities for this sort are: ! Computational Complexity
- *Worst-Case Time:* `O(n * log n)` The complexities for this sort are:
- *Best-Case Time:* `O(n)` - *Worst-Case Time:* `O(n * log n)`
- *Average Time:* `O(n * log n)` - *Best-Case Time:* `O(n)`
- *Worst-Case Space:* `O(n)` additional - *Average Time:* `O(n * log n)`
- *Worst-Case Space:* `O(n)` additional
? Implementation Note ? Implementation Note
The sort implementation is based upon an adaptive, iterative mergesort The sort implementation is based upon an adaptive, iterative mergesort
@ -560,46 +648,69 @@ type Vector
Vector new_vec_arr Vector new_vec_arr
## Transform the vector into text for displaying as part of its default ## UNSTABLE
Transform the vector into text for displaying as part of its default
visualization. visualization.
to_default_visualization_data : Text to_default_visualization_data : Text
to_default_visualization_data = to_default_visualization_data =
json = this.take_start 100 . to_json json = this.take_start 100 . to_json
json.to_text json.to_text
## A builder type for Enso vectors.
A vector builder is a mutable data structure, that allows to gather a
number of elements and then convert them to a vector. This is
particularly useful when the number of elements is not known upfront.
> Example
In the following example we'll read items from the standard input,
until the string "end" is entered by the user and then return a vector
containing all items.
from Standard.Base import all
main =
builder = Vector.new_builder
do_read =
item = IO.readln
if item == "end" then Nothing else
builder.append item
do_read
do_read
vec = builder.to_vector
IO.println vec
type Builder type Builder
## A builder type for Enso vectors.
Arguments:
- to_array: The accumulator for the new vector.
- length: The current length of the vector being built.
A vector builder is a mutable data structure, that allows to gather a
number of elements and then convert them to a vector. This is
particularly useful when the number of elements is not known upfront.
> Example
In the following example we'll read items from the standard input,
until the string "end" is entered by the user and then return a vector
containing all items.
from Standard.Base import all
main =
builder = Vector.new_builder
do_read =
item = IO.readln
if item == "end" then Nothing else
builder.append item
do_read
do_read
vec = builder.to_vector
IO.println vec
type Builder to_array length type Builder to_array length
## Creates a new builder. ## Creates a new builder.
> Example
Make a new builder
Vector.new_builder
new : Builder
new = Builder (Array.new 1) 0 new = Builder (Array.new 1) 0
## Returns the current capacity (i.e. the size of the underlying storage) ## Returns the current capacity (i.e. the size of the underlying storage)
of this builder. of this builder.
> Example
Get the capacity of a new builder.
Vector.new_builder.capacity
capacity : Integer
capacity = this.to_array.length capacity = this.to_array.length
## Appends a new element into this builder. ## Appends a new element into this builder.
Arguments:
- item: The item to append to the vector builder.
> Example
Append an item to a vector builder.
Vector.new_builder.append 10
append : Any -> Nothing append : Any -> Nothing
append item = case this.capacity > this.length of append item = case this.capacity > this.length of
True -> True ->
@ -616,6 +727,14 @@ type Builder
Nothing Nothing
## Converts this builder to a vector containing all the appended elements. ## Converts this builder to a vector containing all the appended elements.
> Example
Use a builder to add elements to and then create a vector.
bldr = Vector.new_builder
bldr.append 1
bldr.append 10
bldr.append 100
bldr.to_vector
to_vector : Vector to_vector : Vector
to_vector = to_vector =
old_array = this.to_array old_array = this.to_array
@ -624,3 +743,19 @@ type Builder
new_array.set_at i (old_array.at i) new_array.set_at i (old_array.at i)
Nothing Nothing
Vector new_array Vector new_array
## UNSTABLE
An error for when an index is out of bounds in a vector.
Arguments:
- index: The requested index in the vector.
- length: The length of the vector.
type Index_Out_Of_Bounds_Error index length
## UNSTABLE
Pretty prints an index out of bounds error.
Index_Out_Of_Bounds_Error.to_display_text : Text
Index_Out_Of_Bounds_Error.to_display_text =
"The index " + this.index.to_text + " is out of bounds in a vector with length " + this.length.to_text + "."

View File

@ -1,32 +1,51 @@
from Standard.Base import all from Standard.Base import all
## Returns the method name of the method that could not be found. ## ADVANCED
UNSTABLE
Returns the method name of the method that could not be found.
No_Such_Method_Error.method_name : Text No_Such_Method_Error.method_name : Text
No_Such_Method_Error.method_name = No_Such_Method_Error.method_name =
Meta.meta this.symbol . name Meta.meta this.symbol . name
## A type used to represent that something has not yet been implemented. ## UNSTABLE
A type used to represent that something has not yet been implemented.
Arguments:
- message: The message describing what implementation is missing.
type Unimplemented_Error message type Unimplemented_Error message
## UNSTABLE
Converts the unimplemented error to a human-readable error message.
Unimplemented_Error.to_display_text : Text
Unimplemented_Error.to_display_text = "An implementation is missing: " + this.message
## A function that can be used to indicate that something hasn't been ## A function that can be used to indicate that something hasn't been
implemented yet. implemented yet.
Arguments:
- message: A description of what implementation is missing.
unimplemented : Text -> Void unimplemented : Text -> Void
unimplemented message="" = Panic.throw (Unimplemented_Error message) unimplemented message="" = Panic.throw (Unimplemented_Error message)
## Executes the provided handler on a dataflow error, or executes as identity on ## Executes the provided handler on a dataflow error, or returns a non-error
a non-error value. value unchanged.
Arguments: Arguments:
- handler: The function to call on this if it is an error value. By default - handler: The function to call on this if it is an error value. By default
this is identity. this is identity.
> Example > Example
Catching an erroneous value to perform some operation on it. Catching an erroneous value and getting the length of its message.
(Time.Time_Error "Message").catch (err -> IO.println err) (Time.Time_Error "Message").catch (err -> err.error_message.length)
Error.catch : (Error -> Any) -> Any Error.catch : (Error -> Any) -> Any
Error.catch (handler = x->x) = this.catch_primitive handler Error.catch (handler = x->x) = this.catch_primitive handler
## Returns a display representation of the dataflow error on which it is called. ## UNSTABLE
Returns a display representation of the dataflow error on which it is called.
> Example > Example
Displaying a dataflow error. Displaying a dataflow error.
@ -34,16 +53,19 @@ Error.catch (handler = x->x) = this.catch_primitive handler
Error.to_default_visualization_data : Text Error.to_default_visualization_data : Text
Error.to_default_visualization_data = this.catch .to_default_visualization_data Error.to_default_visualization_data = this.catch .to_default_visualization_data
## Returns a human-readable text representing this error. ## UNSTABLE
Returns a human-readable text representing this error.
Error.to_display_text : Text Error.to_display_text : Text
Error.to_display_text = "Error: " + (this.catch .to_display_text) Error.to_display_text = "Error: " + (this.catch .to_display_text)
## Maps a dataflow error. ## Transforms an error.
If the original value was a non-error value, it is not affected, but if it
was an error, the error is mapped through the provided function.
Arguments: Arguments:
- f: The function to transform the error. - 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 > Example
Wrapping an error value. Wrapping an error value.
@ -51,11 +73,23 @@ Error.to_display_text = "Error: " + (this.catch .to_display_text)
Error.map_error : (Error -> Error) -> Any Error.map_error : (Error -> Error) -> Any
Error.map_error f = this.catch (x -> Error.throw (f x)) Error.map_error f = this.catch (x -> Error.throw (f x))
## Checks if the underlying value is an error. ## Checks if `this` is an error.
> Example
Checking if the value 1 is an error.
1.is_error
Error.is_error : Boolean Error.is_error : Boolean
Error.is_error = True Error.is_error = True
## Takes any value, and if it is a dataflow error, throws it as a Panic. ## Takes any value, and if it is a dataflow error, throws it as a Panic,
Otherwise, returns the original value unchanged. otherwise, returns the original value unchanged.
Arguments:
- value: The value to rethrow any errors on as a panic.
> Example
Rethrowing a dataflow error as a panic.
Panic.rethrow (Error.throw "Oh, no!")
Panic.rethrow : (Any ! Any) -> Any Panic.rethrow : (Any ! Any) -> Any
Panic.rethrow value = value.catch Panic.throw Panic.rethrow value = value.catch Panic.throw

View File

@ -18,9 +18,35 @@ e : Decimal
e = 2.718281828459045235360 e = 2.718281828459045235360
## Returns the smaller value of `a` and `b`. ## Returns the smaller value of `a` and `b`.
Arguments:
- a: The first number.
- b: The second number.
? Math.min or Number.min
While we provide the min method on `Number`, we find it more intuitive to
write `Math.min a b` rather than `a.min b`. To that end, we recommend using
the first style.
> Example
Calculate the smallest number out of 1 and 2.
Math.min 1 2
min : Number -> Number -> Number min : Number -> Number -> Number
min a b = if a <= b then a else b min a b = if a <= b then a else b
## Returns the larger value of `a` and `b`. ## Returns the larger value of `a` and `b`.
Arguments:
- a: The first number.
- b: The second number.
? Math.max or Number.max
While we provide the max method on `Number`, we find it more intuitive to
write `Math.max a b` rather than `a.max b`. To that end, we recommend using
the first style.
> Example
Calculate the largest number out of 1 and 2.
Math.max 1 2
max : Number -> Number -> Number max : Number -> Number -> Number
max a b = if a < b then b else a max a b = if a < b then b else a

View File

@ -2,91 +2,80 @@ from Standard.Base import all
import Builtins import Builtins
## Represents a polyglot language. ## UNSTABLE
type Language ADVANCED
## The Java laguage.
type Java
## Unknown language.
type Unknown
## A meta-representation of a runtime value. Returns a meta-representation of a given runtime entity.
! Warning Arguments:
The functionality contained in this module exposes certain implementation - value: The runtime entity to get the meta representation of.
details of the language. As such, the API has no stability guarantees and meta : Any -> Meta
is subject to change as the Enso interpreter evolves. meta value = if Builtins.Meta.is_atom value then Atom value else
type Meta if Builtins.Meta.is_constructor value then Constructor value else
## An Atom meta-representation. if Builtins.Meta.is_polyglot value then Polyglot value else
type Atom value if Builtins.Meta.is_unresolved_symbol value then Unresolved_Symbol value else
## A constructor meta-representation. if Builtins.Meta.is_error value then Error value.catch else
type Constructor value Primitive value
## A primitive value meta-prepresentation.
type Primitive value
## An unresolved symbol meta-representation.
type Unresolved_Symbol value
## An error meta-representation, containing the payload of a dataflow error.
type Error value
## A polyglot value meta-representation.
type Polyglot value
## Returns a vector of field values of the given atom. ## UNSTABLE
Atom.fields : Vector.Vector ADVANCED
Atom.fields = Vector.Vector (Builtins.Meta.get_atom_fields this.value)
## Returns a constructor value of the given atom. Checks whether two objects are represented by the same underlying reference.
Atom.constructor : Any
Atom.constructor = Builtins.Meta.get_atom_constructor this.value
## Returns a new unresolved symbol with its name changed to the provided Arguments:
argument. - value_1: The first value.
Unresolved_Symbol.rename : Text -> Any - value_2: The second value.
Unresolved_Symbol.rename new_name = is_same_object : Any -> Any -> Boolean
Builtins.Meta.create_unresolved_symbol new_name this.scope is_same_object value_1 value_2 = Builtins.Meta.is_same_object value_1 value_2
## Returns the name of an unresolved symbol. ## UNSTABLE
Unresolved_Symbol.name : Text ADVANCED
Unresolved_Symbol.name = Builtins.Meta.get_unresolved_symbol_name this.value
## Returns the definition scope of an unresolved symbol. Checks if `this` is an instance of `typ`.
Unresolved_Symbol.scope : Any
Unresolved_Symbol.scope = Builtins.Meta.get_unresolved_symbol_scope this.value
## Returns a vector of field names defined by a constructor. Arguments:
Constructor.fields : Vector.Vector - typ: The type to check `this` against.
Constructor.fields = Vector.Vector (Builtins.Meta.get_constructor_fields this.value)
## Returns the name of a constructor.
Constructor.name : Text
Constructor.name = Builtins.Meta.get_constructor_name this.value
## Creates a new atom of the given constructor, with field values provided
in the `fields` vector.
Constructor.new : Vector.Vector -> Any
Constructor.new fields = Builtins.Meta.new_atom this.value fields.to_array
## Returns the language of a polyglot value.
Polyglot.get_language : Language
Polyglot.get_language =
lang_str = Builtins.Meta.get_polyglot_language
if lang_str == "java" then Java else Unknown
## Checks if `this` is an instance of `typ`.
Any.is_a : Any -> Boolean Any.is_a : Any -> Boolean
Any.is_a typ = here.is_a this typ Any.is_a typ = here.is_a this typ
## Checks if `this` is an instance of `typ`. ## UNSTABLE
ADVANCED
Checks if `this` is an instance of `typ`.
Arguments:
- typ: The type to check `this` against.
Any.is_an : Any -> Boolean Any.is_an : Any -> Boolean
Any.is_an typ = here.is_a this typ Any.is_an typ = here.is_a this typ
## Checks if `this` is an instance of `typ`. ## UNSTABLE
ADVANCED
Checks if `this` is an instance of `typ`.
Arguments:
- typ: The type to check `this` against.
Base.Error.is_a : Any -> Boolean Base.Error.is_a : Any -> Boolean
Base.Error.is_a typ = this.is_an typ Base.Error.is_a typ = this.is_an typ
## Checks if `this` is an instance of `typ`. ## UNSTABLE
ADVANCED
Checks if `this` is an instance of `typ`.
Arguments:
- typ: The type to check `this` against.
Base.Error.is_an : Any -> Boolean Base.Error.is_an : Any -> Boolean
Base.Error.is_an typ = typ == Base.Error Base.Error.is_an typ = typ == Base.Error
## Checks if `value` is an instance of `typ`. ## UNSTABLE
ADVANCED
Checks if `value` is an instance of `typ`.
Arguments:
- value: The value to check for being an instance of `typ`.
- typ: The type to check `this` against.
is_a : Any -> Any -> Boolean is_a : Any -> Any -> Boolean
is_a value typ = if typ == Any then True else is_a value typ = if typ == Any then True else
if Builtins.Meta.is_error value then typ == Base.Error else if Builtins.Meta.is_error value then typ == Base.Error else
@ -113,23 +102,170 @@ is_a value typ = if typ == Any then True else
Unresolved_Symbol _ -> typ == Unresolved_Symbol Unresolved_Symbol _ -> typ == Unresolved_Symbol
_ -> False _ -> False
## Checks if `value` is an instance of `typ`. ## UNSTABLE
ADVANCED
Checks if `value` is an instance of `typ`.
Arguments:
- value: The value to check for being an instance of `typ`.
- typ: The type to check `this` against.
is_an : Any -> Any -> Boolean is_an : Any -> Any -> Boolean
is_an value typ = here.is_a value typ is_an value typ = here.is_a value typ
## Returns a meta-representation of a given runtime entity. ## Represents a polyglot language.
meta : Any -> Meta type Language
meta value = if Builtins.Meta.is_atom value then Atom value else
if Builtins.Meta.is_constructor value then Constructor value else
if Builtins.Meta.is_polyglot value then Polyglot value else
if Builtins.Meta.is_unresolved_symbol value then Unresolved_Symbol value else
if Builtins.Meta.is_error value then Error value.catch else
Primitive value
## Checks whether two objects are represented by the same underlying reference. ## UNSTABLE
This is a power-user feature, that is only useful for certain optimizations. ADVANCED
is_same_object : Any -> Any -> Boolean
is_same_object value_1 value_2 = Builtins.Meta.is_same_object value_1 value_2 The Java laguage.
type Java
## UNSTABLE
ADVANCED
An unknown language.
type Unknown
## UNSTABLE
ADVANCED
A meta-representation of a runtime value.
! Warning
The functionality contained in this module exposes certain implementation
details of the language. As such, the API has no stability guarantees and
is subject to change as the Enso interpreter evolves.
type Meta
## UNSTABLE
ADVANCED
An Atom meta-representation.
Arguments:
- value: The value of the atom in the meta representation.
type Atom value
## UNSTABLE
ADVANCED
A constructor meta-representation.
Arguments:
- value: The value of the constructor in the meta representation.
type Constructor value
## UNSTABLE
ADVANCED
A primitive value meta-prepresentation.
Arguments:
- value: The value of the primitive object in the meta representation.
type Primitive value
## UNSTABLE
ADVANCED
An unresolved symbol meta-representation.
Arguments:
- value: The value of the unresolved symbol in the meta representation.
type Unresolved_Symbol value
## UNSTABLE
ADVANCED
An error meta-representation, containing the payload of a dataflow error.
Arguments:
- value: The payload of the error.
type Error value
## UNSTABLE
ADVANCED
A polyglot value meta-representation.
Arguments:
- value: The polyglot value contained in the meta representation.
type Polyglot value
## UNSTABLE
ADVANCED
Returns a vector of field values of the given atom.
Atom.fields : Vector.Vector
Atom.fields = Vector.Vector (Builtins.Meta.get_atom_fields this.value)
## UNSTABLE
ADVANCED
Returns a constructor value of the given atom.
Atom.constructor : Any
Atom.constructor = Builtins.Meta.get_atom_constructor this.value
## UNSTABLE
ADVANCED
Returns a new unresolved symbol with its name changed to the provided
argument.
Arguments:
- new_name: The new name for the unresolved symbol.
Unresolved_Symbol.rename : Text -> Any
Unresolved_Symbol.rename new_name =
Builtins.Meta.create_unresolved_symbol new_name this.scope
## UNSTABLE
ADVANCED
Returns the name of an unresolved symbol.
Unresolved_Symbol.name : Text
Unresolved_Symbol.name = Builtins.Meta.get_unresolved_symbol_name this.value
## UNSTABLE
ADVANCED
Returns the definition scope of an unresolved symbol.
Unresolved_Symbol.scope : Any
Unresolved_Symbol.scope = Builtins.Meta.get_unresolved_symbol_scope this.value
## UNSTABLE
ADVANCED
Returns a vector of field names defined by a constructor.
Constructor.fields : Vector.Vector
Constructor.fields = Vector.Vector (Builtins.Meta.get_constructor_fields this.value)
## UNSTABLE
ADVANCED
Returns the name of a constructor.
Constructor.name : Text
Constructor.name = Builtins.Meta.get_constructor_name this.value
## UNSTABLE
ADVANCED
Creates a new atom of the given constructor.
Arguments:
- fields: A vector of arguments to pass to the constructor when creating the
new atom.
Constructor.new : Vector.Vector -> Any
Constructor.new fields = Builtins.Meta.new_atom this.value fields.to_array
## UNSTABLE
ADVANCED
Returns the language with which a polyglot value is associated.
Polyglot.get_language : Language
Polyglot.get_language =
lang_str = Builtins.Meta.get_polyglot_language
if lang_str == "java" then Java else Unknown
## PRIVATE ## PRIVATE

View File

@ -3,9 +3,17 @@ from Standard.Base import all
import Builtins import Builtins
## Returns the root directory of the project. ## Returns the root directory of the project.
> Example
Get the root directory of the current project.
Enso_Project.root
Builtins.Project_Description.root : File.File Builtins.Project_Description.root : File.File
Builtins.Project_Description.root = File.File this.prim_root_file Builtins.Project_Description.root = File.File this.prim_root_file
## Returns the root data directory of the project. ## Returns the root data directory of the project.
> Example
Get the data directory of the current project.
Enso_Project.data
Builtins.Project_Description.data : File.File Builtins.Project_Description.data : File.File
Builtins.Project_Description.data = this.root / "data" Builtins.Project_Description.data = this.root / "data"

View File

@ -24,18 +24,180 @@ polyglot java import java.net.URI
polyglot java import java.time.Duration as Java_Duration polyglot java import java.time.Duration as Java_Duration
polyglot java import org.enso.base.Http_Utils polyglot java import org.enso.base.Http_Utils
## An error when sending an Http request. ## UNSTABLE
An error when sending an Http request.
Arguments:
- message: The message for the error.
type Request_Error message type Request_Error message
## UNSTABLE
Convert a request error to a human-readable form.
Request_Error.to_display_text = Request_Error.to_display_text =
"Error when sending request: " + this.message "Error when sending request: " + this.message
## Create a new instance of the HTTP client.
Arguments:
- timeout: The length of time the client will wait for responses.
- follow_redirects: Whether or not the client should follow redirects.
- proxy: The proxy that the client should use, if any.
- version: The HTTP version supported by the client.
> Example
Create an HTTP client with default settings.
Http.new
> Example
Create an HTTP client with extended timeout.
Http.new timeout=30.seconds
> Example
Create an HTTP client with extended timeout and proxy settings.
Http.new (timeout = 30.seconds) (proxy = Proxy.new "example.com" 8080)
new : Duration -> Boolean -> Proxy -> Http
new (timeout = 10.seconds) (follow_redirects = True) (proxy = Proxy.System) (version = Version.Http_1_1) =
Http timeout follow_redirects proxy version
## Send an Options request.
Arguments:
- uri: The address to which the request will be sent.
- headers: Any headers for the options request.
> Example
Send an Options request.
Http.options "http://httpbin.org"
options : (Text | Uri) -> Vector.Vector -> Response ! Request_Error
options uri (headers = []) = here.new.options uri headers
## Send a Get request.
Arguments:
- uri: The address to which the request will be sent.
- headers: Any headers for the options request.
> Example
Send a Get request.
Http.get "http://httpbin.org/get"
> Example
Send authenticated Get request (note the use of TLS).
Http.get "https://httpbin.org/basic-auth/user/pass" [Header.authorization_basic "user" "pass"]
> Example
Download a file.
out_file = File.new "/tmp/out.bin"
res = Http.get "http://httpbin.org/bytes/1024"
res.body.to_file out_file
get : (Text | Uri) -> Vector.Vector -> Response ! Request_Error
get uri (headers = []) = here.new.get uri headers
## Send the Get request and return the body.
Arguments:
- uri: The address to which the request will be sent.
- headers: Any headers for the options request.
> Example
Send a Get request.
Http.fetch "http://httpbin.org/get"
> Example
Send authenticated Get request (note the use of TLS).
Http.fetch "https://httpbin.org/basic-auth/user/pass" [Header.authorization_basic "user" "pass"]
> Example
Download a file.
out_file = File.new "/tmp/out.bin"
res = Http.fetch "http://httpbin.org/bytes/1024" . to_file out_file
fetch : (Text | Uri) -> Vector.Vector -> Response ! Request_Error
fetch uri (headers = []) =
here.new.get uri headers . body
## Send a Head request.
Arguments:
- uri: The address to which the request will be sent.
- headers: Any headers for the options request.
> Example
Send a Head request.
res = Http.head "http://httpbin.org"
IO.println res.headers
head : (Text | Uri) -> Vector.Vector -> Response ! Request_Error
head uri (headers = []) = here.new.options uri headers
## Send a Post request.
Arguments:
- uri: The address to which the request will be sent.
- body: The contents of the post request.
- headers: Any headers for the options request.
> Example
Send a Post request with binary data.
body = Body.Bytes "Hello".utf_8
header_binary = Header.content_type "application/octet-stream"
Http.post "http://httpbin.org/post" body [header_binary]
post : (Text | Uri) -> Request_Body -> Vector.Vector -> Respoonse ! Request_Error
post uri body (headers = []) = here.new.post uri body headers
## Send a Post request with the form. By default it will be encoded as
"application/x-www-form-urlencoded". To encode the form as
"multipart/form-data" add the appropriate header.
Arguments:
- uri: The address to which the request will be sent.
- parts: A form, or a vector of parts for creating a form.
- headers: Any headers for the options request.
> Example
Send a Post request with form.
form = [Form.text_field "name" "John Doe", Form.file_field "license.txt" (Enso_Project.root / "LICENSE")]
Http.post_form "http://httpbin.org/post" form
> Example
Send a Post request with form encoded as "multipart/form-data".
form = [Form.text_field "name" "John Doe", Form.file_field "license.txt" (Enso_Project.root / "LICENSE")]
Http.post_form "http://httpbin.org/post" form [Header.multipart_form_data]
post_form : (Text | Uri) -> (Vector | Form) -> Vector.Vector -> Response ! Request_Error
post_form uri parts (headers = []) = here.new.post_form uri parts headers
## Send a Post request with body with content-type "application/json".
Arguments:
- uri: The address to which the request will be sent.
- body_json: The json for the body.
- headers: Any headers for the options request.
> Example
Send a Post request with json data.
json = Json.parse <| '''
{"key":"val"}
Http.post_json "http://httpbin.org/post" json
post_json : (Text | Uri) -> Json -> Vector.Vector -> Response ! Request_Error
post_json uri body_json (headers = []) = here.new.post_json uri body_json headers
type Http type Http
## An HTTP client.
Arguments:
- timeout: The length of time the client will wait for responses.
- follow_redirects: Whether or not the client should follow redirects.
- proxy: The proxy that the client should use, if any.
- version: The HTTP version supported by the client.
type Http timeout follow_redirects proxy version type Http timeout follow_redirects proxy version
## Send an Options request. ## Send an Options request.
Arguments:
- uri: The address to which the request will be sent.
- headers: Any headers for the options request.
> Example > Example
Send an Options request. Send an Options request.
Http.new.options "http://httpbin.org" Http.new.options "http://httpbin.org"
@ -46,6 +208,10 @@ type Http
## Send a Get request. ## Send a Get request.
Arguments:
- uri: The address to which the request will be sent.
- headers: Any headers for the options request.
> Example > Example
Send a Get request. Send a Get request.
Http.new.get "http://httpbin.org/get" Http.new.get "http://httpbin.org/get"
@ -66,6 +232,10 @@ type Http
## Send a Head request. ## Send a Head request.
Arguments:
- uri: The address to which the request will be sent.
- headers: Any headers for the options request.
> Example > Example
Send a Head request. Send a Head request.
res = Http.new.head "http://httpbin.org" res = Http.new.head "http://httpbin.org"
@ -77,6 +247,11 @@ type Http
## Send a Post request. ## Send a Post request.
Arguments:
- uri: The address to which the request will be sent.
- body: The body of the post request.
- headers: Any headers for the options request.
> Example > Example
Send a Post request with binary data. Send a Post request with binary data.
body = Body.Bytes "Hello".utf_8 body = Body.Bytes "Hello".utf_8
@ -91,6 +266,11 @@ type Http
"application/x-www-form-urlencoded". To encode the form as "application/x-www-form-urlencoded". To encode the form as
"multipart/form-data" add the appropriate header. "multipart/form-data" add the appropriate header.
Arguments:
- uri: The address to which the request will be sent.
- parts: A form, or the parts for creating a form.
- headers: Any headers for the options request.
> Example > Example
Send a Post request with form. Send a Post request with form.
form = [Form.text_field "name" "John Doe", Form.file_field "license.txt" (Enso_Project.root / "LICENSE")] form = [Form.text_field "name" "John Doe", Form.file_field "license.txt" (Enso_Project.root / "LICENSE")]
@ -114,6 +294,11 @@ type Http
## Send a Post request with body with content-type "application/json". ## Send a Post request with body with content-type "application/json".
Arguments:
- uri: The address to which the request will be sent.
- body_json: The JSON body for the post request.
- headers: Any headers for the options request.
> Example > Example
Send a Post request with json data. Send a Post request with json data.
json = Json.parse <| ''' json = Json.parse <| '''
@ -127,6 +312,11 @@ type Http
## Send a Put request. ## Send a Put request.
Arguments:
- uri: The address to which the request will be sent.
- body: The body for the put request.
- headers: Any headers for the options request.
> Example > Example
Send a Put request with binary data. Send a Put request with binary data.
body = Body.Bytes "contents".utf_8 body = Body.Bytes "contents".utf_8
@ -139,6 +329,11 @@ type Http
## Send a Put request with body with content-type "application/json". ## Send a Put request with body with content-type "application/json".
Arguments:
- uri: The address to which the request will be sent.
- body_json: The JSON for the body of the put request.
- headers: Any headers for the options request.
> Example > Example
Send a Put request with json data. Send a Put request with json data.
json = Json.parse <| ''' json = Json.parse <| '''
@ -152,6 +347,10 @@ type Http
## Create a Delete request. ## Create a Delete request.
Arguments:
- uri: The address to which the request will be sent.
- headers: Any headers for the options request.
> Example > Example
Send a Delete request. Send a Delete request.
Http.new.delete "http://httpbin.org/delete" Http.new.delete "http://httpbin.org/delete"
@ -162,6 +361,9 @@ type Http
## Create a request ## Create a request
Arguments:
- req: The HTTP request to send using `this` HTTP client.
> Example > Example
Send a Get request with headers. Send a Get request with headers.
req = Request.new Method.Get "http://httpbin.org/get" . with_header "X-Trace-Id" "00000" req = Request.new Method.Get "http://httpbin.org/get" . with_header "X-Trace-Id" "00000"
@ -282,109 +484,3 @@ type Http
builder.version HttpClient.Version.HTTP_2 builder.version HttpClient.Version.HTTP_2
# build http client # build http client
builder.build builder.build
## Create a new instance of HTTP client.
> Example
Create an HTTP client with default settings.
Http.new
> Example
Create an HTTP client with extended timeout.
Http.new timeout=30.seconds
> Example
Create an HTTP client with extended timeout and proxy settings.
Http.new (timeout = 30.seconds) (proxy = Proxy.new "example.com" 8080)
new : Duration -> Boolean -> Proxy -> Http
new (timeout = 10.seconds) (follow_redirects = True) (proxy = Proxy.System) (version = Version.Http_1_1) =
Http timeout follow_redirects proxy version
## Send an Options request.
> Example
Send an Options request.
Http.options "http://httpbin.org"
options : (Text | Uri) -> Vector.Vector -> Response ! Request_Error
options uri (headers = []) = here.new.options uri headers
## Send a Get request.
> Example
Send a Get request.
Http.get "http://httpbin.org/get"
> Example
Send authenticated Get request (note the use of TLS).
Http.get "https://httpbin.org/basic-auth/user/pass" [Header.authorization_basic "user" "pass"]
> Example
Download a file.
out_file = File.new "/tmp/out.bin"
res = Http.get "http://httpbin.org/bytes/1024"
res.body.to_file out_file
get : (Text | Uri) -> Vector.Vector -> Response ! Request_Error
get uri (headers = []) = here.new.get uri headers
## Send the Get request and return the body.
> Example
Send a Get request.
Http.fetch "http://httpbin.org/get"
> Example
Send authenticated Get request (note the use of TLS).
Http.fetch "https://httpbin.org/basic-auth/user/pass" [Header.authorization_basic "user" "pass"]
> Example
Download a file.
out_file = File.new "/tmp/out.bin"
res = Http.fetch "http://httpbin.org/bytes/1024" . to_file out_file
fetch : (Text | Uri) -> Vector.Vector -> Response ! Request_Error
fetch uri (headers = []) =
here.new.get uri headers . body
## Send a Head request.
> Example
Send a Head request.
res = Http.head "http://httpbin.org"
IO.println res.headers
head : (Text | Uri) -> Vector.Vector -> Response ! Request_Error
head uri (headers = []) = here.new.options uri headers
## Send a Post request.
> Example
Send a Post request with binary data.
body = Body.Bytes "Hello".utf_8
header_binary = Header.content_type "application/octet-stream"
Http.post "http://httpbin.org/post" body [header_binary]
post : (Text | Uri) -> Request_Body -> Vector.Vector -> Respoonse ! Request_Error
post uri body (headers = []) = here.new.post uri body headers
## Send a Post request with the form. By default it will be encoded as
"application/x-www-form-urlencoded". To encode the form as
"multipart/form-data" add the appropriate header.
> Example
Send a Post request with form.
form = [Form.text_field "name" "John Doe", Form.file_field "license.txt" (Enso_Project.root / "LICENSE")]
Http.post_form "http://httpbin.org/post" form
> Example
Send a Post request with form encoded as "multipart/form-data".
form = [Form.text_field "name" "John Doe", Form.file_field "license.txt" (Enso_Project.root / "LICENSE")]
Http.post_form "http://httpbin.org/post" form [Header.multipart_form_data]
post_form : (Text | Uri) -> (Vector | Form) -> Vector.Vector -> Response ! Request_Error
post_form uri parts (headers = []) = here.new.post_form uri parts headers
## Send a Post request with body with content-type "application/json".
> Example
Send a Post request with json data.
json = Json.parse <| '''
{"key":"val"}
Http.post_json "http://httpbin.org/post" json
post_json : (Text | Uri) -> Json -> Vector.Vector -> Response ! Request_Error
post_json uri body_json (headers = []) = here.new.post_json uri body_json headers

View File

@ -5,9 +5,19 @@ import Standard.Base.Data.Vector
## The HTTP form containing a vector of parts. ## The HTTP form containing a vector of parts.
type Form type Form
## PRIVATE
A type representing form data.
Arguments:
- parts: A vector of form segments.
type Form parts type Form parts
## Convert this to a Form. ## Convert this to a Form.
> Example
Convert to a form.
Form.new [Part "foo" (Part_Text "bar")] . to_form
to_form : Form to_form : Form
to_form = this to_form = this
@ -17,25 +27,62 @@ Vector.Vector.to_form = Form this
## The key-value element of the form. ## The key-value element of the form.
type Part type Part
## A form part.
Arguments:
- key: The key for the form section.
- value: The value of the form section.
type Part key value type Part key value
## The value of the form element. ## The value of the form element.
type Part_Value type Part_Value
## A textual value for a form part.
Arguments:
- part_text: The text for the form part.
type Part_Text part_text type Part_Text part_text
## A file value for a form part.
Arguments:
- part_file: The file for the form part.
type Part_File part_file type Part_File part_file
## Create Form data from Parts. ## Create Form data from Parts.
Arguments:
- parts: A vector of parts to make up the form.
> Example
Create a new form
Form.new (Form.text_field "foo" "bar")
new : Vector.Vector -> Form new : Vector.Vector -> Form
new parts = Form parts new parts = Form parts
# Helpers for creating different parts of the form. # Helpers for creating different parts of the form.
## Create a text field of a Form. ## Create a text field of a Form.
Arguments:
- key: The key for the field in the form.
- val: The text for the textual field.
> Example
Create a textual form field.
Form.text_field "Foo" "bar"
text_field : Text -> Text -> Part text_field : Text -> Text -> Part
text_field key val = Part key (Part_Text val) text_field key val = Part key (Part_Text val)
## Create a file field of a Form. ## Create a file field of a Form.
Arguments:
- key: The key for the field in the form.
- file: The textual file contents.
> Example
Create a file form field.
Form.file_field "Foo" "My file contents"
file_field : Text -> Text -> Part file_field : Text -> Text -> Part
file_field key file = Part key (Part_File file) file_field key file = Part key (Part_File file)

View File

@ -4,34 +4,78 @@ polyglot java import org.enso.base.Http_Utils
type Header type Header
## PRIVATE
A type representing a header.
Arguments:
- name: The header name.
- value: The header value.
type Header name value type Header name value
## Header equality. ## Header equality.
Arguments:
- that: The header to compare against.
> Example
Compare two headers.
(Header.new "My_Header" "foo") == (Header.new "My_Header" "bar")
== : Header -> Boolean == : Header -> Boolean
== that = (this.name.equals_ignore_case that.name) && this.value==that.value == that = (this.name.equals_ignore_case that.name) && this.value==that.value
## Create a new Header. ## Create a new Header.
Arguments:
- name: The name of the header.
- value: The value for the header.
> Example
Create a new header called "My_Header".
Header.new "My_Header" "my header's value"
new : Text -> Text -> Header new : Text -> Text -> Header
new name value = Header name value new name value = Header name value
# Accept # Accept
## Create "Accept" header. ## Create an "Accept" header.
Arguments:
- value: The value for the accept header.
> Example
Create an accept header.
Header.accept "my_field"
accept : Text -> Header accept : Text -> Header
accept value = Header "Accept" value accept value = Header "Accept" value
## Header "Accept: */*". ## Create a header that accepts all (`"*/*"`).
> Example
Create an accept all header.
Header.accept_all
accept_all : Header accept_all : Header
accept_all = here.accept "*/*" accept_all = here.accept "*/*"
# Authorization # Authorization
## Create "Authorization" header. ## Create "Authorization" header.
Arguments:
- value: The value for the authorization header.
> Example
Create an auth header containing "foo".
Header.authorization "foo"
authorization : Text -> Header authorization : Text -> Header
authorization value = Header "Authorization" value authorization value = Header "Authorization" value
## Create HTTP basic auth header. ## Create HTTP basic auth header.
Arguments:
- user: The username.
- pass: The password.
> Example > Example
Create basic auth header. Create basic auth header.
Header.authorization_basic "user" "pass" Header.authorization_basic "user" "pass"
@ -42,27 +86,57 @@ authorization_basic user pass =
# Content-Type # Content-Type
## Create "Content-Type" header. ## Create "Content-Type" header.
Arguments:
- value: The value for the content type header.
> Example
Create a content type header containing "my_type".
Header.content_type "my_type"
content_type : Text -> Header content_type : Text -> Header
content_type value = Header "Content-Type" value content_type value = Header "Content-Type" value
## Header "Content-Type: application/json". ## Header "Content-Type: application/json".
> Example
Create a header with content type "application/json".
Header.application_json
application_json : Header application_json : Header
application_json = here.content_type "application/json" application_json = here.content_type "application/json"
## Header "Content-Type: application/octet-stream". ## Header "Content-Type: application/octet-stream".
> Example
Create a header with content type "application/octet-stream".
Header.application_octet_stream
application_octet_stream : Header application_octet_stream : Header
application_octet_stream = here.content_type "application/octet-stream" application_octet_stream = here.content_type "application/octet-stream"
## Header "Content-Type: application/x-www-form-urlencoded". ## Header "Content-Type: application/x-www-form-urlencoded".
> Example
Create a header with content type "application/x-www-form-urlencoded".
Header.application_x_www_form_urlencoded
application_x_www_form_urlencoded : Header application_x_www_form_urlencoded : Header
application_x_www_form_urlencoded = here.content_type "application/x-www-form-urlencoded" application_x_www_form_urlencoded = here.content_type "application/x-www-form-urlencoded"
## Header "Content-Type: multipart/form-data". ## Header "Content-Type: multipart/form-data".
Arguments:
- boundary: The text that delimits boundaries between the parts of the form.
> Example
Create a header with content type "multipart/form-data".
Header.multipart_form_data
multipart_form_data : Text -> Header multipart_form_data : Text -> Header
multipart_form_data (boundary = "") = multipart_form_data (boundary = "") =
if boundary == "" then here.content_type "multipart/form-data" else if boundary == "" then here.content_type "multipart/form-data" else
here.content_type ("multipart/form-data; boundary=" + boundary) here.content_type ("multipart/form-data; boundary=" + boundary)
## Header "Content-Type: text/plain". ## Header "Content-Type: text/plain".
> Example
Create a header with the content type "text/plain".
Header.text_plain
text_plain : Header text_plain : Header
text_plain = here.content_type "text/plain" text_plain = here.content_type "text/plain"

View File

@ -1,10 +1,25 @@
type Method type Method
## The HTTP method "OPTIONS".
type Options type Options
## The HTTP method "GET".
type Get type Get
## The HTTP method "HEAD".
type Head type Head
## The HTTP method "POST".
type Post type Post
## The HTTP method "PUT".
type Put type Put
## The HTTP method "DELETE".
type Delete type Delete
## The HTTP method "TRACE".
type Trace type Trace
## The HTTP method "CONNECT".
type Connect type Connect

View File

@ -10,11 +10,115 @@ import Standard.Base.System.File
polyglot java import org.enso.base.Text_Utils polyglot java import org.enso.base.Text_Utils
## Create new HTTP request.
Arguments:
- method: The HTTP method represented by the request.
- addr: The address for the request.
- headers: A vector containing headers for the request.
- body: The body of the request.
> Example
Create a new post request with no headers and no body.
Request.new Method.Post (Uri.parse "http://example.com")
new : Method -> (Text | Uri) -> Vector.Vector -> Request_Body -> Request
new method addr (headers = []) (body = Request_Body.Empty) =
Panic.recover (Request method (Internal.panic_on_error (addr.to_uri)) headers body) . catch Internal.recover_panic
## Create an Options request.
Arguments:
> Example
Create a new options request.
Request.options (Uri.parse "http://example.com")
options : (Text | Uri) -> Vector.Vector -> Request
options addr (headers = []) = here.new Method.Options addr headers
## Create a Get request.
Arguments:
- addr: The address for the request.
- headers: A vector containing headers for the request.
> Example
Create a new get request.
Request.get (Uri.parse "http://example.com")
get : (Text | Uri) -> Vector.Vector -> Request
get addr (headers = []) = here.new Method.Get addr headers
## Create a Head request.
Arguments:
- addr: The address for the request.
- headers: A vector containing headers for the request.
> Example
Create a new head request.
Request.head (Uri.parse "http://example.com")
head : (Text | Uri) -> Vector.Vector -> Request
head addr (headers = []) = here.new Method.Head addr headers
## Create a Post request.
Arguments:
- addr: The address for the request.
- body: The body for the request.
- headers: A vector containing headers for the request.
> Example
Create a new post request.
Request.post (Uri.parse "http://example.com") Request_Body.Empty
post : (Text | Uri) -> Request_Body -> Vector.Vector -> Request
post addr body (headers = []) = here.new Method.Post addr headers body
## Create a Put request.
Arguments:
- addr: The address for the request.
- body: The body for the request.
- headers: A vector containing headers for the request.
> Example
Create a new put request.
Request.put (Uri.parse "http://example.com") Request_Body.Empty
put : (Text | Uri) -> Request_Body -> Vector.Vector -> Request
put addr body (headers = []) = here.new Method.Put addr headers body
## Create a Delete request.
Arguments:
- addr: The address for the request.
- headers: A vector containing headers for the request.
> Example
Create a new delete request.
Request.delete (Uri.parse "http://example.com")
delete : (Text | Uri) -> Vector.Vector -> Request
delete addr (headers = []) = here.new Method.Delete addr headers
type Request type Request
## PRIVATE
A type representing an HTTP request.
Arguments:
- method: The HTTP method represented by the request.
- uri: The URI for the request.
- headers: A vector containing headers for the request.
- body: The body of the request.
type Request method uri headers body type Request method uri headers body
## Set header. ## Sets the header for the request.
Arguments:
- key: The name for the header in this request.
- val: The value for the header in this request.
> Example
Create a request and add a new header to it.
Request.delete.with_header "Foo" "bar"
with_header : Text -> Text -> Request with_header : Text -> Text -> Request
with_header key val = with_header key val =
new_header = Header.new key val new_header = Header.new key val
@ -27,54 +131,54 @@ type Request
Pair acc False -> acc + [new_header] Pair acc False -> acc + [new_header]
Request this.method this.uri new_headers this.body Request this.method this.uri new_headers this.body
## Set headers. ## Sets the headers in the request.
Arguments:
- new_headers: A vector of headers to put in the request. If `this` has
any headers they will be replaced with new_headers.
> Example
Create a request and unset all the headers.
Request.delete.with_headers []
with_headers : [Header] -> Request with_headers : [Header] -> Request
with_headers new_headers = with_headers new_headers =
update_header req new_header = req.with_header new_header.name new_header.value update_header req new_header = req.with_header new_header.name new_header.value
new_headers.fold this update_header new_headers.fold this update_header
## Set body. ## Set the body for the request.
Arguments:
- new_body: The body to insert into the request.
> Example
Unsetting the body in a post request.
Request.post (Uri.parse "http://example.com") Request_Body.Empty |> .with_body Request_Body.Empty
with_body : Request_Body -> Request with_body : Request_Body -> Request
with_body new_body = Request this.method this.uri this.headers new_body with_body new_body = Request this.method this.uri this.headers new_body
## Set body encoded as "application/json". ## Set the body text in the request encoded as "application/json".
Arguments:
- json_body: The body to insert into the request. It must be textual
JSON.
> Example
Setting the body in a post request to some JSON.
Request.post (Uri.parse "http://example.com") Request_Body.Empty |> .with_body "{ "a": "b" }"
with_json : Text -> Request with_json : Text -> Request
with_json json_body = with_json json_body =
new_body = Request_Body.Json json_body new_body = Request_Body.Json json_body
Request this.method this.uri this.headers new_body . with_headers [Header.application_json] Request this.method this.uri this.headers new_body . with_headers [Header.application_json]
## Set body as vector of parts encoded as ## Set body as vector of parts encoded as "application/x-www-form-urlencoded".
"application/x-www-form-urlencoded".
Arguments:
- parts: The parts of the form, or a form itself.
> Example
Create a delete request with an empty form.
Request.delete (Uri.parse "http://example.com") . with_form []
with_form : (Vector | Form) -> Request with_form : (Vector | Form) -> Request
with_form parts = with_form parts =
new_body = Request_Body.Form parts.to_form new_body = Request_Body.Form parts.to_form
Request this.method this.uri this.headers new_body . with_headers [Header.application_x_www_form_urlencoded] Request this.method this.uri this.headers new_body . with_headers [Header.application_x_www_form_urlencoded]
## Create new HTTP request.
new : Method -> (Text | Uri) -> Vector.Vector -> Request_Body -> Request
new method addr (headers = []) (body = Request_Body.Empty) =
Panic.recover (Request method (Internal.panic_on_error (addr.to_uri)) headers body) . catch Internal.recover_panic
## Create an Options request.
options : (Text | Uri) -> Vector.Vector -> Request
options addr (headers = []) = here.new Method.Options addr headers
## Create a Get request.
get : (Text | Uri) -> Vector.Vector -> Request
get addr (headers = []) = here.new Method.Get addr headers
## Create a Head request.
head : (Text | Uri) -> Vector.Vector -> Request
head addr (headers = []) = here.new Method.Head addr headers
## Create a Post request.
post : (Text | Uri) -> Request_Body -> Vector.Vector -> Request
post addr body (headers = []) = here.new Method.Post addr headers body
## Create a Put request.
put : (Text | Uri) -> Request_Body -> Vector.Vector -> Request
put addr body (headers = []) = here.new Method.Put addr headers body
## Create a Delete request.
delete : (Text | Uri) -> Vector.Vector -> Request
delete addr (headers = []) = here.new Method.Delete addr headers

View File

@ -7,16 +7,31 @@ type Body
type Empty type Empty
## Request body with text. ## Request body with text.
Arguments:
- text: The plain text in the request body.
type Text text type Text text
## Request body with JSON. ## Request body with JSON.
Arguments:
- json: The JSON in the request body.
type Json json type Json json
## Request body with form data. ## Request body with form data.
Arguments:
- form: The form data in the request body.
type Form form type Form form
## Request body with file data. ## Request body with file data.
Arguments:
- file: The file data in the request body.
type File file type File file
## Request body with binary. ## Request body with binary.
Arguments:
- bytes: The binary data in the request body.
type Bytes bytes type Bytes bytes

View File

@ -9,6 +9,13 @@ polyglot java import org.enso.base.Http_Utils
type Response type Response
## PRIVATE
A type representing an HTTP response.
Arguments:
- internal_http_response: The internal represnetation of the HTTP
response.
type Response internal_http_response type Response internal_http_response
## Get the response headers. ## Get the response headers.
@ -25,6 +32,6 @@ type Response
code : Status_Code code : Status_Code
code = Status_Code.status_code this.internal_http_response.statusCode code = Status_Code.status_code this.internal_http_response.statusCode
## A Response to Json conversion. ## Convert the response to JSON.
to_json : Json.Object to_json : Json.Object
to_json = Json.from_pairs [["type", "Response"], ["headers", this.headers], ["body", this.body], ["code", this.code]] to_json = Json.from_pairs [["type", "Response"], ["headers", this.headers], ["body", this.body], ["code", this.code]]

View File

@ -6,6 +6,9 @@ import Standard.Base.System.File
type Body type Body
## Response body ## Response body
Arguments:
- bytes: The body of the response as binary data.
type Body bytes type Body bytes
## Convert response body to Text. ## Convert response body to Text.
@ -17,7 +20,10 @@ type Body
to_json = Json.parse this.to_text to_json = Json.parse this.to_text
## Write response body to a File. ## Write response body to a File.
Arguments:
- file: The file to write the bytes to.
to_file : File -> File to_file : File -> File
to_file path = to_file file =
path.write_bytes this.bytes file.write_bytes this.bytes
path file

View File

@ -2,7 +2,10 @@ from Standard.Base import all
type Status_Code type Status_Code
## HTTP status code. ## An HTTP status code.
Arguments:
- code: The numeric representation of the code.
type Status_Code code type Status_Code code
## 100 Continue. ## 100 Continue.

View File

@ -1,8 +1,17 @@
from Standard.Base import all from Standard.Base import all
## PRIVATE ## PRIVATE
Panics on encountering an error.
Arguments:
- action: The action to perform that may recurn an error.
panic_on_error : Any -> Any
panic_on_error ~action = panic_on_error ~action =
action . catch Panic.throw action . catch Panic.throw
## PRIVATE ## PRIVATE
Recovers from a panic.
recover_panic : Any -> Error
recover_panic error = Error.throw error recover_panic error = Error.throw error

View File

@ -3,15 +3,23 @@ from Standard.Base import all
## Proxy settings. ## Proxy settings.
type Proxy type Proxy
## Proxy is disabled. ## The proxy is disabled.
type None type None
## Use a sysem proxy settings. ## Use the system proxy settings.
type System type System
## Use provided proxy. ## Use the provided proxy server.
type Proxy_Addr proxy_host proxy_port type Proxy_Addr proxy_host proxy_port
## Create new proxy settins from host and port. ## Create new proxy settings from a host and port.
Arguments:
- host: The host address for the proxy.
- port: The port number for the proxy server on `host`.
> Example
Create a new proxy running on localhost at port 80080.
Proxy.new "localhost" 80800
new : Text -> Integer -> Proxy new : Text -> Integer -> Proxy
new host port=80 = Proxy_Addr host port new host port=80 = Proxy_Addr host port

View File

@ -6,23 +6,58 @@ polyglot java import java.net.URI as Java_URI
polyglot java import java.util.Optional polyglot java import java.util.Optional
## Syntax error when parsing a Uri. ## Syntax error when parsing a Uri.
Arguments:
- message: The error message for the URI syntax error.
type Syntax_Error message type Syntax_Error message
## Converts the URI syntax error to a human-readable form.
Syntax_Error.to_display_text = Syntax_Error.to_display_text =
"Uri syntax error: " + this.message "Uri syntax error: " + this.message
## Convert Text to Uri. ## Parse a Uri from text.
Arguments:
- text: The text to parse as a URI.
Throws a Syntax_Error when the text cannot be parsed as a Uri.
> Example
Parse Uri text.
Uri.parse "http://example.com"
parse : Text -> Uri ! Syntax_Error
parse text =
Panic.recover (Uri (Java_URI.create text)) . catch e-> case e of
Polyglot_Error ex -> Error.throw (Syntax_Error ex.getMessage)
other -> Panic.throw other
## Convert Text to a Uri.
Throws a Syntax_Error when `this` cannot be parsed as a Uri.
> Example
Parse Uri text.
Uri.parse "http://example.com"
Text.to_uri : Uri ! Syntax_Error
Text.to_uri = here.parse this Text.to_uri = here.parse this
type Uri type Uri
## Represents a Uniform Resource Identifier (URI) reference. ## Represents a Uniform Resource Identifier (URI) reference.
Arguments:
- internal_uri: The internal representation of the URI.
type Uri internal_uri type Uri internal_uri
## Convert this to Uri. ## Convert this to Uri.
> Examples
Convert a URI to a URI (a no op).
"http://example.com".to_uri.to_uri
to_uri : Uri to_uri : Uri
to_uri = this to_uri = this
## Get scheme part of this Uri. ## Get the scheme part of this Uri.
> Example > Example
Return the "http" part of the HTTP address. Return the "http" part of the HTTP address.
@ -31,7 +66,7 @@ type Uri
scheme : Text ! Nothing scheme : Text ! Nothing
scheme = Internal.handle_nothing this.internal_uri.getScheme scheme = Internal.handle_nothing this.internal_uri.getScheme
## Get user info part of this Uri. ## Get the user info part of this Uri.
> Example > Example
Return the "user:pass" part of the HTTP address. Return the "user:pass" part of the HTTP address.
@ -40,7 +75,7 @@ type Uri
user_info : Text ! Nothing user_info : Text ! Nothing
user_info = Internal.handle_nothing this.internal_uri.getUserInfo user_info = Internal.handle_nothing this.internal_uri.getUserInfo
## Get host part of this Uri. ## Get the host part of this Uri.
> Example > Example
Return the "example.com" part of the HTTP address. Return the "example.com" part of the HTTP address.
@ -49,7 +84,7 @@ type Uri
host : Text ! Nothing host : Text ! Nothing
host = Internal.handle_nothing this.internal_uri.getHost host = Internal.handle_nothing this.internal_uri.getHost
## Get authority (user info and host) part of this Uri. ## Get the authority (user info and host) part of this Uri.
> Example > Example
Return the "user:pass@example.com" part of the HTTP address. Return the "user:pass@example.com" part of the HTTP address.
@ -58,7 +93,7 @@ type Uri
authority : Text ! Nothing authority : Text ! Nothing
authority = Internal.handle_nothing this.internal_uri.getAuthority authority = Internal.handle_nothing this.internal_uri.getAuthority
## Get port part of this Uri. ## Get the port part of this Uri.
> Example > Example
Return the "80" part of the HTTP address. Return the "80" part of the HTTP address.
@ -75,7 +110,7 @@ type Uri
Internal.handle_nothing <| Internal.handle_nothing <|
if port_number == -1 then Nothing else port_number.to_text if port_number == -1 then Nothing else port_number.to_text
## Get path part of this Uri. ## Get the path part of this Uri.
> Example > Example
Return the "/foo/bar" part of the HTTP address. Return the "/foo/bar" part of the HTTP address.
@ -84,7 +119,7 @@ type Uri
path : Text ! Nothing path : Text ! Nothing
path = Internal.handle_nothing this.internal_uri.getPath path = Internal.handle_nothing this.internal_uri.getPath
## Get query part of this Uri. ## Get the query part of this Uri.
> Example > Example
Return the "key=val" part of the HTTP address. Return the "key=val" part of the HTTP address.
@ -93,7 +128,7 @@ type Uri
query : Text ! Nothing query : Text ! Nothing
query = Internal.handle_nothing this.internal_uri.getQuery query = Internal.handle_nothing this.internal_uri.getQuery
## Get fragment part of this Uri. ## Get the fragment part of this Uri.
> Example > Example
Return the empty fragment of the HTTP address. Return the empty fragment of the HTTP address.
@ -102,46 +137,57 @@ type Uri
fragment : Text ! Nothing fragment : Text ! Nothing
fragment = Internal.handle_nothing this.internal_uri.getFragment fragment = Internal.handle_nothing this.internal_uri.getFragment
## Get unescaped user info part of this Uri. ## ADVANCED
Get the unescaped user info part of this Uri.
raw_user_info : Text ! Nothing raw_user_info : Text ! Nothing
raw_user_info = Internal.handle_nothing this.internal_uri.getRawUserInfo raw_user_info = Internal.handle_nothing this.internal_uri.getRawUserInfo
## Get unescaped authority part of this Uri. ## ADVANCED
Get the unescaped authority part of this Uri.
raw_authority : Text ! Nothing raw_authority : Text ! Nothing
raw_authority = Internal.handle_nothing this.internal_uri.getRawAuthority raw_authority = Internal.handle_nothing this.internal_uri.getRawAuthority
## Get unescaped path part of this Uri. ## ADVANCED
Get the unescaped path part of this Uri.
raw_path : Text ! Nothing raw_path : Text ! Nothing
raw_path = Internal.handle_nothing this.internal_uri.getRawPath raw_path = Internal.handle_nothing this.internal_uri.getRawPath
## Get unescaped query part of this Uri. ## ADVANCED
Get the unescaped query part of this Uri.
raw_query : Text ! Nothing raw_query : Text ! Nothing
raw_query = Internal.handle_nothing this.internal_uri.getRawQuery raw_query = Internal.handle_nothing this.internal_uri.getRawQuery
## Get unescaped fragment part of this Uri. ## ADVANCED
Get the unescaped fragment part of this Uri.
raw_fragment : Text ! Nothing raw_fragment : Text ! Nothing
raw_fragment = Internal.handle_nothing this.internal_uri.getRawFragment raw_fragment = Internal.handle_nothing this.internal_uri.getRawFragment
## Convert this Uri to text. ## Convert this Uri to text.
> Example
Convert a URI to text.
Uri.new "https://example.com" . to_text
to_text : Text to_text : Text
to_text = this.internal_uri.toString to_text = this.internal_uri.toString
## An Uri to JSON conversion. ## Convert a Uri to JSON.
> Example
Convert a URI to JSON.
Uri.new "https://example.com" . to_json
to_json : Json.String to_json : Json.String
to_json : Json.String this.to_text to_json : Json.String this.to_text
## Check Uri equality. ## Check if this URI is equal to another URI.
> Example
Check if two URIs are equal.
"https://example.com" == "http://example.com"
== : Uri -> Boolean == : Uri -> Boolean
== that = this.internal_uri.equals that.internal_uri == that = this.internal_uri.equals that.internal_uri
## Parse Uri from text.
Return Syntax_Error when the text cannot be parsed as Uri.
> Example
Parse Uri text.
Uri.parse "http://example.com"
parse : Text -> Uri ! Syntax_Error
parse text =
Panic.recover (Uri (Java_URI.create text)) . catch e-> case e of
Polyglot_Error ex -> Error.throw (Syntax_Error ex.getMessage)
other -> Panic.throw other

View File

@ -1,6 +1,11 @@
from Standard.Base import all from Standard.Base import all
## PRIVATE ## PRIVATE
Handle a nothing value.
Arguments:
- value: The value that may possibly be nothing.
handle_nothing : Any -> Any ! Nothing handle_nothing : Any -> Any ! Nothing
handle_nothing value = case value of handle_nothing value = case value of
Nothing -> Error.throw Nothing Nothing -> Error.throw Nothing

View File

@ -2,7 +2,13 @@ from Standard.Base import all
import Builtins import Builtins
## Checks whether an object is an instance of a given class. ## PRIVATE
Checks whether an object is an instance of a given class.
Arguments:
- object: The object to check for class membership.
- class: The java class to check for membership in.
Builtins.Java.is_instance : Any -> Any -> Boolean Builtins.Java.is_instance : Any -> Any -> Boolean
Builtins.Java.is_instance object class = Builtins.Java.is_instance object class =
class_object = class.class class_object = class.class

View File

@ -6,6 +6,13 @@ polyglot java import java.lang.System
Returns a value of a specified environment variable or Nothing if such Returns a value of a specified environment variable or Nothing if such
variable is not defined. variable is not defined.
Arguments:
- key: The name of the environment variable to look up.
> Example
Look up the value of the `PATH` environment variable.
Environment.get "PATH"
get : Text -> Text | Nothing get : Text -> Text | Nothing
get key = get key =
System.getenv key System.getenv key

View File

@ -10,121 +10,102 @@ polyglot java import java.nio.file.AccessDeniedException
polyglot java import java.nio.file.NoSuchFileException polyglot java import java.nio.file.NoSuchFileException
type File_Error type File_Error
## An error that indicates that the requested file does not exist.
Arguments:
- file: The file that doesn't exist.
type No_Such_File_Error file type No_Such_File_Error file
## An error that indicates that the program does not have access to the
requested file.
Arguments:
- file: The file that the program does not have permission to access.
type Access_Denied_Error file type Access_Denied_Error file
## A generic IO error.
Arguments:
- message: The message for the error.
type Io_Error message type Io_Error message
## PRIVATE ## UNSTABLE
Utility method for rewrapping Java exceptions into Enso panics. Convert the File error to a human-readable format.
rethrow_java file exception = to_display_text : Text
case exception of to_display_text = case this of
Polyglot_Error exc -> No_Such_File_Error file -> "The file at " + file.path + " does not exist."
if Java.is_instance exc NoSuchFileException then Access_Denied_Error file -> "You do not have permission to access the file at " + file.path + "."
Panic.throw (No_Such_File_Error file) Io_Error msg -> "An IO error has occurred: " + msg.to_text + "."
if Java.is_instance exc AccessDeniedException then
Panic.throw (Access_Denied_Error file)
if Java.is_instance exc IOException then
Panic.throw (Io_Error exc.getMessage)
Panic.throw exception
_ -> Panic.throw exception
## PRIVATE ## Creates a new file object, pointing to the given path.
Utility method for running an action with Java exceptions mapping. Arguments:
handle_java_exceptions file ~action = - path: The path to the file that you want to create.
err = Panic.recover action
r = err.catch (here.rethrow_java file)
r
## PRIVATE > Example
Create a new file pointing to the `data.csv` file in the project directory.
File.new (Enso_Project.data / "data.csv").path
new : Text -> File
new path = File (Prim_Io.get_file path)
Utility method for closing primitive Java streams. Provided to avoid ## Open and read the file at the provided `path`.
accidental scope capture with `Managed_Resource` finalizers.
close_stream : Any -> Nothing
close_stream stream =
stream.close
Nothing
## An output stream, allowing for interactive writing of contents into an Arguments:
open file. - path: The path of the file to open and read the contents of. It will
type Output_Stream accept a textual path or a file.
type Output_Stream file stream_resource
## Writes a vector of bytes into the file at the current stream position. ? Module or Instance?
write_bytes : Vector.Vector -> Nothing ! File_Error If you have a variable `file` of type `File`, we recommend calling the
write_bytes contents = Managed_Resource.with this.stream_resource java_stream-> `.read` method on it directly, rather than using `File.read file`. The
here.handle_java_exceptions this.file <| latter, however, will still work.
java_stream.write contents.to_array
java_stream.flush
Nothing
## Closes this stream. > Example
Read the `data.csv` file in the project directory's `data` directory. You
will need to create the file `data.csv` manually in that directory.
File.read (Enso_Project.data / "data.csv").path
read : (Text | File) -> Text
read path = .read <| case path of
Text -> (here.new path)
File _ -> path
Even though Streams are closed automatically upon garbage collection, it ## Returns the current working directory (CWD) of the current program.
is still advised to close streams manually if they are not used within
a bracket pattern.
close : Nothing
close = Managed_Resource.finalize this.stream_resource
## An input stream, allowing for interactive reading of contents from an open > Example
file. Get the program's current working directory.
type Input_Stream File.current_directory
type Input_Stream file stream_resource current_directory : File
current_directory = File (Prim_Io.get_cwd)
## Reads all the bytes in this file into a vector of bytes. ## Returns the home directory of the current user.
read_all_bytes : Vector.Vector ! File_Error
read_all_bytes = Managed_Resource.with this.stream_resource java_stream->
here.handle_java_exceptions this.file <|
Vector.from_polyglot_array java_stream.readAllBytes
## Reads _up to_ the provided number of bytes from the stream. > Example
Get the current user's home directory.
Makes a best-effort to read as many bytes as provided, however fewer File.home
bytes may be read, if end of stream is encountered. home : File
home = here.new (Prim_Io.get_user_home)
The length of the returned vector is the same as the number of bytes
read.
read_n_bytes : Integer -> Vector.Vector ! File_Error
read_n_bytes n = Managed_Resource.with this.stream_resource java_stream->
here.handle_java_exceptions this.file <|
bytes = java_stream.readNBytes n
Vector.from_polyglot_array bytes
## Reads the next byte from the stream.
The returned value is an integer in the range 0-255 representing the
next byte of input, or -1 if end of stream is reached.
read_byte : Integer ! File_Error
read_byte = Managed_Resource.with this.stream_resource java_stream->
here.handle_java_exceptions this.file <|
java_stream.read
## Closes this stream.
Even though Streams are closed automatically upon garbage collection, it
is still advised to close streams manually if they are not used within
a bracket pattern.
close : Nothing
close = Managed_Resource.finalize this.stream_resource
## Exposes operations on the underlying Java input stream.
Useful when integrating with polyglot functions requiring an
`InputStream` as an argument.
with_java_stream : (Java_Input_Stream -> Any) -> Any
with_java_stream f = Managed_Resource.with this.stream_resource f
type File type File
## PRIVATE
A type representing a file.
Arguments:
- prim_file: The internal representation of the file.
type File prim_file type File prim_file
## Returns a new input stream for this file. ## ADVANCED
Returns a new input stream for this file.
Arguments:
- open_options: A vector of `File.Option` objects determining how to open
the stream. These options set the access properties of the stream.
The returned stream should be closed as soon as it is not used anymore. The returned stream should be closed as soon as it is not used anymore.
The `with_input_stream` method should be preferred whenever possible. The `with_input_stream` method should be preferred whenever possible.
The `open_options` argument is a vector of `File.Option` objects,
describing the access properties of the created stream.
new_input_stream : Vector.Vector -> Input_Stream ! File_Error new_input_stream : Vector.Vector -> Input_Stream ! File_Error
new_input_stream open_options = new_input_stream open_options =
opts = open_options . map (_.to_java) . to_array opts = open_options . map (_.to_java) . to_array
@ -133,13 +114,16 @@ type File
resource = Managed_Resource.register stream here.close_stream resource = Managed_Resource.register stream here.close_stream
Input_Stream this resource Input_Stream this resource
## Returns a new output stream for this file. ## ADVANCED
Returns a new output stream for this file.
Arguments:
- open_options: A vector of `File.Option` objects determining how to open
the stream. These options set the access properties of the stream.
The returned stream should be closed as soon as it is not used anymore. The returned stream should be closed as soon as it is not used anymore.
The `with_output_stream` method should be preferred whenever possible. The `with_output_stream` method should be preferred whenever possible.
The `open_options` argument is a vector of `File.Option` objects,
describing the access properties of the created stream.
new_output_stream : Vector.Vector -> Output_Stream ! File_Error new_output_stream : Vector.Vector -> Output_Stream ! File_Error
new_output_stream open_options = new_output_stream open_options =
opts = open_options . map (_.to_java) . to_array opts = open_options . map (_.to_java) . to_array
@ -151,11 +135,14 @@ type File
## Creates a new output stream for this file and runs the specified action ## Creates a new output stream for this file and runs the specified action
on it. on it.
Arguments:
- open_options: A vector of `File.Option` objects determining how to open
the stream. These options set the access properties of the stream.
- action: A function that operates on the output stream and returns some
value. The value is returned from this method.
The created stream is automatically closed when `action` returns (even The created stream is automatically closed when `action` returns (even
if it returns exceptionally). if it returns exceptionally).
The `open_options` argument is a vector of `File.Option` objects,
describing the properties of the created stream.
with_output_stream : Vector.Vector -> (Output_Stream -> Any ! File_Error) -> Any ! File_Error with_output_stream : Vector.Vector -> (Output_Stream -> Any ! File_Error) -> Any ! File_Error
with_output_stream open_options action = with_output_stream open_options action =
Resource.bracket (this.new_output_stream open_options) (_.close) action Resource.bracket (this.new_output_stream open_options) (_.close) action
@ -163,11 +150,14 @@ type File
## Creates a new input stream for this file and runs the specified action ## Creates a new input stream for this file and runs the specified action
on it. on it.
Arguments:
- open_options: A vector of `File.Option` objects determining how to open
the stream. These options set the access properties of the stream.
- action: A function that operates on the input stream and returns some
value. The value is returned from this method.
The created stream is automatically closed when `action` returns (even The created stream is automatically closed when `action` returns (even
if it returns exceptionally). if it returns exceptionally).
The `open_options` argument is a vector of `File.Option` objects,
describing the properties of the created stream.
with_input_stream : Vector.Vector -> (Input_Stream -> Any ! File_Error) -> Any ! File_Error with_input_stream : Vector.Vector -> (Input_Stream -> Any ! File_Error) -> Any ! File_Error
with_input_stream open_options action = with_input_stream open_options action =
Resource.bracket (this.new_input_stream open_options) (_.close) action Resource.bracket (this.new_input_stream open_options) (_.close) action
@ -185,16 +175,25 @@ type File
Text.from_utf_8 bytes Text.from_utf_8 bytes
## Appends a number of bytes at the end of this file. ## Appends a number of bytes at the end of this file.
Arguments:
- contents: A vector of bytes to append to the file.
append_bytes : Vector.Vector -> Nothing ! File_Error append_bytes : Vector.Vector -> Nothing ! File_Error
append_bytes contents = append_bytes contents =
opts = [Option.Append, Option.Create] opts = [Option.Append, Option.Create]
this.with_output_stream opts (_.write_bytes contents) this.with_output_stream opts (_.write_bytes contents)
## Appends a UTF-8 encoded `Text` at the end of this file. ## Appends a UTF-8 encoded `Text` at the end of this file.
Arguments:
- contents: The UTF-8 encoded text to append to the file.
append : Text -> Nothing ! File_Error append : Text -> Nothing ! File_Error
append contents = this.append_bytes contents.utf_8 append contents = this.append_bytes contents.utf_8
## Writes a number of bytes into this file, removing any existing contents. ## Writes a number of bytes into this file, replacing any existing contents.
Arguments:
- contents: The vector of bytes to write into the file.
If the file does not exist, it will be created. If the file does not exist, it will be created.
write_bytes : Vector.Vector -> Nothing ! File_Error write_bytes : Vector.Vector -> Nothing ! File_Error
@ -203,14 +202,20 @@ type File
this.with_output_stream opts (_.write_bytes contents) this.with_output_stream opts (_.write_bytes contents)
Nothing Nothing
## Writes a UTF-8 encoded `Text` into this file, removing any existing ## Writes a UTF-8 encoded `Text` into this file, replacing any existing
contents. contents.
Arguments:
- contents: The UTF-8 encoded text to write to the file.
If the file does not exist, it will be created. If the file does not exist, it will be created.
write : Text -> Nothing ! File_Error write : Text -> Nothing ! File_Error
write contents = this.write_bytes contents.utf_8 write contents = this.write_bytes contents.utf_8
## Resolve a child file of the given file. ## Join two path segments together.
Arguments:
- subpath: The path to join to the path of `this`.
/ : (Text | File) -> File / : (Text | File) -> File
/ subpath = case subpath of / subpath = case subpath of
File prim -> File (this.prim_file.resolve prim) File prim -> File (this.prim_file.resolve prim)
@ -239,6 +244,11 @@ type File
create_directory = this.prim_file.createDirectories create_directory = this.prim_file.createDirectories
## Checks whether the file exists and is a regular file. ## Checks whether the file exists and is a regular file.
? Regular Files
A regular file is one that does not have any special meaning to the
operating system. Examples of files that are not regular are symlinks,
pipes, devices, sockets and directories.
is_regular_file : Boolean is_regular_file : Boolean
is_regular_file = this.prim_file.isRegularFile is_regular_file = this.prim_file.isRegularFile
@ -288,38 +298,150 @@ type File
delete_if_exists : Nothing ! File_Error delete_if_exists : Nothing ! File_Error
delete_if_exists = if this.exists then this.delete else Nothing delete_if_exists = if this.exists then this.delete else Nothing
## Creates a new file object, pointing to the given path. ## An output stream, allowing for interactive writing of contents into an
open file.
type Output_Stream
> Example ## ADVANCED
Create a new file pointing to the `data.csv` file in the project directory.
File.new (Enso_Project.data / "data.csv").path
new : Text -> File
new path = File (Prim_Io.get_file path)
## Open and read the file at the provided `path`. An output stream, allowing for interactive writing of contents into an
open file.
Arguments:
- file: The file which the output stream will write into.
- stream_resource: The internal resource that represents the underlying
stream.
type Output_Stream file stream_resource
## ADVANCED
Writes a vector of bytes into the file at the current stream position.
Arguments:
- contents: A vector of bytes to write into the file.
write_bytes : Vector.Vector -> Nothing ! File_Error
write_bytes contents = Managed_Resource.with this.stream_resource java_stream->
here.handle_java_exceptions this.file <|
java_stream.write contents.to_array
java_stream.flush
Nothing
## ADVANCED
Closes this stream.
Even though Streams are closed automatically upon garbage collection, it
is still advised to close streams manually if they are not used within
a bracket pattern.
close : Nothing
close = Managed_Resource.finalize this.stream_resource
## An input stream, allowing for interactive reading of contents from an open
file.
type Input_Stream
## ADVANCED
An input stream, allowing for interactive reading of contents from an open
file.
Arguments:
- file: The file from which the stream will read.
- stream_resource: The internal resource that represents the underlying
stream.
type Input_Stream file stream_resource
## ADVANCED
Reads all the bytes in this file into a vector of bytes.
read_all_bytes : Vector.Vector ! File_Error
read_all_bytes = Managed_Resource.with this.stream_resource java_stream->
here.handle_java_exceptions this.file <|
Vector.from_polyglot_array java_stream.readAllBytes
## ADVANCED
Reads _up to_ the provided number of bytes from the stream.
Arguments:
- n: The number of bytes to read from the file.
Makes a best-effort to read as many bytes as provided, however fewer
bytes may be read, if end of stream is encountered.
The length of the returned vector is the same as the number of bytes
read.
read_n_bytes : Integer -> Vector.Vector ! File_Error
read_n_bytes n = Managed_Resource.with this.stream_resource java_stream->
here.handle_java_exceptions this.file <|
bytes = java_stream.readNBytes n
Vector.from_polyglot_array bytes
## ADVANCED
Reads the next byte from the stream.
The returned value is an integer in the range 0-255 representing the
next byte of input, or -1 if end of stream is reached.
read_byte : Integer ! File_Error
read_byte = Managed_Resource.with this.stream_resource java_stream->
here.handle_java_exceptions this.file <|
java_stream.read
## ADVANCED
Closes this stream.
Even though Streams are closed automatically upon garbage collection, it
is still advised to close streams manually if they are not used within
a bracket pattern.
close : Nothing
close = Managed_Resource.finalize this.stream_resource
## PRIVATE
Exposes operations on the underlying Java input stream.
Arguments:
- f: Applies a function over the internal java stream.
Useful when integrating with polyglot functions requiring an
`InputStream` as an argument.
with_java_stream : (Java_Input_Stream -> Any) -> Any
with_java_stream f = Managed_Resource.with this.stream_resource f
## PRIVATE
Utility method for rewrapping Java exceptions into Enso panics.
Arguments: Arguments:
- `path`: The path of the file to open and read the contents of. It will - file: The file object.
accept a textual path or a file. - exception: The java exception that was encountered.
rethrow_java : File -> Any -> Any
rethrow_java file exception =
case exception of
Polyglot_Error exc ->
if Java.is_instance exc NoSuchFileException then
Panic.throw (No_Such_File_Error file)
if Java.is_instance exc AccessDeniedException then
Panic.throw (Access_Denied_Error file)
if Java.is_instance exc IOException then
Panic.throw (Io_Error exc.getMessage)
Panic.throw exception
_ -> Panic.throw exception
? Module or Instance? ## PRIVATE
If you have a variable `file` of type `File`, we recommend calling the
`.read` method on it directly, rather than using `File.read file`. The
latter, however, will work.
> Example Utility method for running an action with Java exceptions mapping.
Read the `data.csv` file in the project directory's `data` directory. You handle_java_exceptions file ~action =
will need to create the file `data.csv` manually in that directory. err = Panic.recover action
File.read (Enso_Project.data / "data.csv").path r = err.catch (here.rethrow_java file)
read : (Text | File) -> Text r
read path = .read <| case path of
Text -> (here.new path)
File _ -> path
## Returns the current working directory (CWD) of the current program. ## PRIVATE
current_directory : File
current_directory = File (Prim_Io.get_cwd)
## Returns the home directory of the current user. Utility method for closing primitive Java streams. Provided to avoid
home : File accidental scope capture with `Managed_Resource` finalizers.
home = here.new (Prim_Io.get_user_home) close_stream : Any -> Nothing
close_stream stream =
stream.close
Nothing

View File

@ -8,34 +8,45 @@ polyglot java import java.nio.file.StandardOpenOption
file access. For most use cases, the default values used in the methods of file access. For most use cases, the default values used in the methods of
the `File` type should be preferred. the `File` type should be preferred.
type Option type Option
## If the file is opened for `Write` access then bytes will be written to ## If the file is opened for `Write` access then bytes will be written to
the end of the file rather than the beginning. the end of the file rather than the beginning.
type Append type Append
## Create a new file if it does not exist. ## Create a new file if it does not exist.
type Create type Create
## Create a new file, failing if the file already exists. ## Create a new file, failing if the file already exists.
type Create_New type Create_New
## Delete the underlying file on closing the stream. ## Delete the underlying file on closing the stream.
type Delete_On_Close type Delete_On_Close
## Requires that every update to the file's content be written ## Requires that every update to the file's content be written
synchronously to the underlying storage device. synchronously to the underlying storage device.
type Dsync type Dsync
## Open for read access. ## Open for read access.
type Read type Read
## Sparse file. ## Sparse file.
type Sparse type Sparse
## Requires that every update to the file's content or metadata be written ## Requires that every update to the file's content or metadata be written
synchronously to the underlying storage device. synchronously to the underlying storage device.
type Sync type Sync
## If the file already exists and is opened for `Write` access, ## If the file already exists and is opened for `Write` access,
the original contents will be removed. the original contents will be removed.
type Truncate_Existing type Truncate_Existing
## Open file for write access. ## Open file for write access.
type Write type Write
## PRIVATE ## PRIVATE
Convert this object into a representation understandable by the JVM. Convert this object into a representation understandable by the JVM.
to_java : StandardOpenOption
to_java = case this of to_java = case this of
Append -> StandardOpenOption.APPEND Append -> StandardOpenOption.APPEND
Create -> StandardOpenOption.CREATE Create -> StandardOpenOption.CREATE

View File

@ -2,19 +2,20 @@ from Standard.Base import all
from Builtins import System from Builtins import System
## A representation of the various operating systems on which Enso can run.
type Os type Os
type Linux
type MacOS
type Windows
type Unknown
## PRIVATE ## The Linux operating system.
Create an Os object from text. type Linux
from_text: Text -> Os
from_text os = ## The macOS operating system.
if os == "linux" then Linux else type MacOS
if os == "macos" then MacOS else
if os == "windows" then Windows else Unknown ## The Windows operating system.
type Windows
## An unknown operating system.
type Unknown
## Return the type of operating system. ## Return the type of operating system.
@ -23,3 +24,12 @@ from_text os =
Platform.os Platform.os
os : Os os : Os
os = here.from_text System.os os = here.from_text System.os
## PRIVATE
Create an Os object from text.
from_text: Text -> Os
from_text os =
if os == "linux" then Linux else
if os == "macos" then MacOS else
if os == "windows" then Windows else Unknown

View File

@ -3,15 +3,46 @@ import Standard.Base.System.Process.Exit_Code
from Standard.Base.Data.Vector import Vector from Standard.Base.Data.Vector import Vector
from Builtins import Array, System, True, False from Builtins import Array, System, True, False
## UNSTABLE
Call a command with a list of arguments.
> Example
Call the `echo` command with arguments
Process.run "echo" ["-n", "Hello!"]
The result is printed to stdout:
Hello!
run : Text -> Vector.Vector Text -> Exit_Code
run command arguments=[] =
result = System.create_process command arguments.to_array input="" redirect_in=True redirect_out=True redirect_err=True
Exit_Code.from_number result.exit_code
## UNSTABLE ## UNSTABLE
The builder object that is used to create operating system processes. The builder object that is used to create operating system processes.
type Builder type Builder
## UNSTABLE
A builder object that is used to create operating system processes.
Arguments:
- command: The command to execute on the system.
- arguments: The arguments to pass to `command`. These must be text.
- stdin: Any content to pass to the standard input for `command`.
? Creating a Builder
We recommend that you use this type with its builder interface. Start
by creating a `Builder "command"` and then call functions on it to
set arguments and standard output. It results in much clearer code.
type Builder command arguments=[] stdin="" type Builder command arguments=[] stdin=""
## UNSTABLE ## UNSTABLE
Sets the arguments that should be passed to the created process. Sets the arguments that should be passed to the created process.
Arguments:
- arguments: The arguments to pass to the process.
set_arguments : Vector.Vector Text -> Builder set_arguments : Vector.Vector Text -> Builder
set_arguments arguments = Builder this.command arguments this.stdin set_arguments arguments = Builder this.command arguments this.stdin
@ -19,6 +50,9 @@ type Builder
Sets the text that will be used to feed standard input to the created Sets the text that will be used to feed standard input to the created
process. process.
Arguments:
- stdin: The standard input contents to pass to the process.
set_stdin : Text -> Builder set_stdin : Text -> Builder
set_stdin stdin = Builder this.command this.arguments stdin set_stdin stdin = Builder this.command this.arguments stdin
@ -40,18 +74,10 @@ type Builder
## UNSTABLE ## UNSTABLE
The result of the process invocation. The result of the process invocation.
Arguments:
- exit_code: The exit code for the process.
- stdout: The contents of the process' standard output.
- stderr: The contents of the process' standard error.
type Result exit_code stdout stderr type Result exit_code stdout stderr
## UNSTABLE
Call a command with a list of arguments.
> Example
Call the `echo` command with arguments
Process.run "echo" ["-n", "Hello!"]
The result is printed to stdout:
Hello!
run : Text -> Vector.Vector Text -> Exit_Code
run command arguments=[] =
result = System.create_process command arguments.to_array input="" redirect_in=True redirect_out=True redirect_err=True
Exit_Code.from_number result.exit_code

View File

@ -1,19 +1,34 @@
from Standard.Base import all
## The exit codes that the process can return. ## The exit codes that the process can return.
type Exit_Code type Exit_Code
## The process exited with a success.
type Exit_Success type Exit_Success
## The process exited with a failure.
Arguments:
- code: The exit code for the failure.
type Exit_Failure code type Exit_Failure code
## Convert exit code to a number. ## Convert exit code to a number.
> Example
Convert a success code to a corresponding number.
Exit_Success.to_number
to_number : Integer
to_number = case this of to_number = case this of
Exit_Success -> 0 Exit_Success -> 0
Exit_Failure code -> code Exit_Failure code -> code
## Create exit code from a number. ## Create exit code from a number.
Arguments:
- code: The exit code you want to create.
> Example > Example
Create failure exit code: Create a failure exit code.
Exit_Code.from_number 1 Exit_Code.from_number 1
Result in:
Exit_Failure 1
from_number : Number -> Exit_Code from_number : Number -> Exit_Code
from_number code = if code == 0 then Exit_Success else Exit_Failure code from_number code = if code == 0 then Exit_Success else Exit_Failure code

View File

@ -25,11 +25,11 @@ type Connection
A Database connection using a JDBC driver. A Database connection using a JDBC driver.
Allows to access tables from a database.
Arguments: Arguments:
- java_connection: the resource managing the underlying JDBC connection. - java_connection: the resource managing the underlying JDBC connection.
- dialect: the dialect associated with the database we are connected to. - dialect: the dialect associated with the database we are connected to.
Allows accessing tables from a database.
type Connection connection_resource dialect type Connection connection_resource dialect
## UNSTABLE ## UNSTABLE
@ -106,6 +106,11 @@ type Connection
_ -> Error.throw err _ -> Error.throw err
## PRIVATE ## PRIVATE
Prepares the statement by ensuring that it is sanitised.
Arguments:
- query: The query to prepare the SQL statement in.
prepare_statement : Text | Sql.Statement -> PreparedStatement prepare_statement : Text | Sql.Statement -> PreparedStatement
prepare_statement query = prepare_statement query =
go template holes=[] = Managed_Resource.with this.connection_resource java_connection-> go template holes=[] = Managed_Resource.with this.connection_resource java_connection->
@ -130,6 +135,9 @@ type Connection
A helper function that fetches column names and sql types associated with A helper function that fetches column names and sql types associated with
them for a table in the database. them for a table in the database.
Arguments:
- table_name: The name of the table to fetch the column metadata for.
# fetch_columns : Text -> Vector [Text, Sql_Type] # fetch_columns : Text -> Vector [Text, Sql_Type]
fetch_columns table_name = fetch_columns table_name =
query = IR.Select_All (IR.make_ctx_from table_name) query = IR.Select_All (IR.make_ctx_from table_name)
@ -149,6 +157,9 @@ type Connection
Creates a builder for a column based on a provided SQL type, trying to infer Creates a builder for a column based on a provided SQL type, trying to infer
the best type for the builder. the best type for the builder.
Arguments:
- sql_type: The SQL type of the column to create a builder for.
create_builder : Sql_Type -> Builder create_builder : Sql_Type -> Builder
create_builder sql_type = create_builder sql_type =
initial_size = 10 initial_size = 10
@ -158,16 +169,37 @@ create_builder sql_type =
Builder_Inferred (Java_Exports.make_inferred_builder initial_size) Builder_Inferred (Java_Exports.make_inferred_builder initial_size)
type Builder type Builder
## PRIVATE ## PRIVATE
A builder that has an inferred column type at runtime.
Arguments:
- java_builder: The underlying builder object.
type Builder_Inferred java_builder type Builder_Inferred java_builder
## PRIVATE ## PRIVATE
A builder that has an inferred column type at runtime.
Arguments:
- java_builder: The underlying builder object.
type Builder_Double java_builder type Builder_Double java_builder
## PRIVATE ## PRIVATE
A builder that has an inferred column type at runtime.
Arguments:
- java_builder: The underlying builder object.
type Builder_Long java_builder type Builder_Long java_builder
## PRIVATE ## PRIVATE
A builder that has an inferred column type at runtime.
Arguments:
- java_builder: The underlying builder object.
type Builder_Boolean java_builder type Builder_Boolean java_builder
## PRIVATE ## PRIVATE
@ -202,6 +234,9 @@ type Builder
## PRIVATE ## PRIVATE
Seals the builder and returns a built Java-column. Seals the builder and returns a built Java-column.
Argument:
- name: The name of the column.
make_column : Text -> Java_Exports.Column make_column : Text -> Java_Exports.Column
make_column name = make_column name =
storage = this.java_builder.seal storage = this.java_builder.seal
@ -209,12 +244,24 @@ type Builder
## An error indicating that a supported dialect could not be deduced for the ## An error indicating that a supported dialect could not be deduced for the
provided URL. provided URL.
Argument:
- url: The URL for which the dialect could not be deduced.
type Unsupported_Dialect url type Unsupported_Dialect url
## Pretty print the error about unsupported SQL dialects.
Unsupported_Dialect.to_display_text : Text
Unsupported_Dialect.to_display_text =
"Could not infer the SQL dialect for the database at " + this.url + "."
## PRIVATE ## PRIVATE
Creates a JDBC connection based on a URL and optionally username and Creates a JDBC connection based on a URL and optionally username and
password. password.
Arguments:
- url: The URL to connect to.
- properties: A vector of properties for the connection.
create_jdbc_connection : Text -> Vector -> Connection create_jdbc_connection : Text -> Vector -> Connection
create_jdbc_connection url properties = here.wrap_sql_errors <| create_jdbc_connection url properties = here.wrap_sql_errors <|
java_props = Properties.new java_props = Properties.new
@ -228,37 +275,55 @@ create_jdbc_connection url properties = here.wrap_sql_errors <|
## PRIVATE ## PRIVATE
This cannot be a closure due to limitations of Managed_Resource. This cannot be a closure due to limitations of Managed_Resource.
Arguments:
- connection: The connection to close.
close_connection : Connection -> Nothing
close_connection connection = close_connection connection =
connection.close connection.close
type Sql_Error type Sql_Error
## UNSTABLE ## UNSTABLE
Indicates an error with executing a query, update or connecting to the Indicates an error with executing a query, update or connecting to the
database. database.
Wraps an SQLException from the Java drvier. Arguments:
- java_exception: The underlying exception.
type Sql_Error java_exception type Sql_Error java_exception
## UNSTABLE ## UNSTABLE
Convert the SQL error to a textual representation.
to_text : Text to_text : Text
to_text = this.java_exception.getMessage to_text = "There was an SQL error: " + this.java_exception.getMessage.to_text + "."
## UNSTABLE ## UNSTABLE
Pretty print the SQL error.
to_display_text : Text to_display_text : Text
to_display_text = this.to_text to_display_text = this.to_text
type Sql_Timeout_Error type Sql_Timeout_Error
## UNSTABLE ## UNSTABLE
Indicates that an operation has timed out. Indicates that an operation has timed out.
Arguments:
- java_exception: The underlying exception.
type Sql_Timeout_Error java_exception type Sql_Timeout_Error java_exception
## UNSTABLE ## UNSTABLE
Convert the timeout error to a textual representation.
to_text : Text to_text : Text
to_text = this.java_exception.getMessage to_text = "The SQL connection timed out: " + this.java_exception.getMessage + "."
## UNSTABLE ## UNSTABLE
Pretty print the timeout error.
to_display_text : Text to_display_text : Text
to_display_text = this.to_text to_display_text = this.to_text
@ -266,6 +331,9 @@ type Sql_Timeout_Error
Executes `action` and returns its result, catching any panics and if they are Executes `action` and returns its result, catching any panics and if they are
coming from JDBC, wraps them with our own error types. coming from JDBC, wraps them with our own error types.
Arguments:
- action: The computation to execute. This computation may throw SQL errors.
wrap_sql_errors ~action = wrap_sql_errors ~action =
result = Panic.recover action result = Panic.recover action
result.catch err-> case err of result.catch err-> case err of

View File

@ -6,31 +6,32 @@ from Standard.Database.Connection.Connection import all
Tries to connect to the database under a provided URL. Tries to connect to the database under a provided URL.
Currently SQLite and PostgreSQL databases are supported.
The exact URL depends on the database engine.
For SQLite the expected format is `sqlite:/path/to/database/file`.
For PostgreSQL it can be one of:
- `postgresql:database_name` - which will connect to the database with the
given name on the local machine;
- `postgresql:/` - which will connect to the default database
(which is the same as the username) on the local machine;
- `postgresql://host/database_name` - which will connect to the specified
database on a specified host, the `host` can consist of an IP address or a
hostname, optionally followed by colon and a port number, so values like
`db.example.com`, `127.0.0.1`, `example.com:1234`, `127.0.0.1:1234` are
allowed;
- `postgresql://host/` - which will connect to the same database as the
username on a specified host, the `host`` is defined as above.
Arguments: Arguments:
- url: the URL to connect to. - url: The URL to connect to.
- user: (optional) an username for authentication. - user: A username for authentication. Optional.
- password: (optional) a password for authentication. - password: A password for authentication. Optional.
- custom_properties: (optional) a vector of key-value Text pairs which can - custom_properties: A vector of key-value Text pairs which can
set any other properties that can be used to configure the connection or set any other properties that can be used to configure the connection or
for authentication. Supported properties depend on the database engine that for authentication. Supported properties depend on the database engine that
the connection is made to. the connection is made to. Optional.
Currently SQLite and PostgreSQL databases are supported.
? Finding the URL
The exact URL depends on the database engine. For SQLite the expected o
format is `sqlite:/path/to/database/file`. For PostgreSQL it can be one
of:
- `postgresql:database_name` - which will connect to the database with the
given name on the local machine;
- `postgresql:/` - which will connect to the default database
(which is the same as the username) on the local machine;
- `postgresql://host/database_name` - which will connect to the specified
database on a specified host, the `host` can consist of an IP address or=
a hostname, optionally followed by colon and a port number, so values
like `db.example.com`, `127.0.0.1`, `example.com:1234`, `127.0.0.1:1234`
are allowed;
- `postgresql://host/` - which will connect to the same database as the
username on a specified host, the `host`` is defined as above.
connect : Text -> Nothing | Text -> Nothing | Text -> Vector -> Connection ! Sql_Error connect : Text -> Nothing | Text -> Nothing | Text -> Vector -> Connection ! Sql_Error
connect url user=Nothing password=Nothing custom_properties=[] = connect url user=Nothing password=Nothing custom_properties=[] =
full_url = if url.starts_with "jdbc:" then url else "jdbc:"+url full_url = if url.starts_with "jdbc:" then url else "jdbc:"+url
@ -43,10 +44,10 @@ connect url user=Nothing password=Nothing custom_properties=[] =
Connects to an SQLite database in a file on the filesystem. Connects to an SQLite database in a file on the filesystem.
It is an alternative to `connect` that resolves a path to the database file.
Arguments: Arguments:
- file: the path to the database. - file: The path to the database.
It is an alternative to `connect` that resolves a path to the database file.
open_sqlite_file : File -> Connection ! Sql_Error open_sqlite_file : File -> Connection ! Sql_Error
open_sqlite_file file = open_sqlite_file file =
url = "sqlite:" + file.absolute.path url = "sqlite:" + file.absolute.path

View File

@ -15,6 +15,12 @@ type Column
Represents a single column backed by a database. Represents a single column backed by a database.
Arguments:
- name: The name of the column.
- connection: The connection with which the column is associated.
- expression: The expressions to apply to the column.
- context: The SQl context in which the column exists.
These columns may come from the Table or can be created by combining These columns may come from the Table or can be created by combining
other columns with operators. Expressions created in this way may be other columns with operators. Expressions created in this way may be
materialized or used to apply filters, groupings etc. to tables from materialized or used to apply filters, groupings etc. to tables from
@ -43,6 +49,7 @@ type Column
Arguments: Arguments:
- show_rows: the number of initial rows that should be displayed. - show_rows: the number of initial rows that should be displayed.
print : Nothing
print show_rows=10 = print show_rows=10 =
IO.println (this.display show_rows format_terminal=True) IO.println (this.display show_rows format_terminal=True)
IO.println '' IO.println ''
@ -93,6 +100,14 @@ type Column
## PRIVATE ## PRIVATE
Creates a binary operation with given kind and operand. Creates a binary operation with given kind and operand.
Arguments:
- op_kind: The kind of binary operator.
- operand: The right operand to the binary operator.
- new_type: The type of the SQL column that results from applying the
operator.
- operand_type: The SQL type of the operand.
If not specified, the `new_type` is the same as the current one. If not specified, the `new_type` is the same as the current one.
`operand_type` is only relevant if the operand is not a column, it `operand_type` is only relevant if the operand is not a column, it
defaults to the current type if not provided. defaults to the current type if not provided.
@ -116,6 +131,11 @@ type Column
## PRIVATE ## PRIVATE
Helper for implementing unary operators. Helper for implementing unary operators.
Arguments:
- op_kind: The kind of the unary operator.
- new_type: The type of the SQL column that results from applying the
operator.
make_unary_op : Text -> Text -> (Sql_Type | Nothing) -> Column make_unary_op : Text -> Text -> (Sql_Type | Nothing) -> Column
make_unary_op op_kind new_type=Nothing = make_unary_op op_kind new_type=Nothing =
actual_new_type = if new_type.is_nothing then this.sql_type else new_type actual_new_type = if new_type.is_nothing then this.sql_type else new_type
@ -147,6 +167,12 @@ type Column
mean = this.compute_aggregate "AVG" mean = this.compute_aggregate "AVG"
## PRIVATE ## PRIVATE
Computes an aggregate operator.
Arguments:
- op_name: The name of the operator to compute.
compute_aggregate : Text
compute_aggregate op_name = compute_aggregate op_name =
agg = here.make_aggregate this op_name agg = here.make_aggregate this op_name
agg.to_vector . at 0 agg.to_vector . at 0
@ -171,109 +197,159 @@ type Column
## UNSTABLE ## UNSTABLE
Element-wise equality comparison. Returns a column with results of Element-wise equality comparison.
comparing this column's elements against `other`.
If `other` is a column, the comparison is performed pairwise between Arguments:
corresponding elements of `this` and `other`. - other: The other column to compare pairwise with.
Returns a column with results of comparing this column's elements against
`other`. If `other` is a column, the comparison is performed pairwise
between corresponding elements of `this` and `other`.
== : Column | Any -> Column == : Column | Any -> Column
== other = this.make_binary_op "=" other new_type=Sql_Type.boolean == other = this.make_binary_op "=" other new_type=Sql_Type.boolean
## UNSTABLE ## UNSTABLE
Element-wise non-equality comparison. Returns a column with results of Element-wise non-equality comparison.
comparing this column's elements against `other`.
If `other` is a column, the comparison is performed pairwise between Arguments:
corresponding elements of `this` and `other`. - other: The other column to compare pairwise with.
Returns a column with results of comparing this column's elements against
`other`. If `other` is a column, the comparison is performed pairwise
between corresponding elements of `this` and `other`.
!= : Column | Any -> Column != : Column | Any -> Column
!= other = this.make_binary_op "!=" other new_type=Sql_Type.boolean != other = this.make_binary_op "!=" other new_type=Sql_Type.boolean
## UNSTABLE ## UNSTABLE
Element-wise order comparison. Returns a column with results of Element-wise order comparison.
comparing this column's elements against `other`.
If `other` is a column, the comparison is performed pairwise between Arguments:
corresponding elements of `this` and `other`. - other: The other column to compare pairwise with.
Returns a column with results of comparing this column's elements against
`other`. If `other` is a column, the comparison is performed pairwise
between corresponding elements of `this` and `other`.
>= : Column | Any -> Column >= : Column | Any -> Column
>= other = this.make_binary_op ">=" other new_type=Sql_Type.boolean >= other = this.make_binary_op ">=" other new_type=Sql_Type.boolean
## UNSTABLE ## UNSTABLE
Element-wise order comparison. Returns a column with results of Element-wise order comparison.
comparing this column's elements against `other`.
If `other` is a column, the comparison is performed pairwise between Arguments:
corresponding elements of `this` and `other`. - other: The other column to compare pairwise with.
Returns a column with results of comparing this column's elements against
`other`. If `other` is a column, the comparison is performed pairwise
between corresponding elements of `this` and `other`.
<= : Column | Any -> Column <= : Column | Any -> Column
<= other = this.make_binary_op "<=" other new_type=Sql_Type.boolean <= other = this.make_binary_op "<=" other new_type=Sql_Type.boolean
## UNSTABLE ## UNSTABLE
Element-wise order comparison. Returns a column with results of Element-wise order comparison.
comparing this column's elements against `other`.
If `other` is a column, the comparison is performed pairwise between Arguments:
corresponding elements of `this` and `other`. - other: The other column to compare pairwise with.
Returns a column with results of comparing this column's elements against
`other`. If `other` is a column, the comparison is performed pairwise
between corresponding elements of `this` and `other`.
> : Column | Any -> Column > : Column | Any -> Column
> other = this.make_binary_op ">" other new_type=Sql_Type.boolean > other = this.make_binary_op ">" other new_type=Sql_Type.boolean
## UNSTABLE ## UNSTABLE
Element-wise order comparison. Returns a column with results of Element-wise order comparison.
comparing this column's elements against `other`.
If `other` is a column, the comparison is performed pairwise between Arguments:
corresponding elements of `this` and `other`. - other: The other column to compare pairwise with.
Returns a column with results of comparing this column's elements against
`other`. If `other` is a column, the comparison is performed pairwise
between corresponding elements of `this` and `other`.
< : Column | Any -> Column < : Column | Any -> Column
< other = this.make_binary_op "<" other new_type=Sql_Type.boolean < other = this.make_binary_op "<" other new_type=Sql_Type.boolean
## UNSTABLE ## UNSTABLE
Element-wise addition. Returns a column containing the result Element-wise addition.
of adding `other` to each element of `this`.
If `other` is a column, the operation is performed pairwise between Arguments:
corresponding elements of `this` and `other`. - other: The other column to add to this column.
Returns a column containing the result of adding `other` to each element
of `this`. If `other` is a column, the operation is performed pairwise
between corresponding elements of `this` and `other`.
+ : Column | Any -> Column + : Column | Any -> Column
+ other = this.make_binary_op "+" other + other = this.make_binary_op "+" other
## UNSTABLE ## UNSTABLE
Element-wise subtraction. Returns a column containing the result Element-wise subtraction.
of subtracting `other` from each element of `this`.
If `other` is a column, the operation is performed pairwise between Arguments:
corresponding elements of `this` and `other`. - other: The other column to subtract from this column.
Returns a column containing the result of subtracting `other` from each
element of `this`. If `other` is a column, the operation is performed
pairwise between corresponding elements of `this` and `other`.
- : Column | Any -> Column - : Column | Any -> Column
- other = this.make_binary_op "-" other - other = this.make_binary_op "-" other
## UNSTABLE ## UNSTABLE
Element-wise multiplication. Returns a column containing the result Element-wise multiplication.
of multiplying `other` by each element of `this`.
If `other` is a column, the operation is performed pairwise between Arguments:
corresponding elements of `this` and `other`. - other: The other column to multiply `this` by.
Returns a column containing the result of multiplying `other` by each
element of `this`. If `other` is a column, the operation is performed
pairwise between corresponding elements of `this` and `other`.
* : Column | Any -> Column * : Column | Any -> Column
* other = this.make_binary_op "*" other * other = this.make_binary_op "*" other
## UNSTABLE ## UNSTABLE
Element-wise division. Returns a column containing the result Element-wise division.
of dividing each element of `this` by `other`.
If `other` is a column, the operation is performed pairwise between Arguments:
corresponding elements of `this` and `other`. - other: The other column to divide `this` column by.
Returns a column containing the result of dividing each element of `this`
by `other`. If `other` is a column, the operation is performed pairwise
between corresponding elements of `this` and `other`.
/ : Column | Any -> Column / : Column | Any -> Column
/ other = this.make_binary_op "/" other / other = this.make_binary_op "/" other
## UNSTABLE ## UNSTABLE
Element-wise boolean conjunction. Returns a column containing the result Element-wise boolean conjunction.
of performing the boolean `and` on `other` and each element of `this`.
If `other` is a column, the operation is performed pairwise between Arguments:
corresponding elements of `this` and `other`. - other: The other column to compute the conjunction with.
Returns a column containing the result of performing the boolean `and` on
`other` and each element of `this`. If `other` is a column, the
operation is performed pairwise between corresponding elements of `this` ]
and `other`.
&& : Column | Any -> Column && : Column | Any -> Column
&& other = this.make_binary_op "AND" other && other = this.make_binary_op "AND" other
## UNSTABLE ## UNSTABLE
Element-wise boolean disjunction. Returns a column containing the result Element-wise boolean disjunction.
of performing the boolean `or` on `other` and each element of `this`.
If `other` is a column, the operation is performed pairwise between Arguments:
corresponding elements of `this` and `other`. - other: The other column to compute the disjunction with.
Returns a column containing the result of performing the boolean `or` on
`other` and each element of `this`. If `other` is a column, the
operation is performed pairwise between corresponding elements of `this`
and `other`.
|| : Column | Any -> Column || : Column | Any -> Column
|| other = this.make_binary_op "OR" other || other = this.make_binary_op "OR" other
@ -300,8 +376,13 @@ type Column
## UNSTABLE ## UNSTABLE
Selects only the rows of this column that correspond to `True` values in Selects only the rows of this column that correspond to `True` values in
`indexes`. `filter`.
Arguments:
- filter: A column of booleans to mask `this` by.
This is useful for filtering the rows by given predicate. This is useful for filtering the rows by given predicate.
> Example > Example
Select only the rows of `my_column` where the `status_column` column Select only the rows of `my_column` where the `status_column` column
has the value `"Valid"` has the value `"Valid"`
@ -325,6 +406,9 @@ type Column
## UNSTABLE ## UNSTABLE
Returns the same column with changed name. Returns the same column with changed name.
Arguments:
- new_name: The name to rename `this` column to.
rename : Text -> Column rename : Text -> Column
rename new_name = case Helpers.ensure_name_is_sane new_name of rename new_name = case Helpers.ensure_name_is_sane new_name of
True -> True ->
@ -339,8 +423,8 @@ type Column
Sorts the column according to the specified rules. Sorts the column according to the specified rules.
Arguments: Arguments:
- order: specifies the default sort order for this operation. - order: Specifies the default sort order for this operation.
- missing_last: specifies the default placement of missing values when - missing_last: Specifies the default placement of missing values when
compared to non-missing ones. Note thet this argument is independent compared to non-missing ones. Note thet this argument is independent
from `order`, i.e. missing values will always be sorted according to from `order`, i.e. missing values will always be sorted according to
this rule, ignoring the ascending / descending setting. this rule, ignoring the ascending / descending setting.
@ -360,33 +444,42 @@ type Column
## UNSTABLE ## UNSTABLE
Checks for each element of the column if it starts with `other`. Checks for each element of the column if it starts with `other`.
If `other` is a column, the operation is performed pairwise between
corresponding elements of `this` and `other`.
If the argument is a missing value (a Nothing or a column with missing Arguments:
values), the behaviour on these missing values is vendor specific. - other: A column or text to check for each item in `this`.
If `other` is a column, the operation is performed pairwise between
corresponding elements of `this` and `other`. If the argument is a
missing value (a Nothing or a column with missing values), the behaviour
on these missing values is vendor specific.
starts_with : Column | Text -> Column starts_with : Column | Text -> Column
starts_with other = this.make_binary_op "starts_with" other new_type=Sql_Type.boolean starts_with other = this.make_binary_op "starts_with" other new_type=Sql_Type.boolean
## UNSTABLE ## UNSTABLE
Checks for each element of the column if it ends with `other`. Checks for each element of the column if it ends with `other`.
If `other` is a column, the operation is performed pairwise between
corresponding elements of `this` and `other`.
If the argument is a missing value (a Nothing or a column with missing Arguments:
values), the behaviour on these missing values is vendor specific. - other: A column ot text to check for each item in `this`.
If `other` is a column, the operation is performed pairwise between
corresponding elements of `this` and `other`. If the argument is a
missing value (a Nothing or a column with missing values), the behaviour
on these missing values is vendor specific.
ends_with : Column | Text -> Column ends_with : Column | Text -> Column
ends_with other = this.make_binary_op "ends_with" other new_type=Sql_Type.boolean ends_with other = this.make_binary_op "ends_with" other new_type=Sql_Type.boolean
## UNSTABLE ## UNSTABLE
Checks for each element of the column if it contains `other`. Checks for each element of the column if it contains `other`.
If `other` is a column, the operation is performed pairwise between
corresponding elements of `this` and `other`.
If the argument is a missing value (a Nothing or a column with missing Arguments:
values), the behaviour on these missing values is vendor specific. - other: A column ot text to check for each item in `this`.
If `other` is a column, the operation is performed pairwise between
corresponding elements of `this` and `other`. If the argument is a
missing value (a Nothing or a column with missing values), the behaviour
on these missing values is vendor specific.
contains : Column | Text -> Column contains : Column | Text -> Column
contains other = this.make_binary_op "contains" other new_type=Sql_Type.boolean contains other = this.make_binary_op "contains" other new_type=Sql_Type.boolean
@ -395,13 +488,22 @@ type Column
as_internal = IR.Internal_Column this.name this.sql_type this.expression as_internal = IR.Internal_Column this.name this.sql_type this.expression
type Aggregate_Column type Aggregate_Column
## UNSTABLE ## UNSTABLE
Wraps a column grouped by its index. Allows performing aggregation operations Wraps a column grouped by its index.
on the contained values.
# type Aggregate_Column (name : Text) (connection : Connection) Arguments:
# (sql_type : Sql_Type) (expression : IR.Expression) - name: The name of the column.
# (context : IR.Context) - connection: The connection with which the column is associated.
- sql_type: The SQL type of the aggregate column.
- expression: The expressions to apply to the column.
- context: The SQl context in which the column exists.
Allows performing aggregation operations on the contained values.
# type Aggregate_Column (name : Text) (connection : Connection)
# (sql_type : Sql_Type) (expression : IR.Expression)
# (context : IR.Context)
type Aggregate_Column name connection sql_type expression context type Aggregate_Column name connection sql_type expression context
## UNSTABLE ## UNSTABLE
@ -409,8 +511,8 @@ type Aggregate_Column
Sums the values in each group. Sums the values in each group.
Arguments: Arguments:
- name_suffix: a suffix that will be appended to the original column - name_suffix: a suffix that will be appended to the original column name
name to generate the resulting column name. to generate the resulting column name.
sum : Text -> Column sum : Text -> Column
sum name_suffix='_sum' = sum name_suffix='_sum' =
here.make_aggregate this "SUM" name_suffix here.make_aggregate this "SUM" name_suffix
@ -420,8 +522,8 @@ type Aggregate_Column
Computes the maximum element of each group. Computes the maximum element of each group.
Arguments: Arguments:
- name_suffix: a suffix that will be appended to the original column - name_suffix: a suffix that will be appended to the original column name
name to generate the resulting column name. to generate the resulting column name.
max : Text -> Column max : Text -> Column
max name_suffix='_max' = max name_suffix='_max' =
here.make_aggregate this "MAX" name_suffix here.make_aggregate this "MAX" name_suffix
@ -431,8 +533,8 @@ type Aggregate_Column
Computes the minimum element of each group. Computes the minimum element of each group.
Arguments: Arguments:
- name_suffix: a suffix that will be appended to the original column - name_suffix: a suffix that will be appended to the original column name
name to generate the resulting column name. to generate the resulting column name.
min : Text -> Column min : Text -> Column
min name_suffix='_min' = min name_suffix='_min' =
here.make_aggregate this "MIN" name_suffix here.make_aggregate this "MIN" name_suffix
@ -442,8 +544,8 @@ type Aggregate_Column
Computes the number of non-missing elements in each group. Computes the number of non-missing elements in each group.
Arguments: Arguments:
- name_suffix: a suffix that will be appended to the original column - name_suffix: a suffix that will be appended to the original column name
name to generate the resulting column name. to generate the resulting column name.
count : Text -> Column count : Text -> Column
count name_suffix='_count' = count name_suffix='_count' =
here.make_aggregate this "COUNT" name_suffix new_type=Sql_Type.integer here.make_aggregate this "COUNT" name_suffix new_type=Sql_Type.integer
@ -453,15 +555,15 @@ type Aggregate_Column
Computes the mean of non-missing elements in each group. Computes the mean of non-missing elements in each group.
Arguments: Arguments:
- name_suffix: a suffix that will be appended to the original column - name_suffix: a suffix that will be appended to the original column name
name to generate the resulting column name. to generate the resulting column name.
mean : Text -> Column mean : Text -> Column
mean name_suffix='_mean' = mean name_suffix='_mean' =
here.make_aggregate this "AVG" name_suffix here.make_aggregate this "AVG" name_suffix
## PRIVATE ## PRIVATE
Helper that returns the underlying column from before grouping. A helper that returns the underlying column from before grouping.
ungrouped : Column ungrouped : Column
ungrouped = ungrouped =
new_ctx = this.context.set_groups [] new_ctx = this.context.set_groups []
@ -471,6 +573,13 @@ type Aggregate_Column
A helper method for creating an aggregated column by applying some A helper method for creating an aggregated column by applying some
operation. operation.
Arguments:
- column: The column to aggregate.
- operation: The name of the aggregation operation.
- name_suffix: The suffix to apply to the name of the aggregate column.
- new_type: The SQL type of the result column.
make_aggregate : Column -> Text -> Text -> Sql_Type -> Column
make_aggregate column operation name_suffix="_agg" new_type=Nothing = make_aggregate column operation name_suffix="_agg" new_type=Nothing =
actual_new_type = if new_type.is_nothing then column.sql_type else new_type actual_new_type = if new_type.is_nothing then column.sql_type else new_type
expr = IR.Operation operation [column.expression] expr = IR.Operation operation [column.expression]

View File

@ -15,14 +15,14 @@ type Dialect
Represents a specific SQL dialect. Represents a specific SQL dialect.
It encapsulates dialect-specific code generation details allowing us to
support differing SQL dialects.
Arguments: Arguments:
- name: name of the dialect. - name: name of the dialect.
- generate_sql: a function which generates SQL code from the internal - generate_sql: a function which generates SQL code from the internal
representation according to the specific dialect. representation according to the specific dialect.
# type Dialect (name : Text) (generate_sql : Query -> Sql.Statement)
It encapsulates dialect-specific code generation details allowing us to
support differing SQL dialects.
# type Dialect (name : Text) (generate_sql : Query -> Sql.Statement)
type Dialect name generate_sql type Dialect name generate_sql
## PRIVATE ## PRIVATE
@ -98,5 +98,7 @@ sqlite =
Dialect "sqlite" (query -> Base_Generator.generate_query dialect query . build) Dialect "sqlite" (query -> Base_Generator.generate_query dialect query . build)
## PRIVATE ## PRIVATE
A vector of SQL dialects supported by the Database library.
supported_dialects : Vector Dialect supported_dialects : Vector Dialect
supported_dialects = [here.postgresql, here.sqlite] supported_dialects = [here.postgresql, here.sqlite]

View File

@ -6,19 +6,21 @@ import Standard.Database.Data.Internal.IR
from Standard.Database.Data.Sql import Sql_Type from Standard.Database.Data.Sql import Sql_Type
type Internal_Dialect type Internal_Dialect
## PRIVATE ## PRIVATE
An internal representation of a SQL dialect. An internal representation of a SQL dialect.
Arguments: Arguments:
- operation_map: the mapping which maps operation names to their - operation_map: The mapping which maps operation names to their
implementations; each implementation is a function which takes SQL implementations; each implementation is a function which takes SQL
builders for the arguments and should return a builder yielding the builders for the arguments and should return a builder yielding the
whole operation. whole operation.
- wrap_identifier: a function that converts an arbitrary supported - wrap_identifier: A function that converts an arbitrary supported
identifier name in such a way that it can be used in the query; that identifier name in such a way that it can be used in the query; that
usually consists of wrapping the name in quotes and escaping any quotes usually consists of wrapping the name in quotes and escaping any quotes
within it. within it.
# type Internal_Dialect (operation_map : Map Text (Vector Sql.Builder -> Sql.Builder)) # type Internal_Dialect (operation_map : Map Text (Vector Sql.Builder -> Sql.Builder))
# (identifier_wrapper : Text -> Sql.Builder) # (identifier_wrapper : Text -> Sql.Builder)
type Internal_Dialect operation_map wrap_identifier type Internal_Dialect operation_map wrap_identifier
@ -27,7 +29,9 @@ type Internal_Dialect
Creates a copy of the dialect that supports additional operations or Creates a copy of the dialect that supports additional operations or
overrides existing ones. overrides existing ones.
# extend_with : Vector [Text, Vector Sql.Builder -> Sql.Builder] -> Internal_Dialect # extend_with : Vector [Text, Vector Sql.Builder -> Sql.Builder] -> Internal_Dialect
extend_with : Vector -> Internal_Dialect
extend_with mappings = extend_with mappings =
new_map = mappings.fold this.operation_map (m -> el -> m.insert (el.at 0) (el.at 1)) new_map = mappings.fold this.operation_map (m -> el -> m.insert (el.at 0) (el.at 1))
Internal_Dialect new_map this.wrap_identifier Internal_Dialect new_map this.wrap_identifier
@ -35,6 +39,9 @@ type Internal_Dialect
## PRIVATE ## PRIVATE
A helper function to create a binary operator. A helper function to create a binary operator.
Arguments:
- name: The name of the binary operator.
make_binary_op : Text -> Vector Sql.Builder -> Sql.Builder make_binary_op : Text -> Vector Sql.Builder -> Sql.Builder
make_binary_op name = make_binary_op name =
arguments -> arguments ->
@ -48,6 +55,9 @@ make_binary_op name =
## PRIVATE ## PRIVATE
A helper function to create a unary operator. A helper function to create a unary operator.
Arguments:
- name: The name of the unary operator.
make_unary_op : Text -> Vector Sql.Builder -> Sql.Builder make_unary_op : Text -> Vector Sql.Builder -> Sql.Builder
make_unary_op name = make_unary_op name =
arguments -> arguments ->
@ -61,6 +71,9 @@ make_unary_op name =
A helper function to create a unary operator which is added to the right of A helper function to create a unary operator which is added to the right of
the expression. the expression.
Arguments:
- name: The name of the unary operator.
make_right_unary_op : Text -> Vector Sql.Builder -> Sql.Builder make_right_unary_op : Text -> Vector Sql.Builder -> Sql.Builder
make_right_unary_op name = make_right_unary_op name =
arguments -> arguments ->
@ -73,6 +86,9 @@ make_right_unary_op name =
## PRIVATE ## PRIVATE
A helper function to create a functional operation. A helper function to create a functional operation.
Arguments:
- name: The name of the function.
make_function : Text -> Vector Sql.Builder -> Sql.Builder make_function : Text -> Vector Sql.Builder -> Sql.Builder
make_function name = make_function name =
arguments -> arguments ->
@ -81,6 +97,9 @@ make_function name =
## PRIVATE ## PRIVATE
A helper function to create an operation that takes no arguments. A helper function to create an operation that takes no arguments.
Arguments:
- code: The code for the constant.
make_constant : Text -> Vector Sql.Builder -> Sql.Builder make_constant : Text -> Vector Sql.Builder -> Sql.Builder
make_constant code = make_constant code =
arguments -> arguments ->
@ -90,8 +109,13 @@ make_constant code =
## PRIVATE ## PRIVATE
Wraps the identifier name in quotes and escapes any quotes within the name Wraps the identifier name in quotes and escapes any quotes within the name
with double-quote. This is the simplest way of escaping identifiers that with double-quote.
should work across most dialects.
Arguments:
- identifier: The identifier to wrap and escape.
This is the simplest way of escaping identifiers that should work across most
dialects.
wrap_in_quotes : Text -> Sql.Builder wrap_in_quotes : Text -> Sql.Builder
wrap_in_quotes identifier = wrap_in_quotes identifier =
escaped = identifier.replace '"' '""' escaped = identifier.replace '"' '""'
@ -118,6 +142,10 @@ base_dialect =
## PRIVATE ## PRIVATE
Builds code for an expression. Builds code for an expression.
Arguments:
- dialect: The SQL dialect in which the expression is being generated.
- expr: The expression to generate SQL code for.
generate_expression : Internal_Dialect -> IR.Expression -> Sql.Builder generate_expression : Internal_Dialect -> IR.Expression -> Sql.Builder
generate_expression dialect expr = case expr of generate_expression dialect expr = case expr of
IR.Column origin name -> IR.Column origin name ->
@ -133,6 +161,10 @@ generate_expression dialect expr = case expr of
Adds an alias for the expression, applicable for expressions that represent Adds an alias for the expression, applicable for expressions that represent
columns or sub-queries. columns or sub-queries.
Arguments:
- dialect: The dialect for which to add the alias.
- name: The name of the alias.
alias : Internal_Dialect -> Text -> Sql.Builder alias : Internal_Dialect -> Text -> Sql.Builder
alias dialect name = alias dialect name =
wrapped = dialect.wrap_identifier name wrapped = dialect.wrap_identifier name
@ -141,6 +173,10 @@ alias dialect name =
## PRIVATE ## PRIVATE
Builds code for the FROM clause. Builds code for the FROM clause.
Arguments:
- dialect: The SQL dialect for which the code is generated.
- from_spec: A description of the FROM clause.
generate_from_part : Internal_Dialect -> From_Spec -> Sql.Builder generate_from_part : Internal_Dialect -> From_Spec -> Sql.Builder
generate_from_part dialect from_spec = case from_spec of generate_from_part dialect from_spec = case from_spec of
IR.From_Table name as_name -> IR.From_Table name as_name ->
@ -162,7 +198,13 @@ generate_from_part dialect from_spec = case from_spec of
## PRIVATE ## PRIVATE
Builds code for an ordering. Builds code for an ordering.
Arguments:
- dialect: The SQL dialect for which the code is generated.
- order_description: A description of the ORDER clause.
# generate_order : Internal_Dialect -> [Expression, IR.Order_Direction, IR.Nulls_Order] -> Sql.Builder # generate_order : Internal_Dialect -> [Expression, IR.Order_Direction, IR.Nulls_Order] -> Sql.Builder
generate_order : Internal_Dialect -> Vector -> Sql.Builder
generate_order dialect order_description = generate_order dialect order_description =
order_suffix = case order_description.second of order_suffix = case order_description.second of
IR.Ascending -> Sql.code " ASC" IR.Ascending -> Sql.code " ASC"
@ -173,6 +215,12 @@ generate_order dialect order_description =
(here.generate_expression dialect (order_description.first)) ++ order_suffix ++ nulls_suffix (here.generate_expression dialect (order_description.first)) ++ order_suffix ++ nulls_suffix
## PRIVATE ## PRIVATE
Generates SQL code corresponding to a SELECT statement.
Arguments:
- dialect: The SQL dialect for which the code is being generated.
- ctx: A description of the SELECT clause.
generate_select_context : Internal_Dialect -> IR.Context -> Sql.Builder generate_select_context : Internal_Dialect -> IR.Context -> Sql.Builder
generate_select_context dialect ctx = generate_select_context dialect ctx =
gen_exprs exprs = exprs.map (here.generate_expression dialect) gen_exprs exprs = exprs.map (here.generate_expression dialect)
@ -188,6 +236,15 @@ generate_select_context dialect ctx =
(Sql.code " FROM ") ++ from_part ++ where_part ++ group_part ++ order_part ++ limit_part (Sql.code " FROM ") ++ from_part ++ where_part ++ group_part ++ order_part ++ limit_part
## PRIVATE ## PRIVATE
Generates the SQL code corresponding to an INSERT query.
Arguments:
- dialect: The SQL dialect for which the code is being generated.
- table_name: The name of the table into which the values are being inserted.
- pairs: The values to insert into the table, consisting of pairs of key, and
expression returning a value.
generate_insert_query : Internal_Dialect -> Text -> Vector -> Sql.Builder
generate_insert_query dialect table_name pairs = generate_insert_query dialect table_name pairs =
names = Sql.join ", " <| pairs.map (.first >> dialect.wrap_identifier) names = Sql.join ", " <| pairs.map (.first >> dialect.wrap_identifier)
values = Sql.join ", " <| pairs.map (.second >> here.generate_expression dialect) values = Sql.join ", " <| pairs.map (.second >> here.generate_expression dialect)
@ -198,6 +255,10 @@ generate_insert_query dialect table_name pairs =
## PRIVATE ## PRIVATE
Builds code for a whole query. Builds code for a whole query.
Arguments:
- dialect: The SQL dialect for which the code is being generated.
- query: An IR describing the query.
generate_query : Internal_Dialect -> IR.Query -> Sql.Builder generate_query : Internal_Dialect -> IR.Query -> Sql.Builder
generate_query dialect query = case query of generate_query dialect query = case query of
IR.Select columns ctx -> IR.Select columns ctx ->

View File

@ -10,6 +10,10 @@ polyglot java import java.util.regex.Pattern
Checks if the two tables or columns have the same context and use the same Checks if the two tables or columns have the same context and use the same
connection. connection.
Arguments:
- entity1: The entity to check against the second.
- entity2: The entity to check against the first.
To combine different objects they need to satisfy this requirement, otherwise To combine different objects they need to satisfy this requirement, otherwise
the combination would be ill-formed. the combination would be ill-formed.
check_integrity : (Table | Column) -> (Table | Column) -> Boolean check_integrity : (Table | Column) -> (Table | Column) -> Boolean
@ -20,9 +24,13 @@ check_integrity entity1 entity2 =
## PRIVATE ## PRIVATE
A helper function simplifying argument handling. It always returns a vector, A helper function simplifying argument handling.
if the argument was already a vector, it is kept as-is, otherwise it is
wrapped in a singleton vector. Arguments:
- x: A value that may or may not be a vector.
It always returns a vector, if the argument was already a vector, it is kept
as-is, otherwise it is wrapped in a singleton vector.
unify_vector_singleton : (Any | Vector.Vector Any) -> Vector.Vector Any unify_vector_singleton : (Any | Vector.Vector Any) -> Vector.Vector Any
unify_vector_singleton x = case x of unify_vector_singleton x = case x of
Vector.Vector _ -> x Vector.Vector _ -> x
@ -32,14 +40,25 @@ unify_vector_singleton x = case x of
Signals that a name for a column or table is not supported. Signals that a name for a column or table is not supported.
Arguments:
- text: The name that is not supported.
Currently the names can only include ASCII letters, numbers and the Currently the names can only include ASCII letters, numbers and the
underscore. This is a temporary limitation simplifying name handling. It will underscore. This is a temporary limitation simplifying name handling. It will
be removed in a future version. be removed in a future version.
type Unsupported_Name_Error text type Unsupported_Name_Error text
Unsupported_Name_Error.to_display_text : Text
Unsupported_Name_Error.to_display_text =
"The name " + this.text + " is not currently supported by the Database library."
## PRIVATE ## PRIVATE
This is used to check if the new name is safe for use in Sql queries. This is used to check if the new name is safe for use in Sql queries.
Arguments:
- name: The name to check for safety.
In a future version we will decouple the internal Sql-safe names from the In a future version we will decouple the internal Sql-safe names from the
external names shown to the user, but as a temporary solution we only allow external names shown to the user, but as a temporary solution we only allow
Sql-safe names for columns. Sql-safe names for columns.

View File

@ -6,6 +6,7 @@ from Standard.Base import all
reference, an interpolated constant or an operation that combines other reference, an interpolated constant or an operation that combines other
expressions. expressions.
type Expression type Expression
## PRIVATE ## PRIVATE
The internal representation of an SQL expression that gets a value from a The internal representation of an SQL expression that gets a value from a
@ -16,7 +17,7 @@ type Expression
originates from, it corresponds to the `alias` field in `from_spec`. originates from, it corresponds to the `alias` field in `from_spec`.
- name: the name of the column directly in the table or its alias in a - name: the name of the column directly in the table or its alias in a
sub-query. sub-query.
# type Column (origin : Text) (name : Text) # type Column (origin : Text) (name : Text)
type Column origin name type Column origin name
## PRIVATE ## PRIVATE
@ -50,9 +51,19 @@ type Internal_Column
## PRIVATE ## PRIVATE
An internal column structure. An internal column structure.
Arguments:
- name: The column name.
- sql_type: The SQL type of the column.
- expression: An expression for applying to the column.
type Internal_Column name sql_type expression type Internal_Column name sql_type expression
## PRIVATE ## PRIVATE
Rename the internal column.
Arguments:
- new_name: The new name for the column.
rename : Text -> Internal_Column rename : Text -> Internal_Column
rename new_name = Internal_Column new_name this.sql_type this.expression rename new_name = Internal_Column new_name this.sql_type this.expression
@ -83,15 +94,18 @@ type Context
- meta_index: a list of internal columns to use for joining or grouping. - meta_index: a list of internal columns to use for joining or grouping.
- limit: an optional maximum number of elements that the equery should - limit: an optional maximum number of elements that the equery should
return. return.
# type Context (from_spec : From_Spec) (where_filters : Vector Expression) # type Context (from_spec : From_Spec) (where_filters : Vector Expression)
# (orders : Vector [Expression, Order_Direction, Nulls_Order]) # (orders : Vector [Expression, Order_Direction, Nulls_Order])
# (groups : Vector Expression) (meta_index : Vector Internal_Column) # (groups : Vector Expression) (meta_index : Vector Internal_Column)
# (limit : Nothing | Integer) # (limit : Nothing | Integer)
type Context from_spec where_filters orders groups meta_index limit type Context from_spec where_filters orders groups meta_index limit
## PRIVATE ## PRIVATE
Returns a copy of the context with changed `meta_index`. Returns a copy of the context with changed `meta_index`.
Arguments:
- new_index: The new index to set in the query.
set_index : Vector Internal_Column -> Context set_index : Vector Internal_Column -> Context
set_index new_index = set_index new_index =
Context this.from_spec this.where_filters this.orders this.groups new_index this.limit Context this.from_spec this.where_filters this.orders this.groups new_index this.limit
@ -99,6 +113,9 @@ type Context
## PRIVATE ## PRIVATE
Returns a copy of the context with changed `where_filters`. Returns a copy of the context with changed `where_filters`.
Arguments:
- new_filters: The new filters to set in the query.
set_where_filters : Vector Expression -> Context set_where_filters : Vector Expression -> Context
set_where_filters new_filters = set_where_filters new_filters =
Context this.from_spec new_filters this.orders this.groups this.meta_index this.limit Context this.from_spec new_filters this.orders this.groups this.meta_index this.limit
@ -106,13 +123,20 @@ type Context
## PRIVATE ## PRIVATE
Returns a copy of the context with changed `orders`. Returns a copy of the context with changed `orders`.
# set_orders : Vector [Expression, Order_Direction] -> Context
Arguments:
- new_orders: The new ordering clauses to set in the query.
# set_orders : Vector [Expression, Order_Direction] -> Context
set_orders : Vector -> Context
set_orders new_orders = set_orders new_orders =
Context this.from_spec this.where_filters new_orders this.groups this.meta_index this.limit Context this.from_spec this.where_filters new_orders this.groups this.meta_index this.limit
## PRIVATE ## PRIVATE
Returns a copy of the context with changed `groups`. Returns a copy of the context with changed `groups`.
Arguments:
- new_groups: The new grouping clauses to set in the query.
set_groups : Vector Expression -> Context set_groups : Vector Expression -> Context
set_groups new_groups = set_groups new_groups =
Context this.from_spec this.where_filters this.orders new_groups this.meta_index this.limit Context this.from_spec this.where_filters this.orders new_groups this.meta_index this.limit
@ -120,6 +144,9 @@ type Context
## PRIVATE ## PRIVATE
Returns a copy of the context with changed `limit`. Returns a copy of the context with changed `limit`.
Arguments:
- new_limit: The new limit clauses to set in the query.
set_limit : (Nothing | Integer) -> Context set_limit : (Nothing | Integer) -> Context
set_limit new_limit = set_limit new_limit =
Context this.from_spec this.where_filters this.orders this.groups this.meta_index new_limit Context this.from_spec this.where_filters this.orders this.groups this.meta_index new_limit
@ -139,6 +166,7 @@ type Context
This is useful as a preprocessing step between combining queries, for example in a join. This is useful as a preprocessing step between combining queries, for example in a join.
# as_subquery : Text -> Vector (Vector Internal_Column) -> [IR.Sub_Query, Vector (Vector Internal_Column)] # as_subquery : Text -> Vector (Vector Internal_Column) -> [IR.Sub_Query, Vector (Vector Internal_Column)]
as_subquery : Text -> Vector -> Vector
as_subquery alias column_lists = as_subquery alias column_lists =
rewrite_internal_column : Internal_Column -> Internal_Column rewrite_internal_column : Internal_Column -> Internal_Column
rewrite_internal_column column = rewrite_internal_column column =
@ -169,7 +197,7 @@ type From_Spec
parts of the query, this is especially useful for example in parts of the query, this is especially useful for example in
self-joins, allowing to differentiate between different instances of self-joins, allowing to differentiate between different instances of
the same table. the same table.
# type From_Table (table_name : Text) (alias : Text) # type From_Table (table_name : Text) (alias : Text)
type From_Table table_name alias type From_Table table_name alias
## PRIVATE ## PRIVATE
@ -183,8 +211,8 @@ type From_Spec
- on: a list of expressions that will be used as join conditions, these - on: a list of expressions that will be used as join conditions, these
are usually be equalities between expressions from the left and right are usually be equalities between expressions from the left and right
sources. sources.
# type Join (kind : Join_Kind) (left_spec : From_Spec) # type Join (kind : Join_Kind) (left_spec : From_Spec)
# (right_spec : From_Spec) (on : Vector Expression) # (right_spec : From_Spec) (on : Vector Expression)
type Join kind left_spec right_spec on type Join kind left_spec right_spec on
## PRIVATE ## PRIVATE
@ -285,16 +313,19 @@ type Query
A Select SQL query. A Select SQL query.
Arguments: Arguments:
- expressions: list of pairs specifying the columns to materialize; each - expressions: List of pairs specifying the columns to materialize; each
is a pair whose first element is the name of the materialized column is a pair whose first element is the name of the materialized column
and the second element is the expression to compute. and the second element is the expression to compute.
- context: the query context, see `Context` for more detail. - context: The query context, see `Context` for more detail.
# type Select (expressions : [Text, Expression]) (context : Context) # type Select (expressions : [Text, Expression]) (context : Context)
type Select columns context type Select columns context
## PRIVATE ## PRIVATE
A Select SQL query that gets all columns in a table. A Select SQL query that gets all columns in a table.
Arguments:
- context: The query context, see `Context` for more detail.
type Select_All context type Select_All context
## PRIVATE ## PRIVATE
@ -302,14 +333,17 @@ type Query
An Insert SQL query that inserts a single row to the table. An Insert SQL query that inserts a single row to the table.
Arguments: Arguments:
- table_name: name of the table to insert to. - table_name: The name of the table to insert to.
- pairs: a list of pairs consisting of a column name and and expression. - pairs: A list of pairs consisting of a column name and and expression.
type Insert table_name pairs type Insert table_name pairs
## PRIVATE ## PRIVATE
Creates a query context that just fetches data from a table, without any Creates a query context that just fetches data from a table, without any
additional processing. additional processing.
Arguments:
- table_name: The name of the tanle for which the context is being created.
make_ctx_from : Text -> Context make_ctx_from : Text -> Context
make_ctx_from table_name = make_ctx_from table_name =
Context (From_Table table_name table_name) [] [] [] [] Nothing Context (From_Table table_name table_name) [] [] [] [] Nothing
@ -317,15 +351,25 @@ make_ctx_from table_name =
## PRIVATE ## PRIVATE
Creates an expression which is a simple constant to be interpolated. Creates an expression which is a simple constant to be interpolated.
Arguments:
- sql_type: The SQL type of the value.
- x: The value to turn into a constant.
make_constant : Sql.Sql_Type -> Any -> Expression make_constant : Sql.Sql_Type -> Any -> Expression
make_constant sql_type x = make_constant sql_type x =
Constant sql_type x Constant sql_type x
## PRIVATE ## PRIVATE
A helper function to subsitute names tables inside of expressions. It is used A helper function to subsitute names tables inside of expressions.
for example when renaming a table during a join.
substitute_origin : Text -> Text -> Expression Arguments:
- old_origin: The old table name.
- new_origin: The new table name.
- expr: The expression in which the substitution should be performed.
It is used for example when renaming a table during a join.
substitute_origin : Text -> Text -> Expression -> Expression
substitute_origin old_origin new_origin expr = case expr of substitute_origin old_origin new_origin expr = case expr of
Column origin name -> Column origin name ->
if origin == old_origin then Column new_origin name else expr if origin == old_origin then Column new_origin name else expr
@ -338,6 +382,10 @@ substitute_origin old_origin new_origin expr = case expr of
Lifts a function mapping expressions into a function mapping internal columns Lifts a function mapping expressions into a function mapping internal columns
which applies the original function to their expressions, leaving other which applies the original function to their expressions, leaving other
fields as-is. fields as-is.
Arguments:
- f: The function to map over expressions.
- col: The column over which to apply `f`.
lift_expression_map : (Expression -> Expression) -> Internal_Column -> Internal_Column lift_expression_map : (Expression -> Expression) -> Internal_Column -> Internal_Column
lift_expression_map f col = lift_expression_map f col =
Internal_Column col.name col.sql_type (f col.expression) Internal_Column col.name col.sql_type (f col.expression)

View File

@ -11,10 +11,23 @@ from Builtins import Array
is known in advance and the tree is traversed in order to create the is known in advance and the tree is traversed in order to create the
resulting vector without resizing it. resulting vector without resizing it.
type Vector_Builder type Vector_Builder
## PRIVATE ## PRIVATE
A leaf in the vector builder.
Arguments:
- vec: The vector at the leaf.
type Leaf vec type Leaf vec
## PRIVATE ## PRIVATE
A node that appends the two child nodes.
Arguments:
- left: The left subtree.
- right: The right subtree.
- len: The length of the vectors across the subtrees.
type Append left right len type Append left right len
## PRIVATE ## PRIVATE
@ -52,6 +65,9 @@ type Vector_Builder
Concatenates another builder or vector to this. Concatenates another builder or vector to this.
Arguments:
- other: The other vector to concatenate with `this`.
It returns a new builder that will yield a vector that is a concatenation It returns a new builder that will yield a vector that is a concatenation
of `this` and the argument. of `this` and the argument.
++ : Vector_Builder Any | Vector Any -> Vector_Builder Any ++ : Vector_Builder Any | Vector Any -> Vector_Builder Any
@ -71,5 +87,8 @@ empty = Leaf []
## PRIVATE ## PRIVATE
Creates a vector builder from a vector. Creates a vector builder from a vector.
Arguments:
- vec: The vector to create a vector builder from.
from_vector : Vector Any -> Vector_Builder Any from_vector : Vector Any -> Vector_Builder Any
from_vector vec = Leaf vec from_vector vec = Leaf vec

View File

@ -4,8 +4,54 @@ import Standard.Database.Data.Internal.Vector_Builder
polyglot java import java.sql.Types polyglot java import java.sql.Types
## UNSTABLE
Creates a Builder representing and empty code fragment.
empty : Builder
empty = Builder (Vector_Builder.empty)
## UNSTABLE
Creates a Builder representing a code fragment containing the specified raw
code.
Arguments:
- text: The raw SQL code.
code : Text -> Builder
code text =
vec = if text.is_empty then [] else [Sql_Code_Part text]
Builder (Vector_Builder.from_vector vec)
## UNSTABLE
Creates a Builder representing an interpolation of the given object.
Arguments:
- sql_type: The expected SQL type of `object`.
- object: The object to be interpolated into the query as if it has the type
given by `sql_type`.
interpolation : Sql_Type -> Any -> Builder
interpolation sql_type object = Builder (Vector_Builder.from_vector [Sql_Interpolation sql_type object])
## UNSTABLE
Joins a vector of code fragments with the provided separator.
Arguments:
- separator: The separator to use when joining the code fragments.
- statements: The SQL statements to join using `separator`.
join : Builder | Text -> Vector Builder -> Builder
join separator statements =
sep = case separator of
Builder _ -> separator
_ -> here.code separator
if statements.length == 0 then here.empty else
(1.up_to statements.length . fold (statements.at 0) acc-> i-> acc ++ sep ++ statements.at i)
## Represents an internal SQL data-type. ## Represents an internal SQL data-type.
type Sql_Type type Sql_Type
## Represents an internal SQL data-type. ## Represents an internal SQL data-type.
Arguments: Arguments:
@ -35,24 +81,29 @@ type Sql_Type
## PRIVATE ## PRIVATE
Returns True if this type represents an integer. It only handles the Returns True if this type represents an integer.
standard types so it may return false negatives for non-standard ones.
It only handles the standard types so it may return false negatives for
non-standard ones.
is_definitely_integer : Boolean is_definitely_integer : Boolean
is_definitely_integer = is_definitely_integer =
[Types.INTEGER, Types.SMALLINT, Types.TINYINT].contains this.typeid [Types.INTEGER, Types.SMALLINT, Types.TINYINT].contains this.typeid
## PRIVATE ## PRIVATE
Returns True if this type represents a boolean. It only handles the Returns True if this type represents a boolean.
standard types so it may return false negatives for non-standard ones.
It only handles the standard types so it may return false negatives for
non-standard ones.
is_definitely_boolean : Boolean is_definitely_boolean : Boolean
is_definitely_boolean = is_definitely_boolean =
[Types.BOOLEAN, Types.BIT].contains this.typeid [Types.BOOLEAN, Types.BIT].contains this.typeid
## PRIVATE ## PRIVATE
Returns True if this type represents a floating point number. It only Returns True if this type represents a floating point number.
handles the standard types so it may return false negatives for
It only handles the standard types so it may return false negatives for
non-standard ones. non-standard ones.
is_definitely_double : Boolean is_definitely_double : Boolean
is_definitely_double = is_definitely_double =
@ -67,35 +118,51 @@ type Sql_Type
## UNSTABLE ## UNSTABLE
A fragment of a SQL query. A fragment of a SQL query.
It can either be a Sql_Code_Part that represents raw SQL code or It can either be a Sql_Code_Part that represents raw SQL code or
Sql_Interpolation which represents an object that will be interpolated into Sql_Interpolation which represents an object that will be interpolated into
the query. the query.
type Sql_Fragment type Sql_Fragment
## UNSTABLE ## UNSTABLE
A SQL fragment that represents raw SQL code. A SQL fragment that represents raw SQL code.
# type Sql_Code_Part (code : Text)
Arguments:
- code: A fragment of SQL code.
# type Sql_Code_Part (code : Text)
type Sql_Code_Part code type Sql_Code_Part code
## UNSTABLE ## UNSTABLE
A SQL fragment that represents an object which will be interpolated into A SQL fragment that represents an object which will be interpolated into
the query. the query.
# type Sql_Interpolation (sql_type : Sql_Type) (object : Any)
Arguments:
- sql_type: The expected SQL type of `object`.
- object: A value that will be interpolated into the query, interpreted
as having the type `sql_type`.
# type Sql_Interpolation (sql_type : Sql_Type) (object : Any)
type Sql_Interpolation sql_type object type Sql_Interpolation sql_type object
type Statement type Statement
## UNSTABLE ## UNSTABLE
Represents a built SQL statement. Represents a built SQL statement.
Arguments:
- internal_fragments: A vector of SQL code fragments.
The statement consists of SQL code with parameters and values that will be The statement consists of SQL code with parameters and values that will be
interpolated for these parameters. interpolated for these parameters.
# type Statement (internal_fragments : Vector Sql_Fragment) # type Statement (internal_fragments : Vector Sql_Fragment)
type Statement internal_fragments type Statement internal_fragments
## UNSTABLE ## UNSTABLE
A vector of code fragments. A vector of code fragments.
Consists of two types of values: Consists of two types of values:
- Sql_Code_Part, representing parts of raw SQL code and - Sql_Code_Part, representing parts of raw SQL code and
- Sql_Interpolation, representing objects that will be interpolated in - Sql_Interpolation, representing objects that will be interpolated in
@ -129,7 +196,7 @@ type Statement
Returns a pair consisting of the SQL code with holes for values and Returns a pair consisting of the SQL code with holes for values and
a list for values that should be substituted. a list for values that should be substituted.
# prepare : [Text, Vector Any] # prepare : [Text, Vector Any]
prepare = prepare =
to_code fragment = case fragment of to_code fragment = case fragment of
Sql_Code_Part code -> code Sql_Code_Part code -> code
@ -155,18 +222,25 @@ type Statement
Json.from_pairs [["query", fragments]] Json.from_pairs [["query", fragments]]
type Builder type Builder
## UNSTABLE
## PRIVATE
A Builder for SQL queries. A Builder for SQL queries.
It can be used to concatenate parts of SQL code in O(1) time and at the end Arguments:
build the actual query in linear time. - fragments: A builder that contains fragments of SQL code.
It can be used to concatenate parts of SQL code in O(1) time and at the
end build the actual query in linear time.
# type Builder (fragments : Vector_Builder.Vector_Builder Sql_Fragment) # type Builder (fragments : Vector_Builder.Vector_Builder Sql_Fragment)
type Builder fragments type Builder fragments
## UNSTABLE ## UNSTABLE
Concatenates two code fragments. Concatenates two code fragments.
Arguments:
- other: The code fragment to append to `this`.
++ : Builder -> Builder ++ : Builder -> Builder
++ other = Builder (this.fragments ++ other.fragments) ++ other = Builder (this.fragments ++ other.fragments)
@ -196,6 +270,10 @@ type Builder
## UNSTABLE ## UNSTABLE
If the fragment is non empty, prepends the specified prefix to it. If the fragment is non empty, prepends the specified prefix to it.
Arguments:
- prefix: The prefix to append if the fragment is present.
Empty fragments are unaffected. Empty fragments are unaffected.
prefix_if_present : Text | Builder -> Builder prefix_if_present : Text | Builder -> Builder
prefix_if_present prefix = prefix_if_present prefix =
@ -204,43 +282,13 @@ type Builder
_ -> here.code prefix _ -> here.code prefix
if this.is_empty then this else pref++this if this.is_empty then this else pref++this
## UNSTABLE ## PRIVATE
Creates a Builder representing and empty code fragment.
empty : Builder
empty = Builder (Vector_Builder.empty)
## UNSTABLE
Creates a Builder representing a code fragment containing the specified raw
code.
code : Text -> Builder
code text =
vec = if text.is_empty then [] else [Sql_Code_Part text]
Builder (Vector_Builder.from_vector vec)
## UNSTABLE
Creates a Builder representing an interpolation of the given object.
interpolation : Sql_Type -> Any -> Builder
interpolation sql_type object = Builder (Vector_Builder.from_vector [Sql_Interpolation sql_type object])
## UNSTABLE
Joins a vector of code fragments with the provided separator.
join : Builder | Text -> Vector Builder -> Builder
join separator statements =
sep = case separator of
Builder _ -> separator
_ -> here.code separator
if statements.length == 0 then here.empty else
(1.up_to statements.length . fold (statements.at 0) acc-> i-> acc ++ sep ++ statements.at i)
## UNSTABLE
Merges neighboring code fragments to create a more compact representation of Merges neighboring code fragments to create a more compact representation of
the same code. the same code.
Arguments:
- fragments: The fragments to be merged together.
optimize_fragments : Vector Sql_Fragment -> Vector Sql_Fragment optimize_fragments : Vector Sql_Fragment -> Vector Sql_Fragment
optimize_fragments fragments = optimize_fragments fragments =
builder = Vector.new_builder builder = Vector.new_builder

View File

@ -16,12 +16,19 @@ polyglot java import java.sql.JDBCType
## Represents a column-oriented table data structure backed by a database. ## Represents a column-oriented table data structure backed by a database.
type Table type Table
## PRIVATE ## PRIVATE
Represents a column-oriented table data structure backed by a database. Represents a column-oriented table data structure backed by a database.
# type Table (name : Text) (connection : Connection)
# (internal_columns : Vector Internal_Column) Arguments:
# (context : IR.Context) - name: The name of the table.
- connection: The connection with whicg the table is associated.
- internal_columns: The internal representation of the table columns.
- context: The context associated with this table.
# type Table (name : Text) (connection : Connection)
# (internal_columns : Vector Internal_Column)
# (context : IR.Context)
type Table name connection internal_columns context type Table name connection internal_columns context
## UNSTABLE ## UNSTABLE
@ -50,7 +57,7 @@ type Table
## UNSTABLE ## UNSTABLE
Converts this table to a JSON structure. Converts this table into a JSON structure.
to_json : Json to_json : Json
to_json = case this.internal_columns.is_empty of to_json = case this.internal_columns.is_empty of
True -> True ->
@ -60,15 +67,23 @@ type Table
## UNSTABLE ## UNSTABLE
Returns the column with the given name. Returns the column with the given name.
at : Text -> Column ! UnknownColumnError
Arguments:
- name: The name of the column to get.
at : Text -> Column ! No_Such_Column_Error
at name = at name =
internal = this.internal_columns.find (p -> p.name == name) internal = this.internal_columns.find (p -> p.name == name)
this.make_column internal . map_error (_ -> No_Such_Column_Error name) this.make_column internal . map_error (_ -> No_Such_Column_Error name)
## PRIVATE ## PRIVATE
Resolves the column name to a column within this table. If instead of a
name, a column is provided, it is returned as-is as long as it comes from Resolves the column name to a column within this table.
the same context.
Arguments:
- column: The name (or column handle) for the column you want to resolve.
If instead of a name, a column is provided, it is returned as-is as long
as it comes from the same context.
resolve : Text | Column -> Column resolve : Text | Column -> Column
resolve column = case column of resolve column = case column of
Text -> Panic.rethrow (this.at column) Text -> Panic.rethrow (this.at column)
@ -80,7 +95,13 @@ type Table
Selects only the rows of this table that correspond to `True` values in Selects only the rows of this table that correspond to `True` values in
`filter`. `filter`.
Arguments:
- filter: A column of boolean values that will be used to mask the table
rows.
This is useful for filtering the rows by given predicate. This is useful for filtering the rows by given predicate.
> Example > Example
Select only the rows of `my_table` where the `"Status"` column has the Select only the rows of `my_table` where the `"Status"` column has the
value `"Valid"` value `"Valid"`
@ -100,6 +121,9 @@ type Table
Returns a new Table that will include at most `max_rows` rows from the Returns a new Table that will include at most `max_rows` rows from the
original Table. original Table.
Arguments:
- max_rows: The maximum number of rows to get from the table.
Since this Table is backed by an SQL database, the Table returned by the Since this Table is backed by an SQL database, the Table returned by the
`limit` method is deterministic only if the Table has been ordered (using `limit` method is deterministic only if the Table has been ordered (using
the `sort` method). the `sort` method).
@ -129,8 +153,14 @@ type Table
## UNSTABLE ## UNSTABLE
Sets the column value at the given name. If a column with the given name Sets the column value at the given name.
already exists, it will be replaced. Otherwise a new column is added.
Arguments:
- name: The name of the column to set.
- column: The new value for the column called `name`.
If a column with the given name already exists, it will be replaced.
Otherwise a new column is added.
set : Text -> Column -> Table set : Text -> Column -> Table
set name column = case Helpers.ensure_name_is_sane name of set name column = case Helpers.ensure_name_is_sane name of
True -> True ->
@ -156,6 +186,9 @@ type Table
## UNSTABLE ## UNSTABLE
Sets the index of this table, using the column with the provided name. Sets the index of this table, using the column with the provided name.
Arguments:
- index: The column to use as the index of the table.
set_index : Text | Column | Vector Text -> Table set_index : Text | Column | Vector Text -> Table
set_index index = Panic.recover <| set_index index = Panic.recover <|
new_index = (Helpers.unify_vector_singleton index).map (this.at >> .as_internal) new_index = (Helpers.unify_vector_singleton index).map (this.at >> .as_internal)
@ -174,7 +207,9 @@ type Table
## UNSTABLE ## UNSTABLE
Returns the index (or indexes) of this table, as a column (indexed by itself). Returns the index (or indexes) of this table, as a column (indexed by
itself).
Throws `No_Index_Set_Error` if there is no index set. Throws `No_Index_Set_Error` if there is no index set.
index : Column | Vector Column ! Materialized_Table.No_Index_Set_Error index : Column | Vector Column ! Materialized_Table.No_Index_Set_Error
index = index =
@ -188,26 +223,26 @@ type Table
Sorts the table according to the specified rules. Sorts the table according to the specified rules.
Arguments: Arguments:
- by: specifies the columns used for reordering the table. This - by: Specifies the columns used for reordering the table. This
argument may be one of: argument may be one of:
- a text: the text is treated as a column name. - a text: The text is treated as a column name.
- a column: any column, which is an expression computed from this - a column: Any column, which is an expression computed from this
table. table.
- an order rule: specifies both the sorting column and additional - an order rule: Specifies both the sorting column and additional
settings, that will take precedence over the global parameters of settings, that will take precedence over the global parameters of
this sort operation. The `column` field of the rule may be a text this sort operation. The `column` field of the rule may be a text
or a column, with the semantics described above. or a column, with the semantics described above.
- a vector of any of the above: this will result in a hierarchical - a vector of any of the above: This will result in a hierarchical
sorting, such that the first rule is applied first, the second is sorting, such that the first rule is applied first, the second is
used for breaking ties, etc. used for breaking ties, etc.
- order: specifies the default sort order for this operation. All the - order: Specifies the default sort order for this operation. All the
rules specified in the `by` argument will default to this setting, rules specified in the `by` argument will default to this setting,
unless specified in the rule. unless specified in the rule.
- missing_last: specifies the default placement of missing values when - missing_last: Specifies the default placement of missing values when
compared to non-missing ones. This setting may be overriden by the compared to non-missing ones. This setting may be overriden by the
particular rules of the `by` argument. Note thet this argument is particular rules of the `by` argument. Note thet this argument is
independent from `order`, i.e. missing values will always be sorted independent from `order`, i.e. missing values will always be sorted
according to this rule, ignoring the ascending / descending setting. according to this rule, ignoring the ascending / descending setting.
> Example > Example
Sorting `table` in ascending order by the value in column `'Quantity'` Sorting `table` in ascending order by the value in column `'Quantity'`
@ -261,6 +296,9 @@ type Table
## UNSTABLE ## UNSTABLE
Selects a subset of columns from this table by name. Selects a subset of columns from this table by name.
Arguments:
- columns: The names of the columns to select from the table.
select : Vector Text -> Table select : Vector Text -> Table
select columns = select columns =
find_col = (name -> this.internal_columns.find (p -> p.name == name)) find_col = (name -> this.internal_columns.find (p -> p.name == name))
@ -271,21 +309,21 @@ type Table
Efficiently joins two tables based on either the index or a key column. Efficiently joins two tables based on either the index or a key column.
Arguments:
- other: the table being the right operand of this join operation.
- on: the column(s) or expression(s) of `this` that should be used as
the join key. If this argument is not provided, the index of `this`
will be used.
- drop_unmatched: whether the rows of `this` without corresponding
matches in `other` should be dropped from the result.
- left_suffix: a suffix that should be added to the columns of `this`
when there's a name conflict with a column of `other`.
- right_suffix: a suffix that should be added to the columns of `other`
when there's a name conflict with a column of `this`.
The resulting table contains rows of `this` extended with rows of The resulting table contains rows of `this` extended with rows of
`other` with matching indexes. If the index in `other` is not unique, `other` with matching indexes. If the index in `other` is not unique,
the corresponding rows of `this` will be duplicated in the result. the corresponding rows of `this` will be duplicated in the result.
Arguments:
- other: the table being the right operand of this join operation.
- on: the column(s) or expression(s) of `this` that should be used as
the join key. If this argument is not provided, the index of `this`
will be used.
- drop_unmatched: whether the rows of `this` without corresponding
matches in `other` should be dropped from the result.
- left_suffix: a suffix that should be added to the columns of `this`
when there's a name conflict with a column of `other`.
- right_suffix: a suffix that should be added to the columns of `other`
when there's a name conflict with a column of `this`.
join : Table | Column -> Nothing | Text | Column | Vector (Text | Column) -> Boolean -> Text -> Text -> Table join : Table | Column -> Nothing | Text | Column | Vector (Text | Column) -> Boolean -> Text -> Text -> Table
join other on=Nothing drop_unmatched=False left_suffix='_left' right_suffix='_right' = case other of join other on=Nothing drop_unmatched=False left_suffix='_left' right_suffix='_right' = case other of
Column _ _ _ _ _ -> this.join other.to_table on drop_unmatched left_suffix right_suffix Column _ _ _ _ _ -> this.join other.to_table on drop_unmatched left_suffix right_suffix
@ -365,7 +403,9 @@ type Table
Returns an aggregate table resulting from grouping the elements by the Returns an aggregate table resulting from grouping the elements by the
value of the specified column. value of the specified column.
If the `by` argument is not set, the index is used for grouping instead. Arguments:
- by: The column names on which to group. If this is not set, the index
will be used for grouping instead.
group : Vector Text | Text | Nothing -> Aggregate_Table group : Vector Text | Text | Nothing -> Aggregate_Table
group by=Nothing = Panic.recover <| group by=Nothing = Panic.recover <|
cols = case by of cols = case by of
@ -481,6 +521,9 @@ type Table
## PRIVATE ## PRIVATE
Helper to create columns from internal columns. Helper to create columns from internal columns.
Arguments:
- internal: The internal column to use for creating a column.
make_column : Internal_Column -> Column make_column : Internal_Column -> Column
make_column internal = make_column internal =
Column internal.name this.connection internal.sql_type internal.expression this.context Column internal.name this.connection internal.sql_type internal.expression this.context
@ -488,11 +531,19 @@ type Table
## PRIVATE ## PRIVATE
Returns a copy of this table with updated internal columns. Returns a copy of this table with updated internal columns.
Arguments:
- columns: The columns with which to update this table.
updated_columns : Vector Colums -> Table
updated_columns columns = Table this.name this.connection columns this.context updated_columns columns = Table this.name this.connection columns this.context
## PRIVATE ## PRIVATE
Returns a copy of this table with updated context. Returns a copy of this table with updated context.
Arguments:
- ctx: The new context for this table.
updated_context : Context -> Table
updated_context ctx = Table this.name this.connection this.internal_columns ctx updated_context ctx = Table this.name this.connection this.internal_columns ctx
## PRIVATE ## PRIVATE
@ -506,12 +557,14 @@ type Table
## PRIVATE ## PRIVATE
Inserts a new row to the table. It actually modifies the underlying table Inserts a new row to the table.
in the database.
It can only be called on the Table if no operations modifying it have Arguments:
been performed like modifying, removing or adding columns, filtering, - values: The values making up the row of the table.
grouping etc.
It actually modifies the underlying table in the database. It can only
be called on the Table if no operations modifying it have been performed
like modifying, removing or adding columns, filtering, grouping etc.
insert : Vector Any -> Nothing insert : Vector Any -> Nothing
insert values = insert values =
table_name = case this.context.from_spec of table_name = case this.context.from_spec of
@ -533,9 +586,15 @@ type Aggregate_Table
## UNSTABLE ## UNSTABLE
Represents a table with grouped rows. Represents a table with grouped rows.
# type Aggregate_Table (name : Text) (connection : Connection)
# (internal_columns : Vector [Text, IR.Expression]) Arguments:
# (context : IR.Context) - name: The name of the table.
- connection: The connection with whicg the table is associated.
- internal_columns: The internal representation of the table columns.
- context: The context associated with this table.
# type Aggregate_Table (name : Text) (connection : Connection)
# (internal_columns : Vector [Text, IR.Expression])
# (context : IR.Context)
type Aggregate_Table name connection internal_columns context type Aggregate_Table name connection internal_columns context
## UNSTABLE ## UNSTABLE
@ -555,6 +614,9 @@ type Aggregate_Table
## UNSTABLE ## UNSTABLE
Returns an aggregate column with the given name, contained in this table. Returns an aggregate column with the given name, contained in this table.
Arguments:
- name: The name of the aggregate column to get from the aggregate table.
at : Text -> Column ! No_Such_Column_Error at : Text -> Column ! No_Such_Column_Error
at name = at name =
internal = this.internal_columns.find (p -> p.name == name) internal = this.internal_columns.find (p -> p.name == name)
@ -563,7 +625,10 @@ type Aggregate_Table
## PRIVATE ## PRIVATE
Helper to create aggregate columns from internal columns. Helper to create aggregate columns from internal columns.
# make_column : Internal_Column -> Aggregate_Column
Arguments:
- internal: The internal column to make into an aggregate column.
make_column : Internal_Column -> Aggregate_Column
make_column internal = make_column internal =
Aggregate_Column internal.name this.connection internal.sql_type internal.expression this.context Aggregate_Column internal.name this.connection internal.sql_type internal.expression this.context
@ -579,6 +644,7 @@ type Aggregate_Table
Table this.name this.connection new_cols new_ctx Table this.name this.connection new_cols new_ctx
type Integrity_Error type Integrity_Error
## UNSTABLE ## UNSTABLE
Signalizes that an operation tried using objects coming from different Signalizes that an operation tried using objects coming from different
@ -591,10 +657,19 @@ type Integrity_Error
to_text : Text to_text : Text
to_text = this.object_description + " comes from a different context." to_text = this.object_description + " comes from a different context."
to_display_text : Text
to_display_text = this.to_text
## PRIVATE ## PRIVATE
Creates a Table out of a connection, name and list of column names. Creates a Table out of a connection, name and list of column names.
# make_table : Connection -> Text -> Vector [Text, Sql.Sql_Type] -> Table
Arguments:
- connection: The connection to a database.
- table_name: The name of the table to get.
- columns: The names of the columns to get.
# make_table : Connection -> Text -> Vector [Text, Sql.Sql_Type] -> Table
make_table : Connection -> Text -> Vector -> Table
make_table connection table_name columns = make_table connection table_name columns =
ctx = IR.make_ctx_from table_name ctx = IR.make_ctx_from table_name
cols = columns.map (p -> Internal_Column p.first p.second (IR.Column table_name p.first)) cols = columns.map (p -> Internal_Column p.first p.second (IR.Column table_name p.first))
@ -606,15 +681,15 @@ make_table connection table_name columns =
contains a fragment of the underlying data and count of all rows. contains a fragment of the underlying data and count of all rows.
Arguments: Arguments:
- df: the materialized dataframe that contains the data to be displayed, it - df: The materialized dataframe that contains the data to be displayed, it
should have no indices set. should have no indices set.
- indices_count: indicates how many columns from the materialized dataframe - indices_count: Indicates how many columns from the materialized dataframe
should be treated as indices in the display (index columns will be bold if should be treated as indices in the display (index columns will be bold if
`format_terminal` is enabled). `format_terminal` is enabled).
- all_rows_count: the count of all rows in the underlying Table; if - all_rows_count: The count of all rows in the underlying Table; if
`all_rows_count` is bigger than the amount of rows of `df`, an additional `all_rows_count` is bigger than the amount of rows of `df`, an additional
line will be included that will say how many hidden rows there are. line will be included that will say how many hidden rows there are.
- format_term: a boolean flag, specifying whether to use ANSI escape codes - format_term: A boolean flag, specifying whether to use ANSI escape codes
for rich formatting in the terminal. for rich formatting in the terminal.
display_dataframe : Materialized_Table.Table -> Integer -> Integer -> Boolean -> Text display_dataframe : Materialized_Table.Table -> Integer -> Integer -> Boolean -> Text
display_dataframe df indices_count all_rows_count format_terminal = display_dataframe df indices_count all_rows_count format_terminal =
@ -636,6 +711,12 @@ display_dataframe df indices_count all_rows_count format_terminal =
Creates a list of non-colliding names by merging the two lists and Creates a list of non-colliding names by merging the two lists and
appending suffixes if necessary. appending suffixes if necessary.
Arguments:
- left_names: The names on the left.
- right_names: The names on the right.
- left_suffix: The suffix to apply to colliding names on the left.
- right_suffix: The suffix to apply to colliding names on the right.
If even after appending the suffixes it is impossible to have unique names, If even after appending the suffixes it is impossible to have unique names,
it throws a panic. It returns two vectors, one for each input. It assumes it throws a panic. It returns two vectors, one for each input. It assumes
that the names within each argument itself are unique. that the names within each argument itself are unique.
@ -668,9 +749,15 @@ combine_names left_names right_names left_suffix right_suffix =
## PRIVATE ## PRIVATE
Transforms `preferred_names` names in such a way to not collide with `used_names`. If a name Transforms `preferred_names` names in such a way to not collide with
from `preferred_names` does not collide with others, it is kept as is, otherwise numerical `used_names`.
suffixes are added.
Arguments:
- used_names: The names that have already been used.
- preferred_names: The names that the user wants to use.
If a name from `preferred_names` does not collide with others, it is kept as
is, otherwise numerical suffixes are added.
fresh_names : Vector Text -> Vector Text -> Vector Text fresh_names : Vector Text -> Vector Text -> Vector Text
fresh_names used_names preferred_names = fresh_names used_names preferred_names =
freshen currently_used name ix = freshen currently_used name ix =
@ -686,7 +773,12 @@ fresh_names used_names preferred_names =
## PRIVATE ## PRIVATE
Transforms the vector of columns, changing names of each column to the corresponding name from the second vector. Transforms the vector of columns, changing names of each column to the
corresponding name from the second vector.
Arguments:
- columns: A vector of columns to rename.
- new_names: The new names for the columns.
rename_columns : Vector Internal_Column -> Vector Text -> Vector Internal_Column rename_columns : Vector Internal_Column -> Vector Text -> Vector Internal_Column
rename_columns columns new_names = rename_columns columns new_names =
columns.zip new_names col-> name-> columns.zip new_names col-> name->
@ -694,8 +786,15 @@ rename_columns columns new_names =
## PRIVATE ## PRIVATE
Ensures that the provided columns do not clash with the vector of names provided as first argument. Ensures that the provided columns do not clash with the vector of names
Original column names are kept if possible, but if they would clash, the columns are renamed. provided as first argument.
Arguments:
- used_names: The already used names.
- columns: The columns to rename to avoid clashes.
Original column names are kept if possible, but if they would clash, the
columns are renamed.
freshen_columns : Vector Text -> Vector Column -> Vector Column freshen_columns : Vector Text -> Vector Column -> Vector Column
freshen_columns used_names columns = freshen_columns used_names columns =
fresh_names = here.fresh_names used_names (columns.map .name) fresh_names = here.fresh_names used_names (columns.map .name)

View File

@ -6,9 +6,13 @@ from Standard.Base import all
type Object_Type type Object_Type
## PRIVATE ## PRIVATE
A Geo JSON feature.
type Feature type Feature
## PRIVATE ## PRIVATE
A Geo JSON feature collection.
type Feature_Collection type Feature_Collection
## PRIVATE ## PRIVATE

View File

@ -30,7 +30,10 @@ type Write_Flag
## UNSTABLE ## UNSTABLE
For a JPEG, this can be a quality from 0 to 100 (the higher, the better). Sets the quality used when writing a JPEG.
Arguments:
- value: A quality value from 0 to 100 (the higher, the better).
type Write_Jpeg_Quality value=95 type Write_Jpeg_Quality value=95
## UNSTABLE ## UNSTABLE
@ -45,25 +48,36 @@ type Write_Flag
## UNSTABLE ## UNSTABLE
Separate luma quality level, 0 - 100. Sets the luma quality level used when writing a JPEG.
Arguments:
- value: A quality value from 0 to 100 (the higher, the better).
type Write_Jpeg_Luma_Quality value=0 type Write_Jpeg_Luma_Quality value=0
## UNSTABLE ## UNSTABLE
Separate chroma quality level, 0 - 100. Sets the chroma quality level used when writing a JPEG.
Arguments:
- value: A quality value from 0 to 100 (the higher, the better).
type Write_Jpeg_Chroma_Quality value=0 type Write_Jpeg_Chroma_Quality value=0
## UNSTABLE ## UNSTABLE
For PNG, it can be the compression level from 0 to 9. A higher value Sets the compression level used when writing a PNG.
means a smaller size and longer compression time.
Arguments:
- value: A compression level from 0 to 9. A higher value means a smaller
size but a longer compression time.
type Write_Png_Compression value=3 type Write_Png_Compression value=3
## UNSTABLE ## UNSTABLE
For WEBP, this is a quality from 1 to 100 (the higher, the better). Sets the quality used when writing a WEBP image.
By default (without any parameter) and for quality above 100 the lossless
compression is used. Arguments:
- value: A quality from 0 to 100 (the higher, the better). A quality
above 100 indicates that the encoder should use lossless compression.
type Write_Webp_Quality value=101 type Write_Webp_Quality value=101
## UNSTABLE ## UNSTABLE
@ -74,8 +88,8 @@ type Write_Flag
`Read_Alpha_Channel` flag is specified. `Read_Alpha_Channel` flag is specified.
Arguments: Arguments:
- `location`: the file to read. - location: the file to read.
- `flags`: the read flags. - flags: the read flags.
> Example > Example
Read the image. Read the image.
@ -107,6 +121,10 @@ read location flags=[] =
Write an image to a file. Write an image to a file.
Arguments:
- location: The location to write the image to.
- flags: A vector of flags that control how the image is written.
> Example > Example
Write the image with applying png compression. Write the image with applying png compression.
Codecs.write path image Codecs.write path image
@ -131,3 +149,4 @@ Image.Image.write location flags=[] =
case e of case e of
Polyglot_Error _ -> Panic.throw (File.Io_Error ('Failed to write to the file at ' + path + '.')) Polyglot_Error _ -> Panic.throw (File.Io_Error ('Failed to write to the file at ' + path + '.'))
err -> Panic.throw err err -> Panic.throw err

View File

@ -11,6 +11,10 @@ type Histogram
## UNSTABLE ## UNSTABLE
The histogram of a single image channel. The histogram of a single image channel.
Arguments:
- channel: The channel in the image for which this is a histogram.
- data: The histogram data.
type Histogram channel data type Histogram channel data
## UNSTABLE ## UNSTABLE
@ -26,7 +30,7 @@ type Histogram
Create a histogram for the specified channel of the image. Create a histogram for the specified channel of the image.
Arguments: Arguments:
`channel`: the channel number. - channel: the channel number.
> Example > Example
Create a histogram. Create a histogram.

View File

@ -13,6 +13,9 @@ type Image
The image data type. The image data type.
Arguments:
- opencv_mat: The underlying matrix that stores the image data.
The image is represented with a matrix of rows x columns. Each The image is represented with a matrix of rows x columns. Each
pixel is represented with a vector of 1 to 4 values (channels). pixel is represented with a vector of 1 to 4 values (channels).
Pixel values are normalized in a range [0.0 .. 1.0]. Pixel values are normalized in a range [0.0 .. 1.0].
@ -41,8 +44,8 @@ type Image
Get the pixel value indexed by row and column. Get the pixel value indexed by row and column.
Arguments: Arguments:
- `row`: the row index. - row: the row index.
- `column`: the column index. - column: the column index.
> Example > Example
Get the value at the specified row and column. Get the value at the specified row and column.
@ -61,11 +64,9 @@ type Image
## UNSTABLE ## UNSTABLE
Calculates the per-element sum of an image and a scalar or a matrix. Calculates the per-element sum of an image and a scalar or a matrix.
Matrix should have the same dimensions as the image.
Arguments: Arguments:
- value: A value can be a number, a vector of numbers, or a matrix. The
- `value`: A value can be a number, a vector of numbers, or a matrix. The
number value is applied to each pixel's channel of the image. The number value is applied to each pixel's channel of the image. The
vector value is padded with zeros to match the number of channels and vector value is padded with zeros to match the number of channels and
then applied to each image's pixel. The matrix value must have the same then applied to each image's pixel. The matrix value must have the same
@ -75,6 +76,8 @@ type Image
appropriate pixel (the element with the same row and column) of this appropriate pixel (the element with the same row and column) of this
image. image.
The matrix should have the same dimensions as the image.
> Example > Example
Add the constant to an image. Operation will add 0.1 to each channel Add the constant to an image. Operation will add 0.1 to each channel
of the image. of the image.
@ -93,10 +96,9 @@ type Image
## UNSTABLE ## UNSTABLE
Calculates the per-element difference between an image and a scalar or a matrix. Calculates the per-element difference between an image and a scalar or a matrix.
Matrix should have the same dimensions as the image.
Arguments: Arguments:
- `value`: A value can be a number, a vector of numbers, or a matrix. The - value: A value can be a number, a vector of numbers, or a matrix. The
number value is applied to each pixel's channel of the image. The number value is applied to each pixel's channel of the image. The
vector value is padded with zeros to match the number of channels and vector value is padded with zeros to match the number of channels and
then applied to each image's pixel. The matrix value must have the same then applied to each image's pixel. The matrix value must have the same
@ -106,6 +108,8 @@ type Image
appropriate pixel (the element with the same row and column) of this appropriate pixel (the element with the same row and column) of this
image. image.
The matrix should have the same dimensions as the image.
> Example > Example
Subtract 0.5 from each channel of the image. Subtract 0.5 from each channel of the image.
image - 0.5 image - 0.5
@ -123,10 +127,9 @@ type Image
## UNSTABLE ## UNSTABLE
Calculates the per-element product of an image and a scalar or a matrix. Calculates the per-element product of an image and a scalar or a matrix.
Matrix should have the same dimensions as the image.
Arguments: Arguments:
- `value`: A value can be a number, a vector of numbers, or a matrix. The - value: A value can be a number, a vector of numbers, or a matrix. The
number value is applied to each pixel's channel of the image. The number value is applied to each pixel's channel of the image. The
vector value is padded with zeros to match the number of channels and vector value is padded with zeros to match the number of channels and
then applied to each image's pixel. The matrix value must have the same then applied to each image's pixel. The matrix value must have the same
@ -136,6 +139,8 @@ type Image
appropriate pixel (the element with the same row and column) of this appropriate pixel (the element with the same row and column) of this
image. image.
The matrix should have the same dimensions as the image.
> Example > Example
Multiply each channel of the image by 2. Multiply each channel of the image by 2.
image * 2 image * 2
@ -158,10 +163,9 @@ type Image
## UNSTABLE ## UNSTABLE
Performs per-element division of an image and a scalar or a matrix. Performs per-element division of an image and a scalar or a matrix.
Matrix should have the same dimensions as the image.
Arguments: Arguments:
- `value`: A value can be a number, a vector of numbers, or a matrix. The - value: A value can be a number, a vector of numbers, or a matrix. The
number value is applied to each pixel's channel of the image. The number value is applied to each pixel's channel of the image. The
vector value is padded with zeros to match the number of channels and vector value is padded with zeros to match the number of channels and
then applied to each image's pixel. The matrix value must have the same then applied to each image's pixel. The matrix value must have the same
@ -171,6 +175,8 @@ type Image
appropriate pixel (the element with the same row and column) of this appropriate pixel (the element with the same row and column) of this
image. image.
The matrix should have the same dimensions as the image.
> Example > Example
Divide each channel of the image by 2. Divide each channel of the image by 2.
image / 2 image / 2
@ -194,7 +200,7 @@ type Image
Check the equality of two images. Check the equality of two images.
Arguments: Arguments:
- `that`: the matrix to compare with. - that: the matrix to compare with.
? Implementation Note ? Implementation Note
Two images considered equal when they have the same number of rows, Two images considered equal when they have the same number of rows,
@ -233,11 +239,12 @@ type Image
Create an image from the array of values. Create an image from the array of values.
Arguments: Arguments:
- `values`: the vector of numbers. - values: the vector of numbers.
- `rows`: the number of rows in the resulting image. - rows: the number of rows in the resulting image.
- `channels`: the number of channels in the resulting image. - channels: the number of channels in the resulting image.
The function expects the array of normalized values in a range of [0.0 .. 1.0]. The function expects the array of normalized values to have each value in
the range of [0.0 .. 1.0].
> Example > Example
Create an image from the vector. Create an image from the vector.

View File

@ -8,6 +8,13 @@ polyglot java import org.opencv.core.Mat
polyglot java import org.opencv.core.Scalar polyglot java import org.opencv.core.Scalar
## PRIVATE ## PRIVATE
Apply a core matrix operation.
Arguments:
- mat: The matrix to operate on.
- value: The value to apply to the matrix.
- function: The function with which to apply `value` to `mat`.
core_op : Mat -> Any -> (Mat -> Scalar -> Mat -> Nothing) -> Nothing core_op : Mat -> Any -> (Mat -> Scalar -> Mat -> Nothing) -> Nothing
core_op mat value function = core_op mat value function =
result = Mat.new result = Mat.new
@ -22,6 +29,12 @@ core_op mat value function =
Image.Image result Image.Image result
## PRIVATE ## PRIVATE
Handles errors in `core_op`.
Arguments:
- error: The value to throw as an error.
core_op_handler : Any
core_op_handler error = core_op_handler error =
case error of case error of
Matrix.Dimensions_Not_Equal -> Error.throw error Matrix.Dimensions_Not_Equal -> Error.throw error

View File

@ -12,13 +12,22 @@ type Matrix_Error
## UNSTABLE ## UNSTABLE
Indicates that a matrix has been accessed with an illegal index. Indicates that a matrix has been accessed with an illegal index.
Arguments:
- rows: The number of rows in the matrix.
- columns: The number of columns in the matrix.
- index: The requested index in the matrix.
type Index_Out_Of_Bounds_Error rows columns index type Index_Out_Of_Bounds_Error rows columns index
## UNSTABLE ## UNSTABLE
Indicates that operation has failed. An error indicating that an operation has failed due to a mismatch of
matrix dimensions.
type Dimensions_Not_Equal type Dimensions_Not_Equal
## UNSTABLE
Pretty-prints a matrix error to be readable by the users.
to_display_text : Text to_display_text : Text
to_display_text = case this of to_display_text = case this of
Index_Out_Of_Bounds_Error rows columns index -> Index_Out_Of_Bounds_Error rows columns index ->
@ -33,6 +42,9 @@ type Matrix
The matrix data type. The matrix data type.
Arguments:
- opencv_mat: The internal representation of the matrix.
Each value of the matrix is represented with an array of Each value of the matrix is represented with an array of
channels. In contrast to an Image data type, Matrix values are channels. In contrast to an Image data type, Matrix values are
not normalized. not normalized.
@ -59,8 +71,8 @@ type Matrix
Get the matrix value at the specified row and column. Get the matrix value at the specified row and column.
Arguments: Arguments:
- `row`: the row index. - row: the row index.
- `column`: the column index. - column: the column index.
> Example > Example
Get the value at the specified row and column. Get the value at the specified row and column.
@ -81,8 +93,8 @@ type Matrix
Reshape the matrix specifying new number of rows and channels. Reshape the matrix specifying new number of rows and channels.
Arguments: Arguments:
- `rows`: the new number of rows. - rows: the new number of rows.
- `channels`: the new number of channels. - channels: the new number of channels.
> Example > Example
Reshape the matrix to a new shape of 3 rows and 1 column, with 1 channel. Reshape the matrix to a new shape of 3 rows and 1 column, with 1 channel.
@ -98,7 +110,7 @@ type Matrix
Calculates the per-element sum of two matrices or a matrix and a scalar. Calculates the per-element sum of two matrices or a matrix and a scalar.
Arguments: Arguments:
- `value`: A value can be a number, a vector of numbers, or a matrix. The - value: A value can be a number, a vector of numbers, or a matrix. The
number value is applied to each values's channel of the matrix. The number value is applied to each values's channel of the matrix. The
vector value is padded with zeros to match the number of channels and vector value is padded with zeros to match the number of channels and
then applied to each pixel of this matrix. The matrix value must have then applied to each pixel of this matrix. The matrix value must have
@ -124,10 +136,11 @@ type Matrix
## UNSTABLE ## UNSTABLE
Calculates the per-element difference of two matrices or of a matrix and a scalar. Calculates the per-element difference of two matrices or of a matrix and
a scalar.
Arguments: Arguments:
- `value`: A value can be a number, a vector of numbers, or a matrix. The - value: A value can be a number, a vector of numbers, or a matrix. The
number value is applied to each values's channel of the matrix. The number value is applied to each values's channel of the matrix. The
vector value is padded with zeros to match the number of channels and vector value is padded with zeros to match the number of channels and
then applied to each pixel of this matrix. The matrix value must have then applied to each pixel of this matrix. The matrix value must have
@ -153,10 +166,11 @@ type Matrix
## UNSTABLE ## UNSTABLE
Calculates the per-element product of two matrices or a matrix and a scalar. Calculates the per-element product of two matrices or a matrix and a
scalar.
Arguments: Arguments:
- `value`: A value can be a number, a vector of numbers, or a matrix. The - value: A value can be a number, a vector of numbers, or a matrix. The
number value is applied to each values's channel of the matrix. The number value is applied to each values's channel of the matrix. The
vector value is padded with zeros to match the number of channels and vector value is padded with zeros to match the number of channels and
then applied to each pixel of this matrix. The matrix value must have then applied to each pixel of this matrix. The matrix value must have
@ -190,7 +204,7 @@ type Matrix
Performs per-element division of two matrices or a matrix and a scalar. Performs per-element division of two matrices or a matrix and a scalar.
Arguments: Arguments:
- `value`: A value can be a number, a vector of numbers, or a matrix. The - value: A value can be a number, a vector of numbers, or a matrix. The
number value is applied to each values's channel of the matrix. The number value is applied to each values's channel of the matrix. The
vector value is padded with zeros to match the number of channels and vector value is padded with zeros to match the number of channels and
then applied to each pixel of this matrix. The matrix value must have then applied to each pixel of this matrix. The matrix value must have
@ -219,7 +233,7 @@ type Matrix
Check the equality of two matrices. Check the equality of two matrices.
Arguments: Arguments:
- `that`: the matrix to compare with. - that: the matrix to compare with.
? Implementation Note ? Implementation Note
Two matrices considered equal when they have the same number of rows, Two matrices considered equal when they have the same number of rows,
@ -234,8 +248,8 @@ type Matrix
the matrix becomes `max_value`. the matrix becomes `max_value`.
Arguments: Arguments:
- `min_value`: the minimum value in the resulting normalized range. - min_value: the minimum value in the resulting normalized range.
- `max_value`: the maximum value in the resulting normalized range. - max_value: the maximum value in the resulting normalized range.
> Example > Example
Normalize a matrix from vector. Normalize a matrix from vector.
@ -277,9 +291,9 @@ type Matrix
Create a matrix with all elements set to zero. Create a matrix with all elements set to zero.
Arguments: Arguments:
- `rows`: the number of rows in the resulting matrix. - rows: the number of rows in the resulting matrix.
- `columns`: the number of columns in the resulitng matrix. - columns: the number of columns in the resulitng matrix.
- `channels`: the number of channels in the resulting matrix. - channels: the number of channels in the resulting matrix.
> Example > Example
Create a matrix. Create a matrix.
@ -293,9 +307,9 @@ zeros rows columns channels=1 =
Create a matrix with all elements set to one. Create a matrix with all elements set to one.
Arguments: Arguments:
- `rows`: the number of rows in the resulting matrix. - rows: the number of rows in the resulting matrix.
- `columns`: the number of columns in the resulitng matrix. - columns: the number of columns in the resulitng matrix.
- `channels`: the number of channels in the resulting matrix. - channels: the number of channels in the resulting matrix.
> Example > Example
Create a matrix. Create a matrix.
@ -309,9 +323,9 @@ ones rows columns channels=1 =
Create an identity matrix containing ones on a main diagonal. Create an identity matrix containing ones on a main diagonal.
Arguments: Arguments:
- `rows`: the number of rows in the resulting matrix. - rows: the number of rows in the resulting matrix.
- `columns`: the number of columns in the resulitng matrix. - columns: the number of columns in the resulitng matrix.
- `channels`: the number of channels in the resulting matrix. - channels: the number of channels in the resulting matrix.
> Example > Example
Create a matrix. Create a matrix.
@ -325,9 +339,9 @@ identity rows columns channels=1 =
Create a matrix from the provided vector. Create a matrix from the provided vector.
Arguments: Arguments:
- `values`: the vector of numbers. - values: the vector of numbers.
- `rows`: the number of rows in the resulting matrix. - rows: the number of rows in the resulting matrix.
- `channels`: the number of channels in the resulting matrix. - channels: the number of channels in the resulting matrix.
> Example > Example
Create a matrix. Create a matrix.
@ -335,3 +349,4 @@ identity rows columns channels=1 =
from_vector : Vector -> Integer -> Integer -> Matrix from_vector : Vector -> Integer -> Integer -> Matrix
from_vector values rows=1 channels=1 = from_vector values rows=1 channels=1 =
Matrix (Java_Matrix.from_vector values.to_array channels rows) Matrix (Java_Matrix.from_vector values.to_array channels rows)

View File

@ -7,6 +7,13 @@ polyglot java import org.opencv.core.Mat
polyglot java import org.opencv.core.Scalar polyglot java import org.opencv.core.Scalar
## PRIVATE ## PRIVATE
Apply a core matrix operation.
Arguments:
- mat: The matrix to operate on.
- value: The value to apply to the matrix.
- function: The function with which to apply `value` to `mat`.
core_op : Mat -> Any -> (Mat -> Scalar -> Mat -> Nothing) -> Nothing core_op : Mat -> Any -> (Mat -> Scalar -> Mat -> Nothing) -> Nothing
core_op mat value function = core_op mat value function =
result = Mat.new result = Mat.new
@ -21,6 +28,11 @@ core_op mat value function =
Matrix.Matrix result Matrix.Matrix result
## PRIVATE ## PRIVATE
Handles errors in `core_op`.
Arguments:
- error: The value to throw as an error.
core_op_handler error = core_op_handler error =
case error of case error of
Matrix.Dimensions_Not_Equal -> Error.throw error Matrix.Dimensions_Not_Equal -> Error.throw error

View File

@ -0,0 +1,3 @@
from Standard.Base import all
from Standard.Base export all

View File

@ -16,23 +16,23 @@ from Standard.Table.Data.Order_Rule export Order_Rule
## Converts a JSON array into a dataframe, by looking up the requested keys ## Converts a JSON array into a dataframe, by looking up the requested keys
from each item. from each item.
Arguments:
- fields: a vector of texts representing the names of fields to look up.
The function assumes the elements have one of the following structures: The function assumes the elements have one of the following structures:
- a JSON object containing the requested keys. In case an item is not an - a JSON object containing the requested keys. In case an item is not an
object, or the request key does not exist, the relevant values of the table object, or the request key does not exist, the relevant values of the table
will be set to `Nothing`. will be set to `Nothing`.
- a GeoJSON object of type Feature. The format is described in rfc7946. - a GeoJSON object of type Feature. The format is described in rfc7946.
? Implementation Node ? Implementation Note
GeoJson support is partial. The GeoJson support is only partial.
- Supported geometry objects are Position and Point. Rows containing - Supported geometry objects are Position and Point. Rows containing
other geometry objects are not included in the resulting dataframe. other geometry objects are not included in the resulting dataframe.
- Position arrays are truncated to 3 elements: longitude, latitude - Position arrays are truncated to 3 elements: longitude, latitude
and elevation. and elevation.
- Nested properties are not supported and not included in the resulting - Nested properties are not supported and not included in the resulting
dataframe. dataframe.
Arguments:
- fields: a vector of texts representing the names of fields to look up.
Json.Array.to_table : Vector -> Table Json.Array.to_table : Vector -> Table
Json.Array.to_table fields = case this of Json.Array.to_table fields = case this of
Json.Array items -> Json.Array items ->
@ -48,21 +48,21 @@ Json.Array.to_table fields = case this of
## Converts a JSON object into a dataframe, by looking up the requested keys ## Converts a JSON object into a dataframe, by looking up the requested keys
from each item. from each item.
Arguments:
- fields: a vector of texts representing the names of fields to look up.
The function assumes the elements have one of the following structures: The function assumes the elements have one of the following structures:
- a GeoJSON object of type FeatureCollection. The format is described in - a GeoJSON object of type FeatureCollection. The format is described in
rfc7946. rfc7946.
? Implementation Node ? Implementation Note
GeoJson support is partial. The GeoJson support is only partial.
- Supported geometry objects are Position and Point. Rows containing - Supported geometry objects are Position and Point. Rows containing
other geometry objects are not included in the resulting dataframe. other geometry objects are not included in the resulting dataframe.
- Position arrays are truncated to 3 elements: longitude, latitude - Position arrays are truncated to 3 elements: longitude, latitude
and elevation. and elevation.
- Nested properties are not supported and not included in the resulting - Nested properties are not supported and not included in the resulting
dataframe. dataframe.
Arguments:
- fields: a vector of texts representing the names of fields to look up.
Json.Object.to_table : Vector -> Table ! Nothing Json.Object.to_table : Vector -> Table ! Nothing
Json.Object.to_table fields=Nothing = Json.Object.to_table fields=Nothing =
if this.get_type != Geo_Json.Feature_Collection.to_text then Error.throw Nothing else if this.get_type != Geo_Json.Feature_Collection.to_text then Error.throw Nothing else

View File

@ -6,14 +6,27 @@ import Standard.Table.Data.Storage
polyglot java import org.enso.table.data.table.Column as Java_Column polyglot java import org.enso.table.data.table.Column as Java_Column
polyglot java import org.enso.table.operations.OrderBuilder polyglot java import org.enso.table.operations.OrderBuilder
## Creates a new column given a name and a vector of elements.
Arguments:
- name: The name of the column to create.
- items: The elements to contain in the column.
from_vector : Text -> Vector -> Column
from_vector name items = Column (Java_Column.fromItems name items.to_array)
type Column type Column
## A representation of a column in a Table.
Arguments:
- java_column: The internal representation of the column.
type Column java_column type Column java_column
## Returns a text containing an ASCII-art table displaying this data. ## Returns a text containing an ASCII-art table displaying this data.
Arguments: Arguments:
- show_rows: the number of initial rows that should be displayed. - show_rows: the number of initial rows that should be displayed.
- format_terminal: whether ANSI-terminal formatting should be used - format_terminal: whether ANSI-terminal formatting should be used
display : Integer -> Boolean -> Text display : Integer -> Boolean -> Text
display show_rows=10 format_terminal=False = display show_rows=10 format_terminal=False =
java_col = this.java_column java_col = this.java_column
@ -34,97 +47,158 @@ type Column
## Prints an ASCII-art table with this data to the standard output. ## Prints an ASCII-art table with this data to the standard output.
Arguments: Arguments:
- show_rows: the number of initial rows that should be displayed. - show_rows: the number of initial rows that should be displayed.
print : Integer -> Nothing
print show_rows=10 = print show_rows=10 =
IO.println (this.display show_rows format_terminal=True) IO.println (this.display show_rows format_terminal=True)
IO.println '' IO.println ''
## Element-wise equality comparison. Returns a column with results of ## Element-wise equality comparison.
comparing this column's elements against `other`.
If `other` is a column, the comparison is performed pairwise between Arguments:
corresponding elements of `this` and `other`. - other: The value to compare `this` against. If `other` is a column, the
comparison is performed pairwise between corresponding elements of
`this` and `other`.
Returns a column with results of comparing this column's elements against
`other`.
== : Column | Any -> Column == : Column | Any -> Column
== other = == other =
here.run_vectorized_binary_op this "==" (==) other here.run_vectorized_binary_op this "==" (==) other
## Element-wise non-equality comparison. Returns a column with results of ## Element-wise non-equality comparison.
comparing this column's elements against `other`.
If `other` is a column, the comparison is performed pairwise between Arguments:
corresponding elements of `this` and `other`. - other: The value to compare `this` against. If `other` is a column, the
comparison is performed pairwise between corresponding elements of
`this` and `other`.
Returns a column with results of comparing this column's elements against
`other`.
!= : Column | Any -> Column != : Column | Any -> Column
!= other = (this == other).not != other = (this == other).not
## Element-wise order comparison. Returns a column with results of ## Element-wise order comparison.
comparing this column's elements against `other`.
If `other` is a column, the comparison is performed pairwise between Arguments:
corresponding elements of `this` and `other`. - other: The value to compare `this` against. If `other` is a column, the
comparison is performed pairwise between corresponding elements of
`this` and `other`.
Returns a column with results of comparing this column's elements against
`other`.
>= : Column | Any -> Column >= : Column | Any -> Column
>= other = >= other =
here.run_vectorized_binary_op this ">=" (>=) other here.run_vectorized_binary_op this ">=" (>=) other
## Element-wise order comparison. Returns a column with results of ## Element-wise order comparison.
comparing this column's elements against `other`.
If `other` is a column, the comparison is performed pairwise between Arguments:
corresponding elements of `this` and `other`. - other: The value to compare `this` against. If `other` is a column, the
comparison is performed pairwise between corresponding elements of
`this` and `other`.
Returns a column with results of comparing this column's elements against
`other`.
<= : Column | Any -> Column <= : Column | Any -> Column
<= other = <= other =
here.run_vectorized_binary_op this "<=" (<=) other here.run_vectorized_binary_op this "<=" (<=) other
## Element-wise order comparison. Returns a column with results of ## Element-wise order comparison.
comparing this column's elements against `other`.
If `other` is a column, the comparison is performed pairwise between Arguments:
corresponding elements of `this` and `other`. - other: The value to compare `this` against. If `other` is a column, the
comparison is performed pairwise between corresponding elements of
`this` and `other`.
Returns a column with results of comparing this column's elements against
`other`.
> : Column | Any -> Column > : Column | Any -> Column
> other = > other =
here.run_vectorized_binary_op this ">" (>) other here.run_vectorized_binary_op this ">" (>) other
## Element-wise order comparison. Returns a column with results of ## Element-wise order comparison.
comparing this column's elements against `other`.
If `other` is a column, the comparison is performed pairwise between Arguments:
corresponding elements of `this` and `other`. - other: The value to compare `this` against. If `other` is a column, the
comparison is performed pairwise between corresponding elements of
`this` and `other`.
Returns a column with results of comparing this column's elements against
`other`.
< : Column | Any -> Column < : Column | Any -> Column
< other = here.run_vectorized_binary_op this "<" (<) other < other = here.run_vectorized_binary_op this "<" (<) other
## Element-wise addition. Returns a column containing the result ## Element-wise addition.
of adding `other` to each element of `this`.
If `other` is a column, the operation is performed pairwise between Arguments:
corresponding elements of `this` and `other`. - other: The value to add to `this`. If `other` is a column, the addition
is performed pairwise between corresponding elements of `this` and
`other`.
Returns a column with results of adding `other` from each element of
`this`.
+ : Column | Any -> Column + : Column | Any -> Column
+ other = here.run_vectorized_binary_op this '+' (+) other + other = here.run_vectorized_binary_op this '+' (+) other
## Element-wise subtraction. Returns a column containing the result ## Element-wise subtraction.
of subtracting `other` from each element of `this`.
If `other` is a column, the operation is performed pairwise between Arguments:
corresponding elements of `this` and `other`. - other: The value to subtract from `this`. If `other` is a column, the
subtraction is performed pairwise between corresponding elements of
`this` and `other`.
Returns a column with results of subtracting `other` from each element of
`this`.
- : Column | Any -> Column - : Column | Any -> Column
- other = here.run_vectorized_binary_op this '-' (-) other - other = here.run_vectorized_binary_op this '-' (-) other
## Element-wise multiplication. Returns a column containing the result ## Element-wise multiplication.
of multiplying `other` by each element of `this`.
If `other` is a column, the operation is performed pairwise between Arguments:
corresponding elements of `this` and `other`. - other: The value to multiply `this` by. If `other` is a column, the
multiplication is performed pairwise between corresponding elements of
`this` and `other`.
Returns a column containing the result of multiplying each element of
`this` by `other`.
* : Column | Any -> Column * : Column | Any -> Column
* other = here.run_vectorized_binary_op this '*' (*) other * other = here.run_vectorized_binary_op this '*' (*) other
## Element-wise division. Returns a column containing the result ## Element-wise division.
of dividing each element of `this` by `other`.
If `other` is a column, the operation is performed pairwise between Arguments:
corresponding elements of `this` and `other`. - other: The value to divide `this` by. If `other` is a column, the
division is performed pairwise between corresponding elements of `this`
and `other`.
Returns a column containing the result of dividing each element of `this`
by `other`.
/ : Column | Any -> Column / : Column | Any -> Column
/ other = here.run_vectorized_binary_op this '/' (/) other / other = here.run_vectorized_binary_op this '/' (/) other
## Element-wise boolean conjunction. Returns a column containing the result ## Element-wise boolean conjunction.
of performing the boolean `and` on `other` and each element of `this`.
If `other` is a column, the operation is performed pairwise between Arguments:
corresponding elements of `this` and `other`. - other: The value to compute the conjunction of `this` with. If `other`
is a column, the conjunction is performed pairwise between
corresponding elements of `this` and `other`.
Returns a column containing the result of performing boolean `and` on
each element of `this` and `other`.
&& : Column | Any -> Column && : Column | Any -> Column
&& other = && other =
here.run_vectorized_binary_op this "&&" (&&) other here.run_vectorized_binary_op this "&&" (&&) other
## Element-wise boolean disjunction. Returns a column containing the result ## Element-wise boolean disjunction.
of performing the boolean `or` on `other` and each element of `this`.
If `other` is a column, the operation is performed pairwise between Arguments:
corresponding elements of `this` and `other`. - other: The value to compute the disjunction of `this` with. If `other`
is a column, the disjunction is performed pairwise between
corresponding elements of `this` and `other`.
Returns a column containing the result of performing the boolean `or` on
each element of `this` and `other`.
|| : Column | Any -> Column || : Column | Any -> Column
|| other = || other =
here.run_vectorized_binary_op this "||" (||) other here.run_vectorized_binary_op this "||" (||) other
@ -146,6 +220,9 @@ type Column
## Returns a new column where missing values have been replaced with the ## Returns a new column where missing values have been replaced with the
provided default. provided default.
Arguments:
- default: The value to replace missing values with.
fill_missing : Any -> Column fill_missing : Any -> Column
fill_missing default = fill_missing default =
storage = this.java_column.getStorage storage = this.java_column.getStorage
@ -161,28 +238,40 @@ type Column
this.where this.is_missing.not this.where this.is_missing.not
## Checks for each element of the column if it starts with `other`. ## Checks for each element of the column if it starts with `other`.
If `other` is a column, the operation is performed pairwise between
corresponding elements of `this` and `other`. Arguments:
- other: The value to compare `this` with. If `other` is a column, the
operation is performed pairwise between corresponding elements of
`this` and `other`.
starts_with : Column | Text -> Column starts_with : Column | Text -> Column
starts_with other = starts_with other =
here.run_vectorized_binary_op this "starts_with" (a -> b -> a.starts_with b) other here.run_vectorized_binary_op this "starts_with" (a -> b -> a.starts_with b) other
## Checks for each element of the column if it ends with `other`. ## Checks for each element of the column if it ends with `other`.
If `other` is a column, the operation is performed pairwise between
corresponding elements of `this` and `other`. Arguments:
- other: The value to compare `this` with. If `other` is a column, the
operation is performed pairwise between corresponding elements of
`this` and `other`.
ends_with : Column | Text -> Column ends_with : Column | Text -> Column
ends_with other = ends_with other =
here.run_vectorized_binary_op this "ends_with" (a -> b -> a.ends_with b) other here.run_vectorized_binary_op this "ends_with" (a -> b -> a.ends_with b) other
## Checks for each element of the column if it contains `other`. ## Checks for each element of the column if it contains `other`.
If `other` is a column, the operation is performed pairwise between
corresponding elements of `this` and `other`. Arguments:
- other: The value to compare `this` with. If `other` is a column, the
operation is performed pairwise between corresponding elements of
`this` and `other`.
contains : Column | Text -> Column contains : Column | Text -> Column
contains other = contains other =
here.run_vectorized_binary_op this "contains" (a -> b -> a.contains b) other here.run_vectorized_binary_op this "contains" (a -> b -> a.contains b) other
## Applies `function` to each item in this column and returns the column ## Applies `function` to each item in this column and returns the column
of results. of results.
Arguments:
- function: The function to apply to each element of `this` column.
map : (Any -> Any) -> Column map : (Any -> Any) -> Column
map function = map function =
storage = this.java_column.getStorage storage = this.java_column.getStorage
@ -193,6 +282,11 @@ type Column
## Applies `function` to consecutive pairs of elements of `this` and `that` ## Applies `function` to consecutive pairs of elements of `this` and `that`
and returns a column of results. and returns a column of results.
Arguments:
- that: The column to zip with `this`.
- function: A binary function that is applied to corresponding pairs of
elements of `this` and `that` to produce a value.
zip : Column -> (Any -> Any -> Any) -> Column zip : Column -> (Any -> Any -> Any) -> Column
zip that function = zip that function =
s1 = this.java_column.getStorage s1 = this.java_column.getStorage
@ -203,6 +297,10 @@ type Column
## Returns a new column, containing the same elements as `this`, but with ## Returns a new column, containing the same elements as `this`, but with
the given name. the given name.
Arguments:
- name: The new name for the column.
rename : Text -> Column
rename name = Column (this.java_column.rename name) rename name = Column (this.java_column.rename name)
## Returns the name of this column. ## Returns the name of this column.
@ -222,6 +320,7 @@ type Column
count = this.length - this.count_missing count = this.length - this.count_missing
## Returns the index of this column, as a column (indexed by itself). ## Returns the index of this column, as a column (indexed by itself).
Throws `No_Index_Set_Error` if there is no index set. Throws `No_Index_Set_Error` if there is no index set.
index : Column ! Table.No_Index_Set_Error index : Column ! Table.No_Index_Set_Error
index = case this.java_column.getIndex.toColumn of index = case this.java_column.getIndex.toColumn of
@ -230,11 +329,11 @@ type Column
## Returns the value contained in this column at the given index. ## Returns the value contained in this column at the given index.
Arguments:
- index: The index in the column from which to get the value.
If the value is an NA then this method returns nothing. If the index is If the value is an NA then this method returns nothing. If the index is
not an index in the column it returns an `Index_Out_Of_Bounds_Error`. not an index in the column it returns an `Index_Out_Of_Bounds_Error`.
Arguments:
- `index`: The index in the column from which to get the value
at : Integer -> (Any | Nothing) ! Index_Out_Of_Bounds_Error at : Integer -> (Any | Nothing) ! Index_Out_Of_Bounds_Error
at index = at index =
valid_index = (index >= 0) && (index < this.length) valid_index = (index >= 0) && (index < this.length)
@ -245,6 +344,11 @@ type Column
## Selects only the rows of this column that correspond to `True` values in ## Selects only the rows of this column that correspond to `True` values in
`indexes`. `indexes`.
Arguments:
- indexes: A column containing boolean values that is used to mask
`this`.
This is useful for filtering the rows by given predicate. This is useful for filtering the rows by given predicate.
> Example > Example
@ -288,21 +392,21 @@ type Column
## Efficiently joins two tables based on either the index or the specified ## Efficiently joins two tables based on either the index or the specified
key column. key column.
Arguments:
- other: the table being the right operand of this join operation.
- on: the column of `this` that should be used as the join key. If this
argument is not provided, the index of `this` will be used.
- drop_unmatched: whether the rows of `this` without corresponding
matches in `other` should be dropped from the result.
- left_suffix: a suffix that should be added to the columns of `this`
when there's a name conflict with a column of `other`.
- right_suffix: a suffix that should be added to the columns of `other`
when there's a name conflict with a column of `this`.
The resulting table contains rows of `this` extended with rows of The resulting table contains rows of `this` extended with rows of
`other` with matching indexes. If the index values in `other` are not `other` with matching indexes. If the index values in `other` are not
unique, the corresponding rows of `this` will be duplicated in the unique, the corresponding rows of `this` will be duplicated in the
result. result.
Arguments:
- other: the table being the right operand of this join operation.
- on: the column of `this` that should be used as the join key. If
this argument is not provided, the index of `this` will be used.
- drop_unmatched: whether the rows of `this` without corresponding
matches in `other` should be dropped from the result.
- left_suffix: a suffix that should be added to the columns of `this`
when there's a name conflict with a column of `other`.
- right_suffix: a suffix that should be added to the columns of `other`
when there's a name conflict with a column of `this`.
join : Table.Table | Column -> Text | Nothing -> Boolean -> Text -> Text -> Table join : Table.Table | Column -> Text | Nothing -> Boolean -> Text -> Text -> Table
join other on=Nothing drop_unmatched=False left_suffix='_left' right_suffix='_right' = join other on=Nothing drop_unmatched=False left_suffix='_left' right_suffix='_right' =
this.to_table.join other on drop_unmatched left_suffix right_suffix this.to_table.join other on drop_unmatched left_suffix right_suffix
@ -350,14 +454,14 @@ type Column
Sorts the column according to the specified rules. Sorts the column according to the specified rules.
Arguments: Arguments:
- order: specifies the default sort order for this operation. - order: specifies the default sort order for this operation.
- missing_last: specifies the default placement of missing values when - missing_last: specifies the default placement of missing values when
compared to non-missing ones. Note thet this argument is independent compared to non-missing ones. Note thet this argument is independent
from `order`, i.e. missing values will always be sorted according to from `order`, i.e. missing values will always be sorted according to
this rule, ignoring the ascending / descending setting. this rule, ignoring the ascending / descending setting.
- comparator: function taking two items in this column and returning - comparator: function taking two items in this column and returning
an ordering. If specified, it is used instead of the natural an ordering. If specified, it is used instead of the natural
(`.compare_to`) ordering. (`.compare_to`) ordering.
> Example > Example
Sorting `column` in ascending order. Sorting `column` in ascending order.
@ -368,7 +472,8 @@ type Column
top of the resulting column. top of the resulting column.
column.sort order=Sort_Order.Descending missing_last=False column.sort order=Sort_Order.Descending missing_last=False
> Sorting `column` in ascending order, using a custom comparator > Example
Sorting `column` in ascending order, using a custom comparator
function. function.
manhattan_comparator a b = (a.x.abs + a.y.abs) . compare_to (b.x.abs + b.y.abs) manhattan_comparator a b = (a.x.abs + a.y.abs) . compare_to (b.x.abs + b.y.abs)
column.sort comparator=manhattan_comparator column.sort comparator=manhattan_comparator
@ -449,10 +554,6 @@ type Column
mask = OrderBuilder.buildReversedMask this.length mask = OrderBuilder.buildReversedMask this.length
Column <| this.java_column.applyMask mask Column <| this.java_column.applyMask mask
## Creates a new column given a name and a vector of elements.
from_vector : Text -> Vector -> Column
from_vector name items = Column (Java_Column.fromItems name items.to_array)
## Wraps a column grouped by its index. Allows performing aggregation operations ## Wraps a column grouped by its index. Allows performing aggregation operations
on the contained values. on the contained values.
type Aggregate_Column type Aggregate_Column
@ -462,12 +563,12 @@ type Aggregate_Column
with the provided `function`. with the provided `function`.
Arguments: Arguments:
- function: the function used for value aggregation. Values belonging - function: the function used for value aggregation. Values belonging to
to each group are passed to this function in a vector. each group are passed to this function in a vector.
- skip_missing: controls whether missing values should be included - skip_missing: controls whether missing values should be included in
in groups. groups.
- name_suffix: a suffix that will be appended to the original column - name_suffix: a suffix that will be appended to the original column name
name to generate the resulting column name. to generate the resulting column name.
reduce : (Vector.Vector -> Any) -> Boolean -> Text -> Column reduce : (Vector.Vector -> Any) -> Boolean -> Text -> Column
reduce function skip_missing=True name_suffix="_result" = reduce function skip_missing=True name_suffix="_result" =
f arr = function (Vector.Vector arr) f arr = function (Vector.Vector arr)
@ -477,8 +578,8 @@ type Aggregate_Column
## Sums the values in each group. ## Sums the values in each group.
Arguments: Arguments:
- name_suffix: a suffix that will be appended to the original column - name_suffix: a suffix that will be appended to the original column name
name to generate the resulting column name. to generate the resulting column name.
sum : Text -> Column sum : Text -> Column
sum name_suffix='_sum' = sum name_suffix='_sum' =
r = this.java_column.aggregate 'sum' name_suffix (x-> Vector.Vector x . reduce (+)) True r = this.java_column.aggregate 'sum' name_suffix (x-> Vector.Vector x . reduce (+)) True
@ -487,8 +588,8 @@ type Aggregate_Column
## Computes the maximum element of each group. ## Computes the maximum element of each group.
Arguments: Arguments:
- name_suffix: a suffix that will be appended to the original column - name_suffix: a suffix that will be appended to the original column name
name to generate the resulting column name. to generate the resulting column name.
max : Text -> Column max : Text -> Column
max name_suffix='_max' = max name_suffix='_max' =
r = this.java_column.aggregate 'max' name_suffix (x-> Vector.Vector x . reduce Math.max) True r = this.java_column.aggregate 'max' name_suffix (x-> Vector.Vector x . reduce Math.max) True
@ -497,8 +598,8 @@ type Aggregate_Column
## Computes the minimum element of each group. ## Computes the minimum element of each group.
Arguments: Arguments:
- name_suffix: a suffix that will be appended to the original column - name_suffix: a suffix that will be appended to the original column name
name to generate the resulting column name. to generate the resulting column name.
min : Text -> Column min : Text -> Column
min name_suffix='_min' = min name_suffix='_min' =
r = this.java_column.aggregate 'min' name_suffix (x-> Vector.Vector x . reduce Math.min) True r = this.java_column.aggregate 'min' name_suffix (x-> Vector.Vector x . reduce Math.min) True
@ -507,8 +608,8 @@ type Aggregate_Column
## Computes the number of non-missing elements in each group. ## Computes the number of non-missing elements in each group.
Arguments: Arguments:
- name_suffix: a suffix that will be appended to the original column - name_suffix: a suffix that will be appended to the original column name
name to generate the resulting column name. to generate the resulting column name.
count : Text -> Column count : Text -> Column
count name_suffix='_count' = count name_suffix='_count' =
r = this.java_column.aggregate 'count' name_suffix (x-> x.length) True r = this.java_column.aggregate 'count' name_suffix (x-> x.length) True
@ -517,8 +618,8 @@ type Aggregate_Column
## Computes the mean of non-missing elements in each group. ## Computes the mean of non-missing elements in each group.
Arguments: Arguments:
- name_suffix: a suffix that will be appended to the original column - name_suffix: a suffix that will be appended to the original column name
name to generate the resulting column name. to generate the resulting column name.
mean : Text -> Column mean : Text -> Column
mean name_suffix='_mean' = mean name_suffix='_mean' =
vec_mean v = if v.length == 0 then Nothing else vec_mean v = if v.length == 0 then Nothing else
@ -530,14 +631,23 @@ type Aggregate_Column
such vectors. such vectors.
Arguments: Arguments:
- name_suffix: a suffix that will be appended to the original column - name_suffix: a suffix that will be appended to the original column name
name to generate the resulting column name. to generate the resulting column name.
values : Text -> Column values : Text -> Column
values name_suffix='_values' = values name_suffix='_values' =
r = this.java_column.aggregate Nothing name_suffix Vector.Vector False r = this.java_column.aggregate Nothing name_suffix Vector.Vector False
Column r Column r
## PRIVATE ## PRIVATE
Executes a vectorized binary operation over the provided column.
Arguments:
- column: The column to execute the operation over.
- name: The name of the vectorized operation.
- fallback_fn: A function used if the vectorized operation isn't available.
- operand: The operand to apply to the function after `column`.
run_vectorized_binary_op : Column -> Text -> (Any -> Any) -> Any -> Column
run_vectorized_binary_op column name fallback_fn operand = case operand of run_vectorized_binary_op column name fallback_fn operand = case operand of
Column col2 -> Column col2 ->
s1 = column.java_column.getStorage s1 = column.java_column.getStorage
@ -552,46 +662,75 @@ run_vectorized_binary_op column name fallback_fn operand = case operand of
Column (Java_Column.new "Result" ix rs) Column (Java_Column.new "Result" ix rs)
## PRIVATE ## PRIVATE
Executes a vectorized unary operation over the provided column.
Arguments:
- column: The column to execute the operation over.
- name: The name of the vectorized operation.
- fallback_fn: A function used if the vectorized operation isn't available.
run_vectorized_unary_op : Column -> Text -> (Any -> Any) -> Column
run_vectorized_unary_op column name fallback_fn = run_vectorized_unary_op column name fallback_fn =
s = column.java_column.getStorage s = column.java_column.getStorage
ix = column.java_column.getIndex ix = column.java_column.getIndex
rs = s.map name fallback_fn rs = s.map name fallback_fn
Column (Java_Column.new "Result" ix rs) Column (Java_Column.new "Result" ix rs)
## PRIVATE ## PRIVATE
Keep this in sync with `org.enso.table.data.Storage.Type.LONG` Keep this in sync with `org.enso.table.data.Storage.Type.LONG`
storage_type_long : Integer
storage_type_long = 1 storage_type_long = 1
## PRIVATE ## PRIVATE
Keep this in sync with `org.enso.table.data.Storage.Type.DOUBLE` Keep this in sync with `org.enso.table.data.Storage.Type.DOUBLE`
storage_type_double : Integer
storage_type_double = 2 storage_type_double = 2
## PRIVATE ## PRIVATE
Keep this in sync with `org.enso.table.data.Storage.Type.STRING` Keep this in sync with `org.enso.table.data.Storage.Type.STRING`
storage_type_string : Integer
storage_type_string = 3 storage_type_string = 3
## PRIVATE ## PRIVATE
Keep this in sync with `org.enso.table.data.Storage.Type.BOOL` Keep this in sync with `org.enso.table.data.Storage.Type.BOOL`
storage_type_bool : Integer
storage_type_bool = 4 storage_type_bool = 4
## PRIVATE ## PRIVATE
A helper function for converting a column storage to JSON.
Arguments:
- storage: The storage to convert to JSON.
- factory: The factory function for converting the storage.
storage_to_json : Storage -> (Any -> Json) -> Json
storage_to_json storage factory = storage_to_json storage factory =
Vector.new storage.size ix-> Vector.new storage.size ix->
if storage.isNa ix then Json.Null else if storage.isNa ix then Json.Null else
factory (storage.getItem ix) factory (storage.getItem ix)
## PRIVATE ## PRIVATE
Gets a textual representation of the item at position `ix` in `column`.
Arguments:
- column: The column to get the item from.
- ix: The index in the column from which to get the item.
get_item_string : Column -> Integer -> Text
get_item_string column ix = get_item_string column ix =
tp = column.getType tp = column.getType
if tp == Storage_Type_String then column.getItem ix else if tp == Storage_Type_String then column.getItem ix else
column.getItem ix . to_text column.getItem ix . to_text
## A type representing an error for an out-of-bounds index in a column. ## A type representing an error for an out-of-bounds index in a column.
Arguments:
- index: The index of the element requested.
- length: The length of the column in which `index` was out of bounds.
type Index_Out_Of_Bounds_Error index length type Index_Out_Of_Bounds_Error index length
## Pretty-prints the index out of bounds error. ## Pretty-prints the index out of bounds error.

View File

@ -1,29 +1,30 @@
from Standard.Base import all from Standard.Base import all
type Order_Rule type Order_Rule
## UNSTABLE ## UNSTABLE
A rule used for sorting table-like structures. A rule used for sorting table-like structures.
Arguments: Arguments:
- column: a value representing the data dimension by which this rule is - column: a value representing the data dimension by which this rule is
sorting. This type does not specify the underlying representation of sorting. This type does not specify the underlying representation of a
a column, assuming that the sorting engine defines its own column column, assuming that the sorting engine defines its own column
representation. representation.
- comparator: a function taking two elements of the data being sorted - comparator: a function taking two elements of the data being sorted on
on and returning an `Ordering`. The function may be `Nothing`, in and returning an `Ordering`. The function may be `Nothing`, in which
which case a natural ordering will be used. Note that certain table case a natural ordering will be used. Note that certain table backends
backends (such us database connectors) may not support this field (such us database connectors) may not support this field being set to a
being set to a non-`Nothing` value. non-`Nothing` value.
- order: specifies whether the table should be sorted in an ascending - order: specifies whether the table should be sorted in an ascending or
or descending order. The default value of `Nothing` delegates the descending order. The default value of `Nothing` delegates the decision
decision to the sorting function. Can be set to to the sorting function. Can be set to `Sort_Order.Ascending` or
`Sort_Order.Ascending` or `Sort_Order.Descending` from the `Base` `Sort_Order.Descending` from the `Base` library, to specify the
library, to specify the ordering. ordering.
- missing_last: whether the missing values should be placed at the - missing_last: whether the missing values should be placed at the
beginning or end of the sorted table. Note that this argument is beginning or end of the sorted table. Note that this argument is
independent from `order`, i.e. missing values will always be sorted independent from `order`, i.e. missing values will always be sorted
according to this rule, ignoring the ascending / descending setting. according to this rule, ignoring the ascending / descending setting.
The default value of `Nothing` delegates the decision to the sorting The default value of `Nothing` delegates the decision to the sorting
function. function.
type Order_Rule column comparator=Nothing order=Nothing missing_last=Nothing type Order_Rule column comparator=Nothing order=Nothing missing_last=Nothing

View File

@ -1,7 +1,17 @@
## Represents different types of underlying storage for Columns. ## Represents different types of underlying storage for Columns.
type Type type Type
## A column storing text data.
type Text type Text
## A column storing integer data.
type Integer type Integer
## A column storing decimal data.
type Decimal type Decimal
## A column storing boolean data.
type Boolean type Boolean
## A column storing arbitrary data.
type Any type Any

View File

@ -10,20 +10,76 @@ polyglot java import org.enso.table.data.table.Table as Java_Table
polyglot java import org.enso.table.operations.OrderBuilder polyglot java import org.enso.table.operations.OrderBuilder
## An error returned when a non-existent column is being looked up. ## An error returned when a non-existent column is being looked up.
Arguments:
- column_name: The name of the column that doesn't exist.
type No_Such_Column_Error column_name type No_Such_Column_Error column_name
## An error returned when getting an index but no index is set for that table. ## An error returned when getting an index but no index is set for that table.
type No_Index_Set_Error type No_Index_Set_Error
## Creates a new table from a vector of column names and a vector of vectors
specifying row contents.
Arguments:
- header: A list of texts specifying the column names
- rows: A vector of vectors, specifying the contents of each table row. The
length of each element of `rows` must be equal in length to `header`.
> Example
The code below creates a table with 3 columns, named `foo`, `bar`, and
`baz`, containing `[1, 2, 3]`, `[True, False, True]`, and `['a', 'b', 'c']`,
respectively.
header = [ 'foo' , 'bar' , 'baz' ]
row_1 = [ 1 , True , 'a' ]
row_2 = [ 2 , False , 'b' ]
row_3 = [ 3 , True , 'c' ]
Table.from_rows header [row_1, row_2, row_3]
from_rows : Vector.Vector -> Vector.Vector -> Table
from_rows header rows =
columns = header.map_with_index i-> name-> [name, rows.map (_.at i)]
here.new columns
## Creates a new table from a vector of `[name, items]` pairs.
Arguments:
- columns: The `[name, items]` pairs to construct a new table from.
> Example
Create a new table with the given in two columns:
Table.new [["foo", [1, 2, 3]], ["bar", [True, False, True]]]
new : Vector -> Table
new columns =
cols = columns.map c->
Column.from_vector (c.at 0) (c.at 1) . java_column
here.from_columns cols
## Joins a vector of tables (or columns) into a single table, using each table's
index as the join key.
Arguments:
- tables: A vector of tables to join into a single table.
Particularly useful for joining multiple columns derived from one original
table into a new table.
join : Vector -> Table
join tables =
tables.reduce .join
## Represents a column-oriented table data structure. ## Represents a column-oriented table data structure.
type Table type Table
## A table.
Arguments:
- java_table: The internal java representation of the table.
type Table java_table type Table java_table
## Returns a text containing an ASCII-art table displaying this data. ## Returns a text containing an ASCII-art table displaying this data.
Arguments: Arguments:
- show_rows: the number of initial rows that should be displayed. - show_rows: the number of initial rows that should be displayed.
- format_terminal: whether ANSI-terminal formatting should be used - format_terminal: whether ANSI-terminal formatting should be used
display : Integer -> Boolean -> Text display : Integer -> Boolean -> Text
display show_rows=10 format_terminal=False = display show_rows=10 format_terminal=False =
cols = Vector.Vector this.java_table.getColumns cols = Vector.Vector this.java_table.getColumns
@ -44,7 +100,7 @@ type Table
## Prints an ASCII-art table with this data to the standard output. ## Prints an ASCII-art table with this data to the standard output.
Arguments: Arguments:
- show_rows: the number of initial rows that should be displayed. - show_rows: the number of initial rows that should be displayed.
print show_rows=10 = print show_rows=10 =
IO.println (this.display show_rows format_terminal=True) IO.println (this.display show_rows format_terminal=True)
IO.println '' IO.println ''
@ -61,6 +117,7 @@ type Table
ADVANCED ADVANCED
Returns a Text used to display this table in the IDE by default. Returns a Text used to display this table in the IDE by default.
Returns a JSON object containing useful metadata and previews of column Returns a JSON object containing useful metadata and previews of column
values. values.
to_default_visualization_data : Text to_default_visualization_data : Text
@ -74,6 +131,9 @@ type Table
Json.from_pairs [row_count, ['columns', cols]] . to_text Json.from_pairs [row_count, ['columns', cols]] . to_text
## Returns the column with the given name. ## Returns the column with the given name.
Arguments:
- name: The name of the column being looked up.
at : Text -> Column ! No_Such_Column_Error at : Text -> Column ! No_Such_Column_Error
at name = case this.java_table.getColumnByName name of at name = case this.java_table.getColumnByName name of
Nothing -> Error.throw (No_Such_Column_Error name) Nothing -> Error.throw (No_Such_Column_Error name)
@ -82,13 +142,13 @@ type Table
## Selects only the rows of this table that correspond to `True` values in ## Selects only the rows of this table that correspond to `True` values in
`indexes`. `indexes`.
This is useful for filtering the rows by given predicate.
Arguments: Arguments:
- indexes: The column to mask the table by. This column should contain - indexes: The column to mask the table by. This column should contain
boolean values (`True` or `False`) that determine whether or not the boolean values (`True` or `False`) that determine whether or not the
corresponding row is kept. corresponding row is kept.
This is useful for filtering the rows by given predicate.
> Example > Example
Select only the rows of `my_table` where the `"Status"` column has the Select only the rows of `my_table` where the `"Status"` column has the
value `"Valid"` value `"Valid"`
@ -97,8 +157,14 @@ type Table
where indexes = where indexes =
Table (this.java_table.mask indexes.java_column) Table (this.java_table.mask indexes.java_column)
## Sets the column value at the given name. If a column with the given name ## Sets the column value at the given name.
already exists, it will be replaced. Otherwise a new column is added.
Arguments:
- name: The name of the column to set the value of.
- column: The new value for the column called `name`.
If a column with the given name already exists, it will be replaced.
Otherwise a new column is added.
set : Text -> Column.Column | Vector.Vector -> Table set : Text -> Column.Column | Vector.Vector -> Table
set name column = case column of set name column = case column of
Vector.Vector _ -> Vector.Vector _ ->
@ -112,6 +178,9 @@ type Table
Vector.Vector this.java_table.getColumns . map Column.Column Vector.Vector this.java_table.getColumns . map Column.Column
## Sets the index of this table, using the column with the provided name. ## Sets the index of this table, using the column with the provided name.
Arguments:
- index: The name of the column to use as the index in this table.
set_index : Text -> Table set_index : Text -> Table
set_index index = set_index index =
Table (this.java_table.indexFromColumn index) Table (this.java_table.indexFromColumn index)
@ -132,21 +201,21 @@ type Table
## Efficiently joins two tables based on either the index or the specified ## Efficiently joins two tables based on either the index or the specified
key column. key column.
Arguments:
- other: The table being the right operand of this join operation.
- on: The column of `this` that should be used as the join key. If this
argument is not provided, the index of `this` will be used.
- drop_unmatched: Whether the rows of `this` without corresponding
matches in `other` should be dropped from the result.
- left_suffix: A suffix that should be added to the columns of `this`
when there's a name conflict with a column of `other`.
- right_suffix: A suffix that should be added to the columns of `other`
when there's a name conflict with a column of `this`.
The resulting table contains rows of `this` extended with rows of The resulting table contains rows of `this` extended with rows of
`other` with matching indexes. If the index values in `other` are not `other` with matching indexes. If the index values in `other` are not
unique, the corresponding rows of `this` will be duplicated in the unique, the corresponding rows of `this` will be duplicated in the
result. result.
Arguments:
- other: the table being the right operand of this join operation.
- on: the column of `this` that should be used as the join key. If
this argument is not provided, the index of `this` will be used.
- drop_unmatched: whether the rows of `this` without corresponding
matches in `other` should be dropped from the result.
- left_suffix: a suffix that should be added to the columns of `this`
when there's a name conflict with a column of `other`.
- right_suffix: a suffix that should be added to the columns of `other`
when there's a name conflict with a column of `this`.
join : Table | Column.Column -> Text | Nothing -> Boolean -> Text -> Text -> Table join : Table | Column.Column -> Text | Nothing -> Boolean -> Text -> Text -> Table
join other on=Nothing drop_unmatched=False left_suffix='_left' right_suffix='_right' = join other on=Nothing drop_unmatched=False left_suffix='_left' right_suffix='_right' =
case other of case other of
@ -220,27 +289,27 @@ type Table
Sorts the table according to the specified rules. Sorts the table according to the specified rules.
Arguments: Arguments:
- by: specifies the columns used for reordering the table. This - by: Specifies the columns used for reordering the table. This argument
argument may be one of: may be one of:
- a text: the text is treated as a column name. - a text: The text is treated as a column name.
- a column: any column, that may or may not belong to this table. - a column: Any column, that may or may not belong to this table.
Sorting by a column will result in reordering the rows of this Sorting by a column will result in reordering the rows of this
table in a way that would result in sorting the given column. table in a way that would result in sorting the given column.
- an order rule: specifies both the sorting column and additional - an order rule: Specifies both the sorting column and additional
settings, that will take precedence over the global parameters of settings, that will take precedence over the global parameters of
this sort operation. The `column` field of the rule may be a text this sort operation. The `column` field of the rule may be a text
or a column, with the semantics described above. or a column, with the semantics described above.
- a vector of any of the above: this will result in a hierarchical - a vector of any of the above: This will result in a hierarchical
sorting, such that the first rule is applied first, the second is sorting, such that the first rule is applied first, the second is
used for breaking ties, etc. used for breaking ties, etc.
- order: specifies the default sort order for this operation. All the - order: Specifies the default sort order for this operation. All the
rules specified in the `by` argument will default to this setting, rules specified in the `by` argument will default to this setting,
unless specified in the rule. unless specified in the rule.
- missing_last: specifies the default placement of missing values when - missing_last: Specifies the default placement of missing values when
compared to non-missing ones. This setting may be overriden by the compared to non-missing ones. This setting may be overriden by the
particular rules of the `by` argument. Note thet this argument is particular rules of the `by` argument. Note thet this argument is
independent from `order`, i.e. missing values will always be sorted independent from `order`, i.e. missing values will always be sorted
according to this rule, ignoring the ascending / descending setting. according to this rule, ignoring the ascending / descending setting.
> Example > Example
Sorting `table` in ascending order by the value in column `'Quantity'` Sorting `table` in ascending order by the value in column `'Quantity'`
@ -282,6 +351,14 @@ type Table
Table new_table Table new_table
## PRIVATE ## PRIVATE
Transforms order rules from Enso into Java.
Arguments:
- rules: The rule(s) to convert.
- order: The sorting order.
- missing_last: Whether or not missing values should be ordered last.
build_java_order_rules : (Text | Column.Column. | Order_Rule | Vector (Text | Column.Column | Order_Rule)) -> Sort_Order -> Boolean -> Vector
build_java_order_rules rules order missing_last = case rules of build_java_order_rules rules order missing_last = case rules of
Text -> [this.build_java_order_rule rules order missing_last] Text -> [this.build_java_order_rule rules order missing_last]
Column.Column _ -> [this.build_java_order_rule rules order missing_last] Column.Column _ -> [this.build_java_order_rule rules order missing_last]
@ -289,6 +366,14 @@ type Table
Vector.Vector _ -> rules.map (this.build_java_order_rule _ order missing_last) Vector.Vector _ -> rules.map (this.build_java_order_rule _ order missing_last)
## PRIVATE ## PRIVATE
Builds a java order rule.
Arguments:
- rule: The rule to convert.
- order: The sort order.
- missing_last: Whether or not missing values should be ordered last.
build_java_order_rule : (Text | Column.Column | Order_Rule) -> Sort_Order -> Boolean -> OrderRule
build_java_order_rule rule order missing_last = build_java_order_rule rule order missing_last =
order_bool = case order of order_bool = case order of
Sort_Order.Ascending -> True Sort_Order.Ascending -> True
@ -317,9 +402,14 @@ type Table
## UNSTABLE ## UNSTABLE
Concatenates `other` to `this`. Any column that is present in one table, Concatenates `other` to `this`.
but missing in another, will be `Nothing`-padded in the positions
corresponding to the missing column. Arguments:
- other: The table to concatenate to `this`.
Any column that is present in one table, but missing in another, will be
`Nothing`-padded in the positions corresponding to the missing column.
concat : Table -> Table
concat other = concat other =
Table (this.java_table.concat other.java_table) Table (this.java_table.concat other.java_table)
@ -390,10 +480,23 @@ type Table
Table <| this.java_table.applyMask mask Table <| this.java_table.applyMask mask
## PRIVATE ## PRIVATE
Wraps the Enso comparator function so it's usable in Java.
Arguments:
- cmp: The Enso comparator function.
- x: The left operand to the compartor.
- y: The right operand to the comparator.
comparator_to_java : (Any -> Any -> Ordering) -> Any -> Any -> Integer
comparator_to_java cmp x y = cmp x y . to_sign comparator_to_java cmp x y = cmp x y . to_sign
## Represents a table with grouped rows. ## Represents a table with grouped rows.
type Aggregate_Table type Aggregate_Table
## A table type with grouped rows.
Arguments:
- java_table: The internal representation of the table.
type Aggregate_Table java_table type Aggregate_Table java_table
## Returns a vector of aggregate columns in this table. ## Returns a vector of aggregate columns in this table.
@ -411,69 +514,44 @@ type Aggregate_Table
count = Column.Column this.java_table.count count = Column.Column this.java_table.count
## Returns an aggregate column with the given name, contained in this table. ## Returns an aggregate column with the given name, contained in this table.
at : Text -> Column | Nothing
Arguments:
- name: The name of the aggregate column to get.
at : Text -> Column ! Nothing
at name = case this.java_table.getColumnByName name of at name = case this.java_table.getColumnByName name of
Nothing -> Nothing Nothing -> Error.throw Nothing
c -> Column.Aggregate_Column c c -> Column.Aggregate_Column c
## Prints an ASCII-art table with this data to the standard output. ## Prints an ASCII-art table with this data to the standard output.
Arguments: Arguments:
- show_rows: the number of initial rows that should be displayed. - show_rows: the number of initial rows that should be displayed.
print : Integer -> Nothing print : Integer -> Nothing
print show_rows=10 = this.values.print show_rows print show_rows=10 = this.values.print show_rows
## PRIVATE ## PRIVATE
from_columns cols = Table (Java_Table.new cols.to_array) from_columns cols = Table (Java_Table.new cols.to_array)
## Creates a new table from a vector of column names and a vector of vectors
specifying row contents.
Arguments:
- header: a list of texts specifying the column names
- rows: a vector of vectors, specifying the contents of each table row.
the length of each element of `rows` must be equal in length to `header`.
> Example
The code below creates a table with 3 columns, named `foo`, `bar`, and
`baz`, containing `[1, 2, 3]`, `[True, False, True]`, and `['a', 'b', 'c']`,
respectively.
header = [ 'foo' , 'bar' , 'baz' ]
row_1 = [ 1 , True , 'a' ]
row_2 = [ 2 , False , 'b' ]
row_3 = [ 3 , True , 'c' ]
Table.from_rows header [row_1, row_2, row_3]
from_rows : Vector.Vector -> Vector.Vector -> Table
from_rows header rows =
columns = header.map_with_index i-> name-> [name, rows.map (_.at i)]
here.new columns
## Creates a new table from a vector of `[name, items]` pairs.
> Example
Create a new table with the given in two columns:
Table.new [["foo", [1, 2, 3]], ["bar", [True, False, True]]]
new columns =
cols = columns.map c->
Column.from_vector (c.at 0) (c.at 1) . java_column
here.from_columns cols
## Joins a vector of tables (or columns) into a single table, using each table's
index as the join key. Particularly useful for joining multiple columns
derived from one original table into a new table.
join : Vector -> Table
join tables =
tables.reduce .join
## PRIVATE ## PRIVATE
Ensures that the `txt` has at least `len` characters by appending spaces at Ensures that the `txt` has at least `len` characters by appending spaces at
the end. the end.
Arguments:
- txt: The text to pad.
- len: The minimum length of the text.
pad : Text -> Integer -> Text
pad txt len = pad txt len =
true_len = txt.characters.length true_len = txt.characters.length
txt + (" ".repeat (len - true_len)) txt + (" ".repeat (len - true_len))
## PRIVATE ## PRIVATE
Adds ANSI bold escape sequences to text if the feature is enabled.
Arguments:
- txt: The text to possibly bold.
ansi_bold_enabled : Text -> Text
ansi_bold enabled txt = ansi_bold enabled txt =
case Platform.os of case Platform.os of
## Output formatting for Windows is not currently supported. ## Output formatting for Windows is not currently supported.
@ -506,3 +584,4 @@ print_table header rows indices_count format_term =
y = with_bold_ix . join ' | ' y = with_bold_ix . join ' | '
" " + y " " + y
([" " + header_line, divider] + row_lines).join '\n' ([" " + header_line, divider] + row_lines).join '\n'

View File

@ -8,21 +8,27 @@ polyglot java import org.enso.table.data.column.builder.object.NumericBuilder
polyglot java import org.enso.table.data.column.builder.object.BoolBuilder polyglot java import org.enso.table.data.column.builder.object.BoolBuilder
## PRIVATE ## PRIVATE
make_bool_builder : BoolBuilder
make_bool_builder = BoolBuilder.new make_bool_builder = BoolBuilder.new
## PRIVATE ## PRIVATE
make_double_builder : NumericBuilder
make_double_builder initial_size = NumericBuilder.createDoubleBuilder initial_size make_double_builder initial_size = NumericBuilder.createDoubleBuilder initial_size
## PRIVATE ## PRIVATE
make_long_builder : NumericBuilder
make_long_builder initial_size = NumericBuilder.createLongBuilder initial_size make_long_builder initial_size = NumericBuilder.createLongBuilder initial_size
## PRIVATE ## PRIVATE
make_inferred_builder : NumericBuilder
make_inferred_builder initial_size = InferredBuilder.new initial_size make_inferred_builder initial_size = InferredBuilder.new initial_size
## PRIVATE ## PRIVATE
make_column : Text -> Storage -> Column
make_column name storage = Column.new name storage make_column name storage = Column.new name storage
## PRIVATE ## PRIVATE
make_table_without_columns : Integer -> Table
make_table_without_columns row_count = make_table_without_columns row_count =
index = DefaultIndex.new row_count index = DefaultIndex.new row_count
Table.new [].to_array index Table.new [].to_array index

View File

@ -7,13 +7,13 @@ polyglot java import org.enso.table.format.csv.Parser
## Reads the contents of `this` and parses them as a CSV dataframe. ## Reads the contents of `this` and parses them as a CSV dataframe.
Arguments Arguments
- has_header: Specifies whether the first line of the file should be - has_header: Specifies whether the first line of the file should be
interpreted as a header, containing storage names. If set to `False`, interpreted as a header, containing storage names. If set to `False`,
storage names will be automatically generated. storage names will be automatically generated.
- prefix: text that should be prepended to automatically generated storage - prefix: text that should be prepended to automatically generated storage
names. For example, if `prefix` is set to `X`, the columns will be named names. For example, if `prefix` is set to `X`, the columns will be named
`X0`, `X1`, etc. This argument has no effect if the storage name is `X0`, `X1`, etc. This argument has no effect if the storage name is
inferred from the CSV header row or set manually. inferred from the CSV header row or set manually.
File.File.read_csv : Boolean -> Text -> Table File.File.read_csv : Boolean -> Text -> Table
File.File.read_csv has_header=True prefix='C' = File.File.read_csv has_header=True prefix='C' =
parser_inst = Parser.create has_header prefix parser_inst = Parser.create has_header prefix

View File

@ -1,139 +1,30 @@
from Standard.Base import all from Standard.Base import all
## The top-level entry point for a test suite.
type Suite specs
## PRIVATE
type Spec name behaviors
## PRIVATE
type Behavior name result
## PRIVATE
Behavior.is_fail = this.result.is_fail
## PRIVATE
Spec.is_fail = this.behaviors.any .is_fail
## PRIVATE
Suite.is_fail = this.specs.any .is_fail
## PRIVATE
type Finished_With_Error err stack_trace_text
## PRIVATE
type Matched_On_Error err
## PRIVATE
type Assertion
type Success
type Failure message
type Pending reason
is_fail = case this of
Success -> False
Failure _ -> True
Pending _ -> False
type Verbs
type Verbs
start_with subject argument =
if subject.starts_with argument then Success else
here.fail (subject.to_text + " did not start with " + argument.to_text))
equal subject argument =
if subject == argument then Success else
msg = subject.to_text + " did not equal " + argument.to_text + "."
here.fail msg
be subject argument = this.equal subject argument
contain subject argument =
if subject.contains argument then Success else
msg = subject.to_text + " did not contain " + argument.to_text + "."
here.fail msg
Any.should verb argument = verb Verbs this argument
## Fail a test with the given message.
fail message = Panic.throw (Failure message)
## Expect a function to fail with the provided dataflow error.
Any.should_fail_with matcher =
here.fail ("Expected an error " + matcher.to_text + " but none occurred.")
## Expect a function to fail with the provided dataflow error.
Error.should_fail_with matcher =
caught = this.catch x->x
if caught.is_a matcher then Nothing else
here.fail ("Unexpected error " + caught.to_text + " returned.")
## Expect a function to fail with the provided panic.
expect_panic_with ~action matcher =
res = Panic.recover action
case res of
_ -> here.fail ("Expected a " + matcher.to_text + " to be thrown, but the action succeeded.")
err = res.catch x->x
if err.is_a matcher then Nothing else
here.fail ("Unexpected error " + err.to_text + " thrown.")
## Asserts that `this` value is equal to the expected value.
Any.should_equal that = case this == that of
True -> Success
False ->
loc = Meta.get_source_location 2
msg = this.to_text + " did not equal " + that.to_text + " (at " + loc + ")."
Panic.throw (Failure msg)
## Asserts that `this` value is equal to the expected value.
Error.should_equal _ = Panic.throw (Matched_On_Error this)
## Asserts that `this` is within `epsilon` from `that`.
Decimal.should_equal that (epsilon = 0) = case this.equals that epsilon of
True -> Success
False ->
loc = Meta.get_source_location 2
msg = this.to_text + " did not equal " + that.to_text + " (at " + loc + ")."
Panic.throw (Failure msg)
## Asserts that the given `Boolean` is `True`
Boolean.should_be_true = case this of
True -> Success
False ->
loc = Meta.get_source_location 2
Panic.throw (Failure "Expected False to be True (at "+loc+").")
## Asserts that the given `Boolean` is `True`.
Error.should_be_true = Panic.throw (Matched_On_Error this)
## Asserts that the given `Boolean` is `False`
Boolean.should_be_false = case this of
True ->
loc = Meta.get_source_location 2
Panic.throw (Failure "Expected True to be False (at "+loc+").")
False -> Success
## Asserts that the given `Boolean` is `False`
Error.should_be_false = Panic.throw (Matched_On_Error this)
## PRIVATE
Spec.print_report =
IO.print_err (this.name + ":")
this.behaviors.reverse.each behavior->
case behavior.result of
Success ->
IO.print_err (" - " + behavior.name)
Failure msg ->
IO.print_err (" - [FAILED] " + behavior.name)
IO.print_err (" Reason: " + msg)
Pending reason ->
IO.print_err (" - [PENDING] " + behavior.name)
IO.print_err (" Reason: " + reason)
## Creates a new test group, desribing properties of the object ## Creates a new test group, desribing properties of the object
described by `this`. described by `this`.
Arguments:
- specs: An action encapsulating a number of test specs or groups.
> Example
Suite.run_main <|
Test.group "Number" <|
Test.specify "should define addition" <|
2+3 . should_equal 5
Test.specify "should define multiplication" <|
2*3 . should_equal 6
Suite.run_main : Any -> Nothing
Suite.run_main ~specs =
r = this.run specs
code = if r.is_fail then 1 else 0
System.exit code
## Creates a new test group, desribing properties of the object
described by `this`.
Arguments:
- specs: An action encapsulating a number of test specs or groups.
> Example > Example
Suite.run <| Suite.run <|
Test.group "Number" <| Test.group "Number" <|
@ -141,6 +32,30 @@ Spec.print_report =
2+3 . should_equal 5 2+3 . should_equal 5
Test.specify "should define multiplication" <| Test.specify "should define multiplication" <|
2*3 . should_equal 6 2*3 . should_equal 6
Suite.run : Any -> Any
Suite.run ~specs =
r = State.run Suite (Suite Nil) <|
specs
State.get Suite
r
## Creates a new test group, desribing properties of the object
described by `this`.
Arguments:
- name: The name of the test group.
- behaviors: An action containing a set of specs for the group.
- pending: A reason for why the test is pending, or `Nothing` when it is not
pending.
> Example
Suite.run <|
Test.group "Number" <|
Test.specify "should define addition" <|
2+3 . should_equal 5
Test.specify "should define multiplication" <|
2*3 . should_equal 6
group : Text -> Any -> (Text | Nothing) -> Nothing
group name ~behaviors pending=Nothing = group name ~behaviors pending=Nothing =
case pending of case pending of
Nothing -> Nothing ->
@ -157,6 +72,12 @@ group name ~behaviors pending=Nothing =
## Specifies a single behavior, described by `this`. ## Specifies a single behavior, described by `this`.
Arguments:
- label: A description of the behavior being tested.
- behavior: An action that executes tests.
- pending: A reason for why the test is pending, or `Nothing` when it is not
pending.
> Example > Example
Suite.run <| Suite.run <|
describe "Number" <| describe "Number" <|
@ -164,6 +85,7 @@ group name ~behaviors pending=Nothing =
2+3 . should_equal 5 2+3 . should_equal 5
it "should define multiplication" <| it "should define multiplication" <|
2*3 . should_equal 6 2*3 . should_equal 6
specify : Text -> Any -> (Text | Nothing) -> Nothing
specify label ~behavior pending=Nothing = specify label ~behavior pending=Nothing =
result = case pending of result = case pending of
Nothing -> here.run_spec behavior Nothing -> here.run_spec behavior
@ -172,7 +94,276 @@ specify label ~behavior pending=Nothing =
new_spec = Spec spec.name (Cons (Behavior label result) spec.behaviors) new_spec = Spec spec.name (Cons (Behavior label result) spec.behaviors)
State.put Spec new_spec State.put Spec new_spec
## Asserts a property about the receiver.
Arguments:
- verb: The property (see `Verbs`) being asserted
- argument: The argument to the verb.
Anu.should : (Verbs -> Any -> Any) -> Any -> Assertion
Any.should verb argument = verb Verbs this argument
## Fail a test with the given message.
Arguments:
- message: The message printed when failing the test.
fail : Text -> Assertion
fail message = Panic.throw (Failure message)
## Expect a function to fail with the provided dataflow error.
Arguments:
- matcher: The expected type of dataflow error contained in `this`.
Any.should_fail_with : Any -> Assertion
Any.should_fail_with matcher =
here.fail ("Expected an error " + matcher.to_text + " but none occurred.")
## Expect a function to fail with the provided dataflow error.
Arguments:
- matcher: The expected type of dataflow error contained in `this`.
Error.should_fail_with : Any -> Assertion
Error.should_fail_with matcher =
caught = this.catch x->x
if caught.is_a matcher then Nothing else
here.fail ("Unexpected error " + caught.to_text + " returned.")
## Expect a function to fail with the provided panic.
Arguments:
- action: The action to evaluate that is expected to fail with a panic.
- matcher: The expected type of the panic thrown by `action`.
expect_panic_with : Any -> Any -> Assertion
expect_panic_with ~action matcher =
res = Panic.recover action
case res of
_ -> here.fail ("Expected a " + matcher.to_text + " to be thrown, but the action succeeded.")
err = res.catch x->x
if err.is_a matcher then Nothing else
here.fail ("Unexpected error " + err.to_text + " thrown.")
## Asserts that `this` value is equal to the expected value.
Arguments:
- that: The value to check `this` for equality with.
Any.should_equal : Any -> Assertion
Any.should_equal that = case this == that of
True -> Success
False ->
loc = Meta.get_source_location 2
msg = this.to_text + " did not equal " + that.to_text + " (at " + loc + ")."
here.fail msg
## Asserts that `this` value is equal to the expected value.
Arguments:
- _: The value to check `this` for equality with.
Error.should_equal : Any -> Assertion.
Error.should_equal _ = Panic.throw (Matched_On_Error this)
## Asserts that `this` is within `epsilon` from `that`.
Arguments:
- that: The value to compare `this` for equality with.
- epsilon: The epislon for comparing two decimal numbers.
Decimal.should_equal : Decimal -> Decimal -> Assertion
Decimal.should_equal that (epsilon = 0) = case this.equals that epsilon of
True -> Success
False ->
loc = Meta.get_source_location 2
msg = this.to_text + " did not equal " + that.to_text + " (at " + loc + ")."
Panic.throw (Failure msg)
## Asserts that the given `Boolean` is `True`
Boolean.should_be_true : Assertion
Boolean.should_be_true = case this of
True -> Success
False ->
loc = Meta.get_source_location 2
Panic.throw (Failure "Expected False to be True (at "+loc+").")
## Asserts that the given `Boolean` is `True`.
Error.should_be_true : Assertion
Error.should_be_true = Panic.throw (Matched_On_Error this)
## Asserts that the given `Boolean` is `False`
Boolean.should_be_false : Assertion
Boolean.should_be_false = case this of
True ->
loc = Meta.get_source_location 2
Panic.throw (Failure "Expected True to be False (at "+loc+").")
False -> Success
## Asserts that the given `Boolean` is `False`
Error.should_be_false : Assertion
Error.should_be_false = Panic.throw (Matched_On_Error this)
type Verbs
## Verbs that describe how tests should execute.
type Verbs
## Checks if the `subject` starts with `argument`.
Arguments:
- subject: The value to check. It must have a `.starts_with` method.
- argument: The expected prefix.
start_with : Text -> Text -> Assertion
start_with subject argument =
if subject.starts_with argument then Success else
here.fail (subject.to_text + " did not start with " + argument.to_text))
## Checks if the `subject` is equal to the `argument`.
Arguments:
- subject: The value to check for equality against the provided value.
- argument: The provided value to check the `subject` for equality
against.
equal : Any -> Any -> Assertion
equal subject argument =
if subject == argument then Success else
msg = subject.to_text + " did not equal " + argument.to_text + "."
here.fail msg
## Checks if `subject` is `argument`.
Arguments:
- subject: The value to check for equality against the provided value.
- argument: The provided value to check the `subject` for equality
against.
be : Any -> Any -> Assertion
be subject argument = this.equal subject argument
## Checks if `subject` contains `argument`.
Arguments:
- subject: The collection type to check if `argument` is contained in it.
This type must have a `.contains` method.
- argument: The value to see if it is contained in `subject`.
contain : Any -> Any -> Assertion
contain subject argument =
if subject.contains argument then Success else
msg = subject.to_text + " did not contain " + argument.to_text + "."
here.fail msg
## PRIVATE ## PRIVATE
Prints a report on the tests to standard output.
Spec.print_report : Nothing
Spec.print_report =
IO.print_err (this.name + ":")
this.behaviors.reverse.each behavior->
case behavior.result of
Success ->
IO.print_err (" - " + behavior.name)
Failure msg ->
IO.print_err (" - [FAILED] " + behavior.name)
IO.print_err (" Reason: " + msg)
Pending reason ->
IO.print_err (" - [PENDING] " + behavior.name)
IO.print_err (" Reason: " + reason)
## PRIVATE
The top-level entry point for a test suite.
Arguments:
- specs: The specs contained within the test suite.
type Suite specs
## PRIVATE
A group of behaviors for a test.
Arguments:
- name: The name of the spec.
- behaviors: The results of the behaviors encapsulated in that spec.
type Spec name behaviors
## PRIVATE
A description of a behaviors in a test.
Arguments:
- name: The name of the behavior.
- result: The result of the behavior.
type Behavior name result
## PRIVATE
Checks if the behavior is a failure.
Behavior.is_fail : Boolean
Behavior.is_fail = this.result.is_fail
## PRIVATE
Checks if the spec group contains any failures and hence fails itself.
Spec.is_fail : Boolean
Spec.is_fail = this.behaviors.any .is_fail
## PRIVATE
Checks if the suite contains any failures, and hence fails itself.
Suite.is_fail : Boolean
Suite.is_fail = this.specs.any .is_fail
## PRIVATE
An error describing that a test finished with an unexpected error.
Arguments:
- err: The payload of the error that triggered this error.
- stack_trace_text: A textual representation of the stack trace for the
error.
type Finished_With_Error err stack_trace_text
## PRIVATE
An error describing that the test runner matched on an unexpected error.
Arguments:
- err: The payload of the error that triggered this error.
type Matched_On_Error err
## PRIVATE
type Assertion
## PRIVATE
Represents a successful behavioral test.
type Success
## PRIVATE
Represents a failing behavioral test.
Arguments:
- message: The reason why the test failed.
type Failure message
## PRIVATE
Represents a pending behavioral test.
Arguments:
- reason: Text describing why the test is pending.
type Pending reason
## PRIVATE
Checks if the Assertion is a failure.
is_fail : Boolean
is_fail = case this of
Success -> False
Failure _ -> True
Pending _ -> False
## PRIVATE
Executes a behavior test.
Arguments:
- behavior: The behavior to execute.
run_spec : Any -> Assertion
run_spec ~behavior = run_spec ~behavior =
recovery = Panic.recover <| recovery = Panic.recover <|
result = behavior result = behavior
@ -187,34 +378,3 @@ run_spec ~behavior =
Failure ("An unexpected error was returned: " + err.to_display_text + '\n' + stack_trace_text) Failure ("An unexpected error was returned: " + err.to_display_text + '\n' + stack_trace_text)
_ -> Failure ("An unexpected panic was thrown: " + ex.to_display_text + '\n' + maybeExc.get_stack_trace_text) _ -> Failure ("An unexpected panic was thrown: " + ex.to_display_text + '\n' + maybeExc.get_stack_trace_text)
result result
## Creates a new test group, desribing properties of the object
described by `this`.
> Example
Suite.run <|
Test.group "Number" <|
Test.specify "should define addition" <|
2+3 . should_equal 5
Test.specify "should define multiplication" <|
2*3 . should_equal 6
Suite.run ~specs =
r = State.run Suite (Suite Nil) <|
specs
State.get Suite
r
## Creates a new test group, desribing properties of the object
described by `this`.
> Example
Suite.run <|
Test.group "Number" <|
Test.specify "should define addition" <|
2+3 . should_equal 5
Test.specify "should define multiplication" <|
2*3 . should_equal 6
Suite.runMain ~specs =
r = this.run specs
code = if r.is_fail then 1 else 0
System.exit code

View File

@ -1,13 +1,27 @@
from Standard.Base import all from Standard.Base import all
reverse_list = list -> ## PRIVATE
Reverses the provided list.
Arguments:
- list: The list to reverse.
reverse_list : List Any -> List
reverse_list list =
go = list -> acc -> case list of go = list -> acc -> case list of
Cons h t -> @Tail_Call go t (Cons h acc) Cons h t -> @Tail_Call go t (Cons h acc)
Nil -> acc Nil -> acc
res = go list Nil res = go list Nil
res res
sum_list = list -> ## PRIVATE
Sums the elements of the list.
Arguments:
- list: The list of numbers to sum.
sum_list : List Number -> Sum
sum_list list =
go = list -> acc -> case list of go = list -> acc -> case list of
Cons a b -> @Tail_Call go b (acc + a) Cons a b -> @Tail_Call go b (acc + a)
Nil -> acc Nil -> acc
@ -15,21 +29,50 @@ sum_list = list ->
res = go list 0 res = go list 0
res res
avg_list = list -> here.sum_list list / here.len_list list ## PRIVATE
len_list = list -> Calculate the average of the elements of a numeric list.
Arguments:
- list: The list of numbers to calculate the average of.
avg_list : List Number -> Number
avg_list list = here.sum_list list / here.len_list list
## PRIVATE
Calculates the length of the provided list.
Arguments:
- list: The list to calculate the length of.
len_list : List Any -> Integer
len_list list =
go = list -> acc -> case list of go = list -> acc -> case list of
Cons _ b -> @Tail_Call go b (acc + 1) Cons _ b -> @Tail_Call go b (acc + 1)
Nil -> acc Nil -> acc
res = go list 0 res = go list 0
res res
Number.times = act -> ## PRIVATE
Perform an action a number of times.
Arguments:
- act: The action to perform `this` number of times.
Number.times : List Any
Number.times act =
go = results -> number -> if number == 0 then results else go = results -> number -> if number == 0 then results else
@Tail_Call go (Cons (act number) results) number-1 @Tail_Call go (Cons (act number) results) number-1
res = here.reverse_list (go Nil this) res = here.reverse_list (go Nil this)
res res
## Measure the amount of time it takes to execute a given computation.
Arguments:
- act: The action to perform.
- label: A name for the measurement.
- iter_size: The number of runs per iteration.
- num_iters: The number of iterations per measurement.
measure : Any -> Text -> Integer -> Integer -> Nothing
measure = ~act -> label -> iter_size -> num_iters -> measure = ~act -> label -> iter_size -> num_iters ->
single_call = _ -> single_call = _ ->
x1 = System.nano_time x1 = System.nano_time
@ -43,3 +86,4 @@ measure = ~act -> label -> iter_size -> num_iters ->
fmt = (avg / 1000000).format "%.2f" fmt = (avg / 1000000).format "%.2f"
IO.println (label + "/iteration:" + act_it_num.to_text + ": " + fmt + "ms") IO.println (label + "/iteration:" + act_it_num.to_text + ": " + fmt + "ms")
num_iters.times iteration num_iters.times iteration

View File

@ -6,12 +6,16 @@ import Standard.Visualization.Helpers
Prepares the query for visualization. Prepares the query for visualization.
Arguments:
- x: The query to prepare for visualisation.
For each interpolation it provides its value, its actual type name, its For each interpolation it provides its value, its actual type name, its
expected SQL type name and if it was possible to infer it, its expected Enso expected SQL type name and if it was possible to infer it, its expected Enso
typename. typename.
Expected Enso types are inferred based on known SQL types and their mapping Expected Enso types are inferred based on known SQL types and their mapping
to Enso types. to Enso types.
prepare_visualization : Table.IR.Query -> Json
prepare_visualization x = Helpers.recover_errors <| prepare_visualization x = Helpers.recover_errors <|
prepared = x.to_sql.prepare prepared = x.to_sql.prepare
code = prepared.first code = prepared.first
@ -29,8 +33,12 @@ prepare_visualization x = Helpers.recover_errors <|
Return an expected Enso type for an SQL type. Return an expected Enso type for an SQL type.
Arguments:
- sql_type: The SQL type to convert to an Enso type.
Expected Enso types are only inferred for some known SQL types. For unknown Expected Enso types are only inferred for some known SQL types. For unknown
types it will return `Nothing`. types it will return `Nothing`.
find_expected_enso_type_for_sql : Sql_Type -> Text
find_expected_enso_type_for_sql sql_type = find_expected_enso_type_for_sql sql_type =
if sql_type.is_definitely_integer then "Builtins.Main.Integer" else if sql_type.is_definitely_integer then "Builtins.Main.Integer" else
if sql_type.is_definitely_double then "Builtins.Main.Decimal" else if sql_type.is_definitely_double then "Builtins.Main.Decimal" else

View File

@ -7,11 +7,17 @@ import Standard.Database.Data.Column as Database_Column
import Standard.Visualization.Helpers import Standard.Visualization.Helpers
# TODO add an initial offset to fully support lazy visualizations # TODO add an initial offset to fully support lazy visualizations
## PRIVATE ## PRIVATE
Prepares a table or column for visualization. Prepares a table or column for visualization.
Arguments:
- x: The table to prepare for visualisation.
- max_rows: The maximum number of rows to display.
In case of Database backed data, it materializes a fragment of the data. In case of Database backed data, it materializes a fragment of the data.
prepare_visualization : Any -> Integer -> Json
prepare_visualization x max_rows = Helpers.recover_errors <| case x of prepare_visualization x max_rows = Helpers.recover_errors <| case x of
Dataframe_Table.Table _ -> Dataframe_Table.Table _ ->
dataframe = x.take_start max_rows dataframe = x.take_start max_rows
@ -71,6 +77,7 @@ prepare_visualization x max_rows = Helpers.recover_errors <| case x of
`dataframe`. `dataframe`.
- all_rows_count: the number of all rows in the underlying data, useful if - all_rows_count: the number of all rows in the underlying data, useful if
only a fragment is displayed. only a fragment is displayed.
make_json : Table -> Vector Column -> Integer -> Json
make_json dataframe indices all_rows_count = make_json dataframe indices all_rows_count =
columns = dataframe.columns columns = dataframe.columns
header = ["header", columns.map .name] header = ["header", columns.map .name]

View File

@ -1,6 +1,7 @@
package org.enso.interpreter.epb.node; package org.enso.interpreter.epb.node;
import com.oracle.truffle.api.*; import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.TruffleLanguage.ContextReference; import com.oracle.truffle.api.TruffleLanguage.ContextReference;
import com.oracle.truffle.api.dsl.CachedContext; import com.oracle.truffle.api.dsl.CachedContext;
import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.dsl.Specialization;
@ -8,20 +9,16 @@ import com.oracle.truffle.api.exception.AbstractTruffleException;
import com.oracle.truffle.api.frame.FrameDescriptor; import com.oracle.truffle.api.frame.FrameDescriptor;
import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.UnknownIdentifierException;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.nodes.IndirectCallNode;
import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.api.nodes.RootNode;
import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.source.Source;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.enso.interpreter.epb.EpbContext; import org.enso.interpreter.epb.EpbContext;
import org.enso.interpreter.epb.EpbLanguage; import org.enso.interpreter.epb.EpbLanguage;
import org.enso.interpreter.epb.EpbParser; import org.enso.interpreter.epb.EpbParser;
import org.enso.interpreter.epb.runtime.GuardedTruffleContext; import org.enso.interpreter.epb.runtime.GuardedTruffleContext;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public abstract class ForeignEvalNode extends RootNode { public abstract class ForeignEvalNode extends RootNode {
private final EpbParser.Result code; private final EpbParser.Result code;
private @Child ForeignFunctionCallNode foreign; private @Child ForeignFunctionCallNode foreign;

View File

@ -30,7 +30,7 @@ type Boolean
Arguments: Arguments:
- that: The boolean to compute the conjunction of this with. - that: The boolean to compute the conjunction of this with.
? Short Circuiting ! Short Circuiting
This method is not implemented in a short-circuiting manner. This means This method is not implemented in a short-circuiting manner. This means
that even if this is False, it will also evaluate that. This is that even if this is False, it will also evaluate that. This is
for performance. for performance.
@ -46,7 +46,7 @@ type Boolean
Arguments: Arguments:
- that: The boolean to compute the disjunction of this with. - that: The boolean to compute the disjunction of this with.
? Short Circuiting ! Short Circuiting
This methid is not implemented in a short-circuiting manner. This means This methid is not implemented in a short-circuiting manner. This means
that even if this is True, it will also evaluate that. This is that even if this is True, it will also evaluate that. This is
for performance. for performance.
@ -232,6 +232,10 @@ type Error
get_stack_trace_text = @Builtin_Method "Error.get_stack_trace_text" get_stack_trace_text = @Builtin_Method "Error.get_stack_trace_text"
## Converts an error to a corresponding textual representation. ## Converts an error to a corresponding textual representation.
> Example
Converting a thrown error to text.
Error.throw "foo" . to_text
to_text : Text to_text : Text
to_text = @Builtin_Method "Error.to_text" to_text = @Builtin_Method "Error.to_text"
@ -853,11 +857,6 @@ type Array
Arguments: Arguments:
- index: The index to get the element from. - index: The index to get the element from.
? Safety
If index >= this.length, then this operation will result in an
Invalid_Array_Index_Error exception. If the element at index is
null, then this method will return null.
> Example > Example
Get the element at index 1. Get the element at index 1.
[1,2,3].to_array.at 1 [1,2,3].to_array.at 1
@ -951,8 +950,8 @@ type Ref
## The root type of the Enso numeric hierarchy. ## The root type of the Enso numeric hierarchy.
If a Number is expected, then the program can provide both a Decimal and If a Number is expected, then the program can provide either a Decimal or
an Integer in this place. an Integer in its place.
@Builtin_Type @Builtin_Type
type Number type Number
@ -1497,7 +1496,9 @@ type Resource
@Builtin_Type @Builtin_Type
type Resource type Resource
## Acquires a resource, performs an action on it, and destroys it safely, ## ADVANCED
Acquires a resource, performs an action on it, and destroys it safely,
even in the presence of panics. even in the presence of panics.
Arguments: Arguments:
@ -1520,17 +1521,25 @@ type Managed_Resource
@Builtin_Type @Builtin_Type
type Managed_Resource type Managed_Resource
## Registers a resource with the resource manager to be cleaned up using ## ADVANCED
Registers a resource with the resource manager to be cleaned up using
function once it is no longer in use. function once it is no longer in use.
Arguments: Arguments:
- resource: The resource to be managed automatically. - resource: The resource to be managed automatically.
- function: The action to be executed on resource to clean it up when - function: The action to be executed on resource to clean it up when
it is no longer in use. it is no longer in use.
> Example
Registering a managed resource.
Managed_Resource
register : Any -> (Any -> Nothing) -> Managed_Resource register : Any -> (Any -> Nothing) -> Managed_Resource
register resource function = @Builtin_Method "Managed_Resource.register" register resource function = @Builtin_Method "Managed_Resource.register"
## Forces finalization of a managed resource using the registered finalizer, ## ADVANCED
Forces finalization of a managed resource using the registered finalizer,
even if the resource is still reachable. even if the resource is still reachable.
Arguments: Arguments:
@ -1538,7 +1547,9 @@ type Managed_Resource
finalize : Managed_Resource -> Nothing finalize : Managed_Resource -> Nothing
finalize resource = @Builtin_Method "Managed_Resource.finalize" finalize resource = @Builtin_Method "Managed_Resource.finalize"
## Executes the provided action on the resource managed by the managed ## ADVANCED
Executes the provided action on the resource managed by the managed
resource object. resource object.
Arguments: Arguments:
@ -1548,7 +1559,9 @@ type Managed_Resource
with : Managed_Resource -> (Any -> Any) -> Any with : Managed_Resource -> (Any -> Any) -> Any
with resource ~action = @Builtin_Method "Managed_Resource.with" with resource ~action = @Builtin_Method "Managed_Resource.with"
## Takes the value held by the managed resource and unregisters the ## ADVANCED
Takes the value held by the managed resource and unregisters the
finalization step for this resource, effectively removing it from the finalization step for this resource, effectively removing it from the
managed resources system. managed resources system.

View File

@ -5,7 +5,7 @@ import Database_Tests.Codegen_Spec
import Database_Tests.Sqlite_Spec import Database_Tests.Sqlite_Spec
import Database_Tests.Postgresql_Spec import Database_Tests.Postgresql_Spec
main = Test.Suite.runMain <| main = Test.Suite.run_main <|
Codegen_Spec.spec Codegen_Spec.spec
Sqlite_Spec.spec Sqlite_Spec.spec
Postgresql_Spec.spec Postgresql_Spec.spec

View File

@ -13,7 +13,7 @@ sqlite_specific_spec connection =
action = connection.execute_query "SELECT A FROM undefined_table" action = connection.execute_query "SELECT A FROM undefined_table"
action . should_fail_with Sql_Error action . should_fail_with Sql_Error
action.catch.to_text . should_equal "[SQLITE_ERROR] SQL error or missing database (no such table: undefined_table)" action.catch.to_text . should_equal "There was an SQL error: '[SQLITE_ERROR] SQL error or missing database (no such table: undefined_table)'."
Test.group "[SQLite] Metadata" <| Test.group "[SQLite] Metadata" <|
connection.execute_update 'CREATE TABLE "Tinfo" ("strs" VARCHAR, "ints" INTEGER, "bools" BOOLEAN, "reals" REAL)' connection.execute_update 'CREATE TABLE "Tinfo" ("strs" VARCHAR, "ints" INTEGER, "bools" BOOLEAN, "reals" REAL)'

View File

@ -4,5 +4,5 @@ import Standard.Test
import Geo_Tests.Geo_Spec import Geo_Tests.Geo_Spec
main = Test.Suite.runMain <| main = Test.Suite.run_main <|
Geo_Spec.spec Geo_Spec.spec

View File

@ -5,7 +5,7 @@ import Image_Tests.Codecs_Spec
import Image_Tests.Data.Image_Spec import Image_Tests.Data.Image_Spec
import Image_Tests.Data.Matrix_Spec import Image_Tests.Data.Matrix_Spec
main = Test.Suite.runMain <| main = Test.Suite.run_main <|
Codecs_Spec.spec Codecs_Spec.spec
Matrix_Spec.spec Matrix_Spec.spec
Image_Spec.spec Image_Spec.spec

View File

@ -5,6 +5,6 @@ import Standard.Test
import Table_Tests.Table_Spec import Table_Tests.Table_Spec
import Table_Tests.Column_Spec import Table_Tests.Column_Spec
main = Test.Suite.runMain <| main = Test.Suite.run_main <|
Column_Spec.spec Column_Spec.spec
Table_Spec.spec Table_Spec.spec

View File

@ -40,7 +40,7 @@ import Tests.Network.Uri_Spec
import Tests.System.File_Spec import Tests.System.File_Spec
import Tests.System.Process_Spec import Tests.System.Process_Spec
main = Test.Suite.runMain <| main = Test.Suite.run_main <|
Any_Spec.spec Any_Spec.spec
Array_Spec.spec Array_Spec.spec
Case_Spec.spec Case_Spec.spec

View File

@ -9,7 +9,7 @@ import Visualization_Tests.Scatter_Plot_Spec
import Visualization_Tests.Sql_Spec import Visualization_Tests.Sql_Spec
import Visualization_Tests.Table_Spec import Visualization_Tests.Table_Spec
main = Test.Suite.runMain <| main = Test.Suite.run_main <|
Geo_Map_Spec.spec Geo_Map_Spec.spec
Helpers_Spec.spec Helpers_Spec.spec
Histogram_Spec.spec Histogram_Spec.spec