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

View File

@ -1,6 +1,6 @@
license: APLv2
name: Standard
enso-version: default
version: "0.0.1"
version: "0.1.0"
author: "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.`
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
structure, and each of the values of their fields are recursively equal.
Two values are considered to be equal in Enso when they obey the following
recursive properties:
- At each level, they have the same structure.
- The value of each field in `this` is equal (by this definition) to the
corresponding field in `that`.
! Implementing Your Own Equality
Equality in Enso is defined to allow comparison of any two values
(universal equality), no matter if they are not directly comparable. When
implementing equality for your own types, keep in mind that it needs to
work with any Enso value as the `that` argument.
? Generic Equality and Performance
While the generic equality provided here will work for _all_ values in
Enso, its performance may often be suboptimal. Many types can implement
their own equality operations that will be more efficient than these.
> Example
Checking if 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
## Constructor comparison is covered by the identity 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
## 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:
- that: The object to compare `this` against.
! Implementing Your Own Inequality
We recommend that you do not implement your own inequality, instead relying
on the default definition given here. If you do, please ensure that you
satisfy universal equality, as described in the documentation for `Any.==`.
> Example
Checking if 1 is not equal to 2.
1 != 2
@ -45,53 +64,111 @@ Any.!= that = (this == that).not
## Checks if `this` is greater than `that`.
Arguments:
- that: The value to compare `this` against.
To have `>` defined, a type must define `compare_to`, returning an Ordering.
! Implementing Greater Than
Many types can admit a definition of greater than that is more efficient
than the generic one given here. When implementing this for your own types
please ensure that it is semantically equivalent to using `.compare_to`.
> Example
Compare two integers.
1 > 10 == False
Checking if 1 is greater than 10.
1 > 10
Any.> : Any -> Boolean
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`.
Arguments:
- that: The value to compare `this` against.
To have `<` defined, a type must define `compare_to`, returning an Ordering.
! Implementing Less Than
Many types can admit a definition of less than that is more efficient than
the generic one given here. When implementing this for your own types
please ensure that it is semantically equivalent to using `.compare_to`.
> Example
Compare two integers.
1 < 10 == True
Checking if 1 is less than 10.
1 < 10
Any.< : Any -> Boolean
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
Checking if a variable `a` is nothing.
a.is_nothing
Checking if 1 is less than or equal to 10.
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 = case this of
Nothing -> True
_ -> False
## Executes the provided handler on a dataflow error, or executes as identity on
a non-error value.
## Executes the provided handler on a dataflow error, or returns a non-error
value unchanged.
Arguments:
- handler: The function to call on this if it is an error value. By default
this is identity.
> Example
Catching an erroneous value to perform some operation on it.
(Time.Time_Error "Message").catch (err -> IO.println err)
Catching an erroneous value and getting the length of its message.
(Time.Time_Error "Message").catch (err -> err.error_message.length)
Any.catch : (Error -> Any) -> Any
Any.catch (handler = x->x) = this.catch_primitive handler
## Maps a dataflow 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.
## Transforms an error.
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
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 _ = this
## Checks if the underlying value is an error.
## Checks if `this` is an error.
Any.is_error : Boolean
Any.is_error = False
@ -108,6 +185,11 @@ Any.is_error = False
Arguments:
- argument: The argument to apply `this` to.
? Piping Blocks to Functions
This construction is particularly useful for passing a block as an argument
to a function. This means that you can compute more sophisticated values
in-line, as shown in the example below.
> Example
Applying a function to a block.
(x -> x + 1) <|
@ -121,28 +203,35 @@ Any.<| ~argument = this argument
Arguments
- function: The function to apply to `this`.
? `|>` or `.`?
The eagle-eyed reader will notice that the operator dot (`.`) is very
similar to the operator `|>`. In Enso, with the variable precedence of
operators, this makes perfect sense. In general, we recommend using `.`.
However, there are some contexts where variable precedence might be unclear
or confusing, or where the function being applied is not a method. In these
contexts we recommend using `|>`.
> Example
Applying a function in a pipeline.
1 |> (* 2)
Applying multiple functions in a pipeline to compute a number and transform
it to text.
1 |> (* 2) |> (/ 100) |> .to_text
Any.|> : (Any -> Any) -> Any
Any.|> function = function this
Any.|> ~function = function this
## Composes two functions together.
For `f << g`, this creates the function composition `f ∘ g`.
## Composes two functions together, for `f << g` creating the function
composition `f ∘ g` (equivalent to `x -> f (g x)`).
Arguments:
- that: The function to compose with `this`.
> Example
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
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.
For `f >> g`, this creates the function composition `g ∘ f`.
## Composes two functions together in the forward direction, for `f >> g`
creating the function composition `g ∘ f` (equivalent to `x -> g (f (x))`).
Arguments:
- that: The function to compose with `this`.
@ -151,16 +240,22 @@ Any.<< that = x -> this (that x)
Add one and then multiply by two as a function applied to 2.
(+1 >> *2) 2
Any.>> : (Any -> Any) -> (Any -> Any) -> Any -> Any
Any.>> that = x -> that (this x)
Any.>> ~that = x -> that (this x)
## UNSTABLE
ADVANCED
Returns a Text used to display this value in the IDE. The particular
representation is left unspecified and subject to change in the future.
The current implementation uses a JSON serialization as the default.
Returns a Text used to display this value in the IDE.
The particular representation is left unspecified and subject to change in
the future. The current implementation uses JSON serialization as the
default.
Types defining their own versions of this method should ensure that the
result is reasonably small and 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 = this.to_json.to_text

View File

@ -1,8 +1,18 @@
from Standard.Base import all
## Transform the array into text for displaying as part of its default
visualization.
## UNSTABLE
ADVANCED
Returns a Text used to display this value in the IDE.
The particular representation is left unspecified and subject to change in
the future. The current implementation uses JSON serialization as the
default.
> 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 =
Array.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
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
## Checks if the interval contains `that`.
Arguments:
- that: The item to check if it is contained in the interval.
> Example
Checking if the interval 1 to 5 contains 7.
(Interval.inclusive 1 5) . contains 7
@ -56,6 +65,10 @@ type Interval
Bound.Inclusive e -> that <= e
## 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 = case this.start of
Bound.Exclusive s -> case this.end of
@ -66,6 +79,10 @@ type Interval
Bound.Inclusive e -> s > e
## 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 = 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.
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
## 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
## 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

View File

@ -4,19 +4,47 @@ import Standard.Base.Data.Json.Internal
## Represents a JSON structure.
type Json
## A representation of a JSON object.
Arguments:
- fields: The fields of the JSON object.
type Object fields
## A representation of a JSON array.
Arguments:
- items: The items in the JSON array.
type Array items
## A representation of a JSON string.
Arguments:
- value: The text contained in the JSON string.
type String value
## A representation of a JSON number.
Arguments:
- value: The number contained in the JSON number.
type Number value
## A representation of a JSON boolean.
Arguments:
- value: The boolean contained in a JSON boolean.
type Boolean value
## A representation of a JSON null.
type Null
## Marshalls this JSON into an arbitrary value described by
`type_descriptor`.
The type descriptor is a fully-applied type, describing all required
sub-types. It can either be an Atom or one of the primitive types
(`Number`, `Text`, `Boolean`, `Vector`).
Arguments:
- `type_dscriptor`: The type descriptor is a fully-applied type,
describing all required sub-types. It can either be an Atom or one of
the primitive types (`Number`, `Text`, `Boolean`, `Vector`).
> Example
The following shows an example of reading a nested JSON into a desired
@ -63,10 +91,18 @@ type Json
to_json = this
## 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 = Internal.render_helper "" this
## 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 = case this of
Json.Array its -> its.map .unwrap
@ -76,21 +112,36 @@ type Json
Json.Null -> Nothing
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.
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 = "Parse error in parsing JSON: " + this.message.to_text + "."
## Gets the value associated with the given key in this object. Returns
`Nothing` if the associated key is not defined.
Object.get : Text -> Json | Nothing
## Gets the value associated with the given key in this object.
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
## 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 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)
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.
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.
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.
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.
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,
when the JSON does not contain all the fields required by the atom.
type Missing_Field_Error json field format
## UNSTABLE
Convert the marshalling error into a human-readable format.
to_display_text : Text
to_display_text = case this of
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 atom's type name and all other fields serialized with their name as
object key and the value as the object value.
> Example
Convert a vector to JSON.
[1, 2, 3, 4].to_json
Any.to_json =
m = Meta.meta this
case m of
@ -147,20 +221,35 @@ Any.to_json =
Meta.Primitive _ -> Null
## 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 = 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 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
## A smart constructor, building an object representation based on a vector
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.
> 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.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.
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
## 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
Nil -> Ref.put this.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.
seal_child : Nothing
seal_child =
child = Ref.get this.child_consumer
val = child.seal
@ -28,92 +49,202 @@ type Consumer
Ref.put this.child_consumer p
p.on_value val
## Consumes the `start_object` event.
## PRIVATE
Consumes the `start_object` event.
on_start_object : Nothing
on_start_object =
parent = Ref.get this.child_consumer
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
## Consumes the `end_object` event.
## PRIVATE
Consumes the `end_object` event.
on_end_object : Nothing
on_end_object = this.seal_child
## Consumes the `start_array` event.
## PRIVATE
Consumes the `start_array` event.
on_start_array : Nothing
on_start_array =
parent = Ref.get this.child_consumer
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
## 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)
## 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)
## 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)
## Consumes the `true` event.
## PRIVATE
Consumes the `true` event.
on_true : Nothing
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)
## Consumes the `null` event.
## PRIVATE
Consumes the `null` event.
on_null : Nothing
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
## 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
## Consumes a value.
## PRIVATE
Consumes a value.
Arguments:
- v: The value to process.
on_value : Any -> Nothing
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 =
vec = this.builder.to_vector
Array vec
## A child consumer, used to process events inside objects.
## PRIVATE
A child consumer, used to process events inside objects.
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
## 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
## Consumes a value.
## PRIVATE
Consumes a value.
Arguments:
- v: The value to process.
on_value : Any -> Nothing
on_value v =
k = Ref.get this.last_key
m = Ref.get this.map
new_m = m.insert k v
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 =
m = Ref.get this.map
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 =
k = Ref.new ""
m = Ref.new Map.empty
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 =
bldr = Vector.new_builder
Array_Consumer bldr parent
## Creates a new top-level consumer.
## PRIVATE
Creates a new top-level consumer.
mk_consumer : Consumer
mk_consumer =
child = Ref.new Nil
val = Ref.new Nothing
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
Object fields ->
r = Ref.new ""
@ -143,9 +274,16 @@ render_helper builder json = case json of
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.
into_helper : Any -> Json -> Any
into_helper fmt json = case fmt of
Base.Vector.Vector field -> case json of
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)
## 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 json_text =
consumer = here.mk_consumer

View File

@ -4,6 +4,11 @@ from Builtins export Nil, Cons
## PRIVATE
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
a tail-recursive manner. The mutation is purely internal and does not leak
to the user-facing API.
@ -16,7 +21,7 @@ map_helper list cons f = case list of
## 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,
while an empty list is represented by `Nil`.
@ -29,12 +34,20 @@ type List
Cons
## 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 = this.fold 0 (acc -> _ -> acc + 1)
## Combines all the elements of the list, by iteratively applying the
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
(Cons l0 <| Cons l1 <| ... <| Cons ln) . fold init f
is the same as
@ -54,8 +67,10 @@ type List
## Checks whether any element of the list matches the given predicate.
A predicate is a function that takes a list element 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
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.
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 Boolean value.
@ -84,6 +104,11 @@ type 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
Check if all elements in the list are less than zero.
(Cons 1 (Cons 2 Nil)).all (< 0)
@ -92,6 +117,9 @@ type List
## Checks whether this list contains a given value as an element.
Arguments:
- elem: The element to check if it is in the list.
> Example
Checking if the list contains the number 72.
(Cons 1 (Cons 72 Nil)).contains 72
@ -118,9 +146,14 @@ type List
## 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
Selecting all elements that are greater than 3.
(Cons 1 Nil).filter (> 3)
(Cons 1 Nil).filter (> 3)
filter : (Any -> Boolean) -> List
filter predicate =
case this of
@ -132,11 +165,12 @@ type List
## Applies a function to each element of the list, returning the list of
results.
Arguments:
- f: The function to apply to each element of the list.
> 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
The result of running the code above is:
Cons 1 <| Cons 2 <| Cons 3 <| Nil
map : (Any -> Any) -> List
map f = case this of
Nil -> Nil
@ -147,12 +181,14 @@ type 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,
therefore it is only useful for side-effecting computations.
> Example
In the following example, we're printing each element of the list
to the standard output:
Print each of the list elements to the standard output.
(Cons 0 <| Cons 1 <| Cons 2 <| Nil) . each IO.println
each : (Any -> Any) -> Nothing
each f =
@ -176,6 +212,9 @@ type List
## Creates a new list with the first `count` elements at the start of `this`
removed.
Arguments:
- count: The number of elements to take drop the start of `this`.
> Example
Removing the first element from a list.
(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
of `this`.
Arguments:
- count: The number of elements to take from the start of `this`.
> Example
Obtaining the first 2 elements of a list.
(Cons 1 (Cons 2 (Cons 3 Nil))).take_start 2

View File

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

View File

@ -2,19 +2,39 @@ from Standard.Base import all
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
## Returns an empty map.
> Example
Create an empty map.
Map.empty
empty : Map
empty = Tip
## 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 key value = Bin 1 key value Tip Tip
## Builds a map from a vector of key-value pairs.
Arguments:
- vec: A vector of key-value pairs.
> Example
Building a map containing two key-value pairs.
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,
using the `<`, `>` and `==` operators.
type Map
## PRIVATE
A key-value store. This type assumes all keys are pairwise comparable,
using the `<`, `>` and `==` operators.
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
## 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 = case this of
Bin _ _ _ _ _ -> False
Tip -> True
## 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 = this.is_empty.not
## Returns the number of entries in this map.
> Example
Get the size of a singleton map.
Map.singleton 1 2 . size
size : Integer
size = case this of
Bin s _ _ _ _ -> s
Tip -> 0
## Converts the map into a vector of `[key, value]` pairs.
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 =
builder = Vector.new_builder
@ -60,23 +112,49 @@ type Map
result
## Returns a text representation of this map.
> Example
Convert an empty map to text.
Map.empty.to_text
to_text : Text
to_text = this.to_vector.to_text
## 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
associated with each key are pairwise equal.
> Example
Checking two singleton maps for equality.
(Map.singleton 1 2) == (Map.singleton 2 3)
== : Map -> Boolean
== that = this.to_vector == that.to_vector
## Inserts a key-value mapping into this map. If `key` is already present,
it will be overriden with the new `value`.
## Inserts a key-value mapping into this map, overriding any existing
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 key value = Internal.insert this key value
## Gets the value associated with `key` in this map, or returns a
`Nothing`, if `key` is not present.
## Gets the value associated with `key` in this map, or throws a `Nothing`,
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 key =
go map = case map of
@ -89,12 +167,25 @@ type Map
## Gets the value associated with `key` in this map, or returns `other` if
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 key ~other =
this.get key . catch (_ -> other)
## 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
Turn all keys into `Text` and double the values for a map `m`.
m.transform (k -> v -> [k.to_text, v*2])
@ -106,6 +197,10 @@ type 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
Turn all values into `Text` for a map `m`.
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
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
Adding the key to the value in a map `m`.
m.map_with_key (k -> v -> k + v)
@ -130,6 +229,10 @@ type 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
Doubling all keys in the map `m`.
m.map_keys (k -> k*2)
@ -140,6 +243,10 @@ type 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
computations with side-effects.
@ -153,6 +260,10 @@ type 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
computations with side-effects.
@ -172,6 +283,10 @@ type 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
Summing all of the values in the map `m`.
m.fold 0 (+)
@ -187,6 +302,11 @@ type 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
Sum the keys and values in the map `m`.
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
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 =
new_left = here.insert l key value
here.balance_left k v new_left r
## 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 =
new_right = here.insert r key value
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.
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
in a Functional Language" by Stephen Adams.
Implementation is based on Haskell's `Data.Map.Strict` implemented in the
`containers` package.
in a Functional Language" by Stephen Adams. The implementation is based on
Haskell's `Data.Map.Strict` as implemented in the `containers` package.
insert : Map -> Any -> Any -> Map
insert map key value = case map of
Bin s k v l r ->
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
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
Bin rs _ _ _ _ -> case l of
Bin ls lk lx ll lr ->
@ -62,6 +92,12 @@ balance_left k x l r = case r of
## PRIVATE
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
Bin ls _ _ _ _ -> case r of
Bin rs rk rx rl rr ->
@ -109,6 +145,10 @@ delta = 3
## PRIVATE
Gets the size of a map.
Arguments:
- m: The map to get the size of.
size: Map -> Integer
size m = case m of
Bin s _ _ _ _ -> s
_ -> 0

View File

@ -7,6 +7,9 @@ type Maybe
Nothing
## A value.
Arguments:
- value: The contained value in the maybe.
type Some value
## 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.
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
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.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
below.
type Generator
## PRIVATE
The basic generator type.
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.
- A range for output values, which should range over the chosen output
type.
@ -31,9 +39,23 @@ type Generator
It produces what is commonly termed "white" noise, where any value in the
range has an equal chance of occurring.
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
## 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 input interval =
max_long = Long.MAX_VALUE

View File

@ -7,99 +7,209 @@ polyglot java import java.lang.String
## Computes the inverse of the sine function
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 = Math.asin this.to_decimal
## Computes the inverse of the cosine function.
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 = Math.acos this.to_decimal
## Computes the inverse of the tangent function.
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 = Math.atan this.to_decimal
## 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.
> Example
Convert the coordinates 1 and 2 to polar form.
1.atan_2 2
Number.atan_2 : Number -> Decimal
Number.atan_2 y = Math.atan2 this.to_decimal y.to_decimal
## Computes the sine function.
> Example
Calculate the sine of 2.
2.sin
Number.sin : Decimal
Number.sin = Math.sin this.to_decimal
## Computes the cosine function.
> Example
Calculate the cosine of 2.
2.cos
Number.cos : Decimal
Number.cos = Math.cos this.to_decimal
## Computes the tangent function.
> Example
Calculate the tangent of 2.
2.tan
Number.tan : Decimal
Number.tan = Math.tan this.to_decimal
## Computes the hyperbolic sine function.
> Example
Calculate the hyperbolic sine of 1.
1.sinh
Number.sinh : Decimal
Number.sinh = Math.sinh this.to_decimal
## Computes the hyperbolic cosine function.
> Example
Calcualte the hyperbolic cosine of 1.
1.cosh
Number.cosh : Decimal
Number.cosh = Math.cosh this.to_decimal
## Computes the hyperbolic tangent function.
> Example
Calculate the hyperbolic tangent of 1.
1.tanh
Number.tanh : 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 = Math.exp this.to_decimal
## Computes the natural logarithm function.
> Example
Calculate the natural logarithm of 2.
2.ln
Number.ln : Decimal
Number.ln = Math.log this.to_decimal
## Computes the square root of `this`.
> Example
Calculate the square root of 8.
8.sqrt
Number.sqrt : Decimal
Number.sqrt = Math.sqrt this.to_decimal
## 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 base = this.ln / base.ln
# TODO this should expose a more-user friendly API in the future.
## Converts a decimal value to a string, using the Java string formatting
## UNSTABLE The API will become more user-friendly in future.
Converts a decimal value to a string, using the Java string formatting
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 fmt = String.format fmt this
## 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 n = Range this n
## 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 that epsilon=0.0 = (this - that).abs <= epsilon
## 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 that = if this < that then this else 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 that = if this > that then this else that
## Number to JSON conversion.
> Example
Convert the number 8 to JSON.
8.to_json
Number.to_json : Json.Number
Number.to_json = Json.Number this
## Parses a textual representation of a decimal into a decimal number.
Returns `Nothing` if the text does not represent a valid decimal.
Decimal.parse : Text -> Decimal | Nothing
Decimal.parse text =
Panic.recover (Double.parseDouble text) . catch (_ -> Nothing)
## Parses a textual representation of a decimal into a decimal number, returning
`Nothing` if the text does not represent a valid decimal.
Arguments:
- 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
`that`. So, if `this` is greater than `that`, you should return `Greater.`
type Ordering
## An ordering where a compared value is less than another.
Less
## An ordering where a compared value is equal to another.
Equal
## An ordering where a compared value is greater than another.
Greater
## 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 = case this of
Less -> -1

View File

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

View File

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

View File

@ -2,6 +2,13 @@ from Standard.Base import all
## Represents a right-exclusive range of integer values.
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
## Get the number of elements in the range.
@ -30,6 +37,9 @@ type Range
## Applies a function for each element in the range.
Arguments:
- function: The function to apply to each integer in the range.
> Example
To print all the numbers from 1 to 100 use:
1.up_to 101 . each IO.println
@ -44,6 +54,11 @@ type Range
## Combines all the elements of the range, by iteratively applying the
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
Range start end . fold init f
is the same as
@ -53,18 +68,20 @@ type Range
In the following example, we'll compute the sum of all elements of a
range:
Range 0 100 . fold 0 (+)
fold : Any -> (Number -> Any) -> Any
fold initial function =
fold : Any -> (Any -> Number -> Any) -> Any
fold init function =
it acc start end = if start == end then acc else
new_acc = function acc start
@Tail_Call it new_acc start+1 end
res = it initial this.start this.end
res = it init this.start this.end
res
## 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
a boolean.
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
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.
A predicate is a function that takes an element in the range and returns
a boolean.
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
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.
A predicate is a function that takes an element in the range and returns
a boolean.
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
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.
A character is defined as an Extended Grapheme Cluster, see
Unicode Standard Annex 29.
! 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.
This is the smallest unit that still has semantic meaning in most
text-processing applications.
> Example
Getting the length of the string "건반(Korean)".
"건반(Korean)".length
Text.length : Integer
Text.length =
iterator = BreakIterator.getCharacterInstance
@ -30,13 +33,19 @@ Text.length =
@Tail_Call count counter next_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
Unicode Standard Annex 29.
Arguments:
- function: The operation to apply to each character in the text.
This is the smallest unit that still has semantic meaning in most
text-processing applications.
! 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
Print each character in the text "aaa".
"aaa".each IO.println
Text.each : (Text -> Any) -> Nothing
Text.each function =
iterator = BreakIterator.getCharacterInstance
@ -54,11 +63,14 @@ Text.each function =
## Returns a vector containing all characters in the given text.
A character is defined as an Extended Grapheme Cluster, see
Unicode Standard Annex 29.
! 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.
This is the smallest unit that still has semantic meaning in most
text-processing applications.
> Example
Get the individual characters in the text "건반(Korean)".
"건반(Korean)".characters
Text.characters : Vector.Vector
Text.characters =
bldr = Vector.new_builder
@ -68,12 +80,16 @@ Text.characters =
## Takes a separator string and returns a vector resulting from splitting
`this` on each occurence of `separator`.
Arguments:
- separator: The separator to use to split the text.
> Example
In the following example, we'll split the text into a vector of
comma-separated items:
Split the comma-separated text into a vector of items.
"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 (separator = Split_Kind.Whitespace) =
result = case separator of
@ -85,12 +101,15 @@ Text.split (separator = Split_Kind.Whitespace) =
## Returns a vector containing all words in the given text.
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.
Arguments:
- keep_whitespace: Whether or not the whitespace around the words should be
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
this can be enabled.
! What is a Word?
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
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`.
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.
Arguments:
- that: The text to compare `this` for equality 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
The string 'é' (i.e. the character U+00E9, LATIN SMALL LETTER E WITH
ACUTE) is canonically the same as the string 'e\u0301' (i.e. the letter
`e` followed by U+0301, COMBINING ACUTE ACCENT). Therefore:
The string 'é' (i.e. the character U+00E9, LATIN SMALL LETTER E WITH ACUTE)
is canonically the same as the string 'e\u0301' (i.e. the letter `e`
followed by U+0301, COMBINING ACUTE ACCENT). Therefore:
('é' == 'e\u0301') == True
Text.== : Any -> Boolean
Text.== that = if Meta.is_same_object this Text then Meta.is_same_object that Text else
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
and corresponding characters are equal ignoring case.
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.
! 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
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,
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
ACCENT). Therefore:
(('É' . equals_ignore_case 'é') && ('é' == 'e\u0301')) == True
Text.equals_ignore_case : Text -> Boolean
Text.equals_ignore_case that = Text_Utils.equals_ignore_case this that
## Compare two texts to discover their ordering.
Arguments:
- that: The text to order `this` with respect to.
> Example
Checking how "a" orders in relation 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
## 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 = this == ""
## 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 = 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
decoding.
> Example
Get the UTF-8 bytes of the text "Hello".
"Hello".utf_8
Text.utf_8 : Vector.Vector
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
UTF-8.
## Takes a vector of bytes and returns Text resulting from decoding it as UTF-8.
Arguments:
- bytes: The vector of UTF-8 bytes.
This is useful for low-level operations, such as binary data encoding and
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 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
decoding.
> Example
Get the codepoints of the text "Hello".
"Hello".codepoints
Text.codepoints : Vector.Vector
Text.codepoints =
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
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 codepoints = Text_Utils.from_codepoints codepoints.to_array
## 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 prefix = Text_Utils.starts_with this prefix
## 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 suffix = Text_Utils.ends_with this suffix
## 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 sequence = Text_Utils.contains this 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.
> Example
Replace letters in the text "aaa".
'aaa'.replace 'aa' 'b' == 'ba'
Text.replace : Text -> Text -> Text
Text.replace old_sequence new_sequence = Text_Utils.replace this old_sequence new_sequence
## Text to JSON conversion.
> Example
Convert the text "cześć" to JSON.
"cześć".to_json
Text.to_json : Json.String
Text.to_json = Json.String this
## Takes a non-negative integer and returns a new text, consisting of `count`
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 count =
0.up_to count . fold "" acc-> _-> acc + 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
is returned.
## Creates a new text by removing the first `count` characters of `this`,
returning an empty text if `count` is greater than or equal to the length of
`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 count =
iterator = BreakIterator.getCharacterInstance
@ -247,9 +375,21 @@ Text.drop_first count =
boundary = iterator.next count
if boundary == -1 then '' else Text_Utils.drop_first this boundary
## 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
is returned.
## Creates a new text by removing the last `count` characters of `this`,
returning an empty text if `count` is greater than or equal to the length of
`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 count =
iterator = BreakIterator.getCharacterInstance
@ -258,9 +398,20 @@ Text.drop_last count =
boundary = iterator.next -count
if boundary == -1 then '' else Text_Utils.substring this 0 boundary
## 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
`this` is returned.
## Creates a new text by selecting the first `count` characters of `this`,
returning `this` if `count` is greater than or equal to the length of `this`.
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 count =
iterator = BreakIterator.getCharacterInstance
@ -269,9 +420,20 @@ Text.take_first count =
boundary = iterator.next count
if boundary == -1 then this else Text_Utils.substring this 0 boundary
## 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
`this` is returned.
## Creates a new text by selecting the last `count` characters of `this`,
returning `this` if `count` is greater than or equal to the length of `this`.
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 count =
iterator = BreakIterator.getCharacterInstance
@ -283,8 +445,13 @@ Text.take_last count =
## Converts each character in `this` to lower case.
Arguments:
- locale: specifies the locale for charater case mapping. Defaults to the
`Locale.default` locale.
- locale: specifies the locale for charater case mapping. Defaults to the
`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
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.
Arguments:
- locale: specifies the locale for charater case mapping. Defaults to
`Locale.default`.
- locale: specifies the locale for charater case mapping. Defaults to
`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
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.
type Split_Kind
## Split on unicode whitespace.
type Whitespace
## Split into lines.
type Lines
## Split into words.
type Words
## Split on a literal.
## Split on a literal text value.
Text

View File

@ -12,8 +12,12 @@ polyglot java import org.enso.base.Time_Utils
type Date
## This type represents a date, often viewed as year-month-day. For example,
the value "2nd October 2007" can be stored in a `Date`.
## This type represents a date, often viewed as year-month-day.
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
is a description of the date, as used for birthdays. It cannot represent
@ -22,56 +26,93 @@ type Date
type Date internal_local_date
## Get the year field.
> Example
Get the current year.
Date.now.year
year : Integer
year = this . internal_local_date . getYear
## Get the month of year field, as a number from 1 to 12.
> Example
Get the current month.
Date.now.month
month : Integer
month = this . internal_local_date . getMonthValue
## Get the day of month field.
> Example
Get the current day.
Date.now.day
day : Integer
day = this . internal_local_date . getDayOfMonth
## 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
Convert this date to midnight UTC time.
Day.new 2020 2 3 . to_time Time_Of_Day.new Zone.utc
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
Add 6 months to a local date.
Date.new 2020 + 6.months
+ : 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
Subtract 7 days from a local date.
Date.new 2020 - 7.days
- : 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.
> Example
Convert the current date to text.
Date.now.to_text
to_text : Text
to_text = Time_Utils.default_date_formatter . format this.internal_local_date
## A Date to Json conversion.
> Example
Convert the current date to JSON.
Date.now.to_json
to_json : Json.Object
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
example, "d MMM yyyy" will format "2011-12-03" as "3 Dec 2011".
Arguments:
- pattern: The text specifying the format for formatting the date.
For the list of accepted symbols in pattern refer to
`Base.Data.Time.Time.format` doc.
? Pattern Syntax
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
Format "2020-06-02" as "2 June 2020"
@ -95,33 +136,34 @@ type Date
format : Text -> Text
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:
- 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
provided `pattern`.
The text must represent a valid date and is parsed using the ISO-8601
extended local date format. The format consists of:
? Date Formatting
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
will be pre-padded by zero to ensure four digits. Years outside
that range will have a prefixed positive or negative symbol.
- A dash
- Two digits for the month-of-year. This is pre-padded by zero to ensure two
digits.
- A dash
- Two digits for the day-of-month. This is pre-padded by zero to ensure two
digits.
- 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
that range will have a prefixed positive or negative symbol.
- A dash
- Two digits for the month-of-year. This is pre-padded by zero to ensure
two digits.
- A dash
- Two digits for the day-of-month. This is pre-padded by zero to ensure two
digits.
> Example
Parse the date of 23rd December 2020.
Date.parse "2020-12-23"
> Example
Recover from the parse error.
Recover from an error due to a wrong format.
Date.parse "my birthday" . catch e-> case e of
Time.Error _ -> Date.new 2000 1 1
parse : Text -> Date ! Time.Time_Error
@ -130,18 +172,19 @@ parse text =
Polyglot_Error err -> Error.throw (Time.Time_Error err.getMessage)
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:
- text: The textual content to parse as a time.
- 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
provided `pattern`.
? Pattern Syntax
For the list of accepted symbols in pattern refer to the
`Base.Data.Time.Time.format` doc.
> Example
Parse "1999-1-1" as Date.
Date.parse_format "1999-1-1" "yyyy-M-d"
@ -159,18 +202,27 @@ parse_format text pattern =
x -> x
## Obtains the current date from the system clock in the system timezone.
> Example
Get the current date.
Date.now
now : Date
now = Date LocalDate.now
## Alias for `now`.
> Example
Get the current date.
Date.today
today : Date
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)
- day - the day-of-month to represent, from 1 to 31 and must be valid for the
year and month
Arguments
- month: The month-of-year to represent, from 1 (January) to 12 (December).
- 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.

View File

@ -9,9 +9,17 @@ type Duration
## An amount of time in terms of years, months, days, hours, minutes,
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
## 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
Add 6 seconds to a duration of 3 minutes
@ -21,9 +29,12 @@ type Duration
Add 12 hours to a duration of a month.
1.month + 12.hours
+ : 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
Subtract 11 months from a duration of 3 years
@ -33,37 +44,69 @@ type Duration
Substract 30 minutes from a duration of 7 months.
7.months - 30.minutes
- : 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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]
## A Duration to Json conversion.
> Example
Convert a duration of 10 seconds to Json.
10.seconds.to_json
to_json : Json.Object
to_json =
b = Vector.new_builder
@ -95,18 +142,37 @@ type Duration
Json.from_pairs b.to_vector
## 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 = (this.years==0 . not) || (this.months==0 . not) || (this.days==0 . not)
## 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 = (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.
> Example
Check if the duration of 10 seconds is empty.
10.seconds.is_empty
is_empty : Boolean
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
== 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.
Arguments:
- start_inclusive: The start time of the duration.
- end_inclusife: The end time of the duration.
> Example
An hour interval between two points in time.
Duration.between Time.now (Time.new 2010 10 20)
between : Time -> Time -> Duration
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)

View File

@ -12,7 +12,12 @@ polyglot java import org.enso.base.Time_Utils
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
@ -20,6 +25,9 @@ type Time
## A date-time with a timezone in the ISO-8601 calendar system, such as
"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
stores all date and time fields, to a precision of nanoseconds, and a
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`.
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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 (this . internal_zoned_date_time . getZone)
## 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 = this . internal_zoned_date_time . toEpochSecond
## 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 = 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 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 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
Convert time instance to -04:00 timezone.
@ -85,7 +146,10 @@ type Time
at_zone : Zone -> Time
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
Add 1 hour to a zoned date time.
@ -97,7 +161,11 @@ type Time
+ : Duration -> Time
+ 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
Subtract 10 days from a zoned date time.
@ -109,60 +177,72 @@ type Time
- : Duration -> Time
- 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 = 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.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
example, "d MMM uuuu" will format "2011-12-03" as "3 Dec 2011".
Arguments:
- 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"
- '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 list of accepted symbols with examples:
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
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:
- text: The text representing the time to be parsed.
The text must represent a valid date-time and is parsed using the ISO-8601
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:
? Valid Formatting
The text must represent a valid date-time and is parsed using the ISO-8601
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.
- If the zone ID is not available or is a zone offset then the format is
complete.
- An open square bracket '['.
- The zone ID. This is not part of the ISO-8601 standard. Parsing is case
sensitive.
- A close square bracket ']'.
- The ISO offset date time.
- If the zone ID is not available or is a zone offset then the format is
complete.
- An open square bracket '['.
- The zone ID. This is not part of the ISO-8601 standard. Parsing is case
sensitive.
- A close square bracket ']'.
This method will return a `Time_Error` if the provided time cannot be parsed
using the above format.
@ -225,7 +306,7 @@ parse text =
Polyglot_Error err -> Error.throw (Time_Error err.getMessage)
x -> x
## Obtains an instance of Time from a text using custom format.
## Converts text to a time using a provided format specifier.
Arguments:
- 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
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
Parse "2020-05-06 04:30:20" as Time
@ -251,6 +333,10 @@ parse_format text pattern locale=Locale.default =
x -> x
## Obtains the current date-time from the system clock in the system timezone.
> Example
Get the current time
Time.now
now : Time
now = Time ZonedDateTime.now

View File

@ -14,39 +14,71 @@ polyglot java import org.enso.base.Time_Utils
type Time_Of_Day
## This type is a date-time object that represents a time, often viewed
as hour-minute-second. Time is represented to nanosecond precision. For
example, the value "13:45.30.123456789" can be stored in a `Time_Of_Day`.
as hour-minute-second.
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
## 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 = 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 = 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 = 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 = this . internal_local_time . getNano
## 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 = this . internal_local_time . toSecondOfDay
## 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
Convert local time to 1st January 2020 12:30 at system timezone.
Time_Of_Day.new 12 30 . to_time (Date.new 2020)
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)
## 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
Add 3 seconds to a local time.
@ -54,7 +86,11 @@ type 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)
## 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
Subtract 12 hours from a local time.
@ -62,21 +98,33 @@ type 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)
## 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 = Time_Utils.default_time_of_day_formatter . format this.internal_local_time
## 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.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
example, "HH-mm-ss.SSS" will format "16:21:10" as "16-21-10.323".
Arguments:
- pattern: The pattern specifying how to format the time of day.
For the list of accepted symbols in pattern refer to
`Base.Data.Time.Time.format` doc.
? Pattern Syntax
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
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
default format.
The text must represent a valid time and is parsed using the ISO-8601
extended local time format. The format consists of:
? Valid Time Format
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
digits.
- A colon
- Two digits for the minute-of-hour. This is pre-padded by zero to ensure two
digits.
- If the second-of-minute is not available then the format is complete.
- A colon
- Two digits for the second-of-minute. This is pre-padded by zero to ensure
two digits.
- If the nano-of-second is zero or not available then the format is complete.
- A decimal point
- One to nine digits for the nano-of-second. As many digits will be output as
required.
- Two digits for the hour-of-day. This is pre-padded by zero to ensure two
digits.
- A colon
- Two digits for the minute-of-hour. This is pre-padded by zero to ensure
two digits.
- If the second-of-minute is not available then the format is complete.
- A colon
- Two digits for the second-of-minute. This is pre-padded by zero to ensure
two digits.
- If the nano-of-second is zero or not available then the format is
complete.
- A decimal point
- One to nine digits for the nano-of-second. As many digits will be output
as required.
> Example
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
provided pattern and locale.
For the list of accepted symbols in pattern refer to
`Base.Data.Time.Time.format` doc.
? Pattern Syntax
For the list of accepted symbols in pattern refer to the
`Base.Data.Time.Time.format` doc.
> Example
Parse "04:30:20" as Time_Of_Day.
@ -167,16 +218,21 @@ parse_format text pattern locale=Locale.default =
x -> x
## 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 LocalTime.now
## Obtains an instance of `Time_Of_Day` from an hour, minute, second
and nanosecond.
- hour - the hour-of-day to represent, from 0 to 23
- minute - the minute-of-hour to represent, from 0 to 59
- second - the second-of-minute to represent, from 0 to 59
- nanosecond - the nano-of-second to represent, from 0 to 999,999,999
Arguments:
- hour: The hour-of-day to represent, from 0 to 23.
- minute: The minute-of-hour to represent, from 0 to 59.
- 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.

View File

@ -7,20 +7,35 @@ type 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
"Europe/Paris".
type Zone internal_zone_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 = 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.from_pairs [["type", "Zone"], ["id", this.zone_id]]
## This method parses the ID producing a `Zone`.
Arguments:
- text: The text representing a zone identifier.
> Example
Get Central European Time.
Zone.parse "CET"
@ -40,27 +55,41 @@ parse : Text -> Zone
parse text = Zone (ZoneId.of text)
## The system default timezone.
> Example
Get the system default timezone.
Zone.system
system : Zone
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 = here.system
## UTC time zone.
## The UTC timezone.
> Example
Get the UTC timezone.
Zone.utc
utc : Zone
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
- the timezone offset in minutes, from 0 to ±59, sign matches hours and
seconds
- the timezone offset in seconds, from 0 to ±59, sign matches hours and
minutes
Arguments:
- hours: The timezone offset in hours from UTC, from -18 to +18.
- minutes: The timezone offset in minutes from the nearest hour, from 0 to
±59. The sign must match that of the hours argument.
- seconds: The timezone offset in seconds from the nearest minute, from 0 to
±59. The sign must match that of the minutes argument.
> 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
new : Integer -> Integer -> Integer -> Zone
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
the provided constructor function.
The constructor function is called with the consecutive indices
(0-based) of the vector elements.
Arguments:
- 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
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
the provided constant.
Arguments:
- length: The length of the vector (>= 0).
- constructor: A value fo be placed into each element of the vector.
> Example
A vector containing 50 elements, each being the number `42`, can be
created by:
@ -58,8 +64,12 @@ fill length ~item =
new_builder : Builder
new_builder = Builder.new
## Converts a polyglot value representing an array into a vector. This is
useful when wrapping polyglot APIs for further use in Enso.
## Converts a polyglot value representing an array into a vector.
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 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).
Arguments:
- index: The location in the vector to get the element from.
> Example
To get the second element of the vector `[1, 2, 3]`, use:
[1, 2, 3].at 1
@ -98,6 +111,10 @@ type Vector
## Combines all the elements of the vector, by iteratively applying the
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
[l0, l1, ..., ln] . fold init f
is the same as
@ -108,12 +125,16 @@ type Vector
vector:
[0, 1, 2] . fold 0 (+)
fold : Any -> (Any -> Any -> Any) -> Any
fold initial function =
fold init function =
arr = this.to_array
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.
Arguments:
- function: A binary operation that takes two items and combines them.
If the vector is empty, it throws Nothing.
> Example
@ -128,8 +149,10 @@ type 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
Checking if any element of the list is larger than 3.
@ -142,10 +165,12 @@ type Vector
go 0 False
## 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
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
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.
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
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.
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
Check if all elements in the vector are less than zero.
[-1, 1, 5, 8].all (< 0)
@ -181,6 +214,9 @@ type Vector
## Checks whether this vector contains a given value as an element.
Arguments:
- elem: The item to see if it exists in the vector.
> Example
Checking if the vector contains the number 72.
[1, 383, 72, 301].contains 72
@ -207,8 +243,10 @@ type Vector
## Selects all elements of this vector which satisfy a predicate.
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
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
results.
Arguments:
- function: A function that takes an element in the vector and returns
some transformation of that element.
> Example
In the following example, we add `1` to each element of the vector:
[1, 2, 3] . map +1
@ -233,12 +275,14 @@ type Vector
## Applies a function to each element of the vector, returning the vector
that contains all results concatenated.
Arguments:
- function: A function that takes an element in the vector, transforms
it, and returns a vector.
> Example
In the following example, we replace each number `n` with itself
repeated `n` times:
[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 function =
mapped = this.map function
@ -252,13 +296,24 @@ type Vector
## Applies a function to each element of the vector, returning the vector
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
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)
## 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,
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
the opposite order.
> Example
Reversing a two-element vector.
[1, 2].reverse
reverse : Vector
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
"[" + (this.at 0 . to_text) + tail_elems + "]"
## Checks whether this vector is equal to `that`. Two vectors are considered
equal, when they have the same length and their items are pairwise equal.
## Checks whether this vector is equal to `that`.
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
Comparing two vectors for equality (this case is false).
[1, 2, 3] == [2, 3, 4
[1, 2, 3] == [2, 3, 4]
== : Vector -> Boolean
== that =
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
elements of `this`, followed by all the elements of `that`.
Arguments:
- that: The vector to concatenate to the end of `this`.
> Example
Concatenating two single-element vectors.
[1] + [2] == [1, 2]
@ -323,7 +390,7 @@ type Vector
> Example
Add one element in front:
[2, 3].prepend 1 == [1, 2, 3]
[2, 3].prepend 1 == [1, 2, 3]
prepend : Any -> Vector
prepend element = [element] + this
@ -334,13 +401,16 @@ type Vector
> Example
Add one element to the end:
[1, 2].append 3 == [1, 2, 3]
[1, 2].append 3 == [1, 2, 3]
append : Any -> Vector
append element = this + [element]
## When `this` is a vector of text values, concatenates all the values by
interspersing them with `separator`.
Arguments:
- separator: The text to use to join the textual elements of the vector.
> Example
The following code returns "foo, bar, baz"
["foo", "bar", "baz"].join ", "
@ -352,6 +422,9 @@ type Vector
## 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
The following code returns [2, 3, 4, 5]
[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.
Arguments:
- count: The number of elements to drop from the end of `this`.
> Example
The following code returns [1, 2, 3]
[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
left of `this`.
Arguments:
- count: The number of elements to take from the start of `this`.
> Example
The following code returns [1, 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
right of `this`.
Arguments:
- count: The number of elements to take from the end of `this`.
> Example
The following code returns [3, 4, 5]
[1, 2, 3, 4, 5].take_end 3
@ -390,12 +472,20 @@ type Vector
## Performs a pair-wise operation passed in `function` on consecutive
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
`this` and `that`, containing results of calling `function`.
> Example
To pairwise-sum two vectors:
[1, 2, 3].zip [4, 5, 6] (+) == [5, 7, 9]
> Example
When the `function` is not provided, it defaults to creating a pair
of both elements:
[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)
## 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`
vector is returned.
the end.
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
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
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 n elem =
if this.length >= n then this else
this + (here.fill n-this.length elem)
## 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 (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
The following code returns 1.
[1, 2, 3, 4].head
> Example
Empty vectors return `Nothing`.
[].head == Nothing
head : Any ! Nothing
head = if this.length >= 1 then this.at 0 else Error.throw Nothing
@ -439,10 +538,6 @@ type Vector
> Example
The following code returns [2, 3, 4].
[1, 2, 3, 4].tail
> Example
Empty vectors return `Nothing`.
[].tail == Nothing
tail : Vector ! Nothing
tail = if this.length >= 1 then this.drop_start 1 else Error.throw Nothing
@ -451,38 +546,30 @@ type Vector
> Example
The following code returns [1, 2, 3].
[1, 2, 3, 4].init
> Example
Empty vectors return `Nothing`.
[].init == Nothing
init : Vector ! 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
The following code returns 4.
[1, 2, 3, 4].last
> Example
Empty vectors return `Nothing`.
[].last == Nothing
last : Vector ! 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
The following code returns 1.
[1, 2, 3, 4].first
> Example
Empty vectors return `Nothing`.
[].first == Nothing
first : Vector ! Nothing
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.
> Example
@ -506,11 +593,11 @@ type Vector
## Sort the Vector.
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.
- `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.
- `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
`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
have their order changed by the sorting process.
The complexities for this sort are:
- *Worst-Case Time:* `O(n * log n)`
- *Best-Case Time:* `O(n)`
- *Average Time:* `O(n * log n)`
- *Worst-Case Space:* `O(n)` additional
! Computational Complexity
The complexities for this sort are:
- *Worst-Case Time:* `O(n * log n)`
- *Best-Case Time:* `O(n)`
- *Average Time:* `O(n * log n)`
- *Worst-Case Space:* `O(n)` additional
? Implementation Note
The sort implementation is based upon an adaptive, iterative mergesort
@ -560,46 +648,69 @@ type Vector
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.
to_default_visualization_data : Text
to_default_visualization_data =
json = this.take_start 100 . to_json
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
## 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
## Creates a new builder.
> Example
Make a new builder
Vector.new_builder
new : Builder
new = Builder (Array.new 1) 0
## Returns the current capacity (i.e. the size of the underlying storage)
of this builder.
> Example
Get the capacity of a new builder.
Vector.new_builder.capacity
capacity : Integer
capacity = this.to_array.length
## 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 item = case this.capacity > this.length of
True ->
@ -616,6 +727,14 @@ type Builder
Nothing
## 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 =
old_array = this.to_array
@ -624,3 +743,19 @@ type Builder
new_array.set_at i (old_array.at i)
Nothing
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
## 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 =
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
## 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
implemented yet.
Arguments:
- message: A description of what implementation is missing.
unimplemented : Text -> Void
unimplemented message="" = Panic.throw (Unimplemented_Error message)
## Executes the provided handler on a dataflow error, or executes as identity on
a non-error value.
## Executes the provided handler on a dataflow error, or returns a non-error
value unchanged.
Arguments:
- handler: The function to call on this if it is an error value. By default
this is identity.
> Example
Catching an erroneous value to perform some operation on it.
(Time.Time_Error "Message").catch (err -> IO.println err)
Catching an erroneous value and getting the length of its message.
(Time.Time_Error "Message").catch (err -> err.error_message.length)
Error.catch : (Error -> Any) -> Any
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
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 = 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 = "Error: " + (this.catch .to_display_text)
## Maps a dataflow 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.
## Transforms an error.
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
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 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 = True
## Takes any value, and if it is a dataflow error, throws it as a Panic.
Otherwise, returns the original value unchanged.
## Takes any value, and if it is a dataflow error, throws it as a Panic,
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 value = value.catch Panic.throw

View File

@ -18,9 +18,35 @@ e : Decimal
e = 2.718281828459045235360
## 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 a b = if a <= b then a else 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 a b = if a < b then b else a

View File

@ -2,91 +2,80 @@ from Standard.Base import all
import Builtins
## Represents a polyglot language.
type Language
## The Java laguage.
type Java
## Unknown language.
type Unknown
## UNSTABLE
ADVANCED
## A meta-representation of a runtime value.
Returns a meta-representation of a given runtime entity.
! 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
## An Atom meta-representation.
type Atom value
## A constructor meta-representation.
type Constructor 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
Arguments:
- value: The runtime entity to get the meta representation of.
meta : Any -> Meta
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
## 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
Checks whether two objects are represented by the same underlying reference.
## Returns a new unresolved symbol with its name changed to the provided
argument.
Unresolved_Symbol.rename : Text -> Any
Unresolved_Symbol.rename new_name =
Builtins.Meta.create_unresolved_symbol new_name this.scope
Arguments:
- value_1: The first value.
- value_2: The second value.
is_same_object : Any -> Any -> Boolean
is_same_object value_1 value_2 = Builtins.Meta.is_same_object value_1 value_2
## 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
Checks if `this` is an instance of `typ`.
## 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)
## 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`.
Arguments:
- typ: The type to check `this` against.
Any.is_a : Any -> Boolean
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 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 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 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 value typ = if typ == Any then True 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
_ -> 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 value typ = here.is_a value typ
## Returns a meta-representation of a given runtime entity.
meta : Any -> Meta
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
## Represents a polyglot language.
type Language
## Checks whether two objects are represented by the same underlying reference.
This is a power-user feature, that is only useful for certain optimizations.
is_same_object : Any -> Any -> Boolean
is_same_object value_1 value_2 = Builtins.Meta.is_same_object value_1 value_2
## UNSTABLE
ADVANCED
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

View File

@ -3,9 +3,17 @@ from Standard.Base import all
import Builtins
## 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 this.prim_root_file
## 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 = 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 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
## UNSTABLE
Convert a request error to a human-readable form.
Request_Error.to_display_text =
"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
## 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
## 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.new.options "http://httpbin.org"
@ -46,6 +208,10 @@ type Http
## 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.new.get "http://httpbin.org/get"
@ -66,6 +232,10 @@ type Http
## 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.new.head "http://httpbin.org"
@ -77,6 +247,11 @@ type Http
## 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
Send a Post request with binary data.
body = Body.Bytes "Hello".utf_8
@ -91,6 +266,11 @@ type Http
"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 the 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")]
@ -114,6 +294,11 @@ type Http
## 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
Send a Post request with json data.
json = Json.parse <| '''
@ -127,6 +312,11 @@ type Http
## 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
Send a Put request with binary data.
body = Body.Bytes "contents".utf_8
@ -139,6 +329,11 @@ type Http
## 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
Send a Put request with json data.
json = Json.parse <| '''
@ -152,6 +347,10 @@ type Http
## Create a Delete request.
Arguments:
- uri: The address to which the request will be sent.
- headers: Any headers for the options request.
> Example
Send a Delete request.
Http.new.delete "http://httpbin.org/delete"
@ -162,6 +361,9 @@ type Http
## Create a request
Arguments:
- req: The HTTP request to send using `this` HTTP client.
> Example
Send a Get request with headers.
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
# build http client
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.
type Form
## PRIVATE
A type representing form data.
Arguments:
- parts: A vector of form segments.
type Form parts
## Convert this to a Form.
> Example
Convert to a form.
Form.new [Part "foo" (Part_Text "bar")] . to_form
to_form : Form
to_form = this
@ -17,25 +27,62 @@ Vector.Vector.to_form = Form this
## The key-value element of the form.
type Part
## A form part.
Arguments:
- key: The key for the form section.
- value: The value of the form section.
type Part key value
## The value of the form element.
type Part_Value
## A textual value for a form part.
Arguments:
- part_text: The text for the form part.
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
## 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 parts = Form parts
# Helpers for creating different parts of the 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 key val = Part key (Part_Text val)
## 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 key file = Part key (Part_File file)

View File

@ -4,34 +4,78 @@ polyglot java import org.enso.base.Http_Utils
type Header
## PRIVATE
A type representing a header.
Arguments:
- name: The header name.
- value: The header value.
type Header name value
## 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
== that = (this.name.equals_ignore_case that.name) && this.value==that.value
## 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 name value = Header name value
# 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 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 = here.accept "*/*"
# Authorization
## 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 value = Header "Authorization" value
## Create HTTP basic auth header.
Arguments:
- user: The username.
- pass: The password.
> Example
Create basic auth header.
Header.authorization_basic "user" "pass"
@ -42,27 +86,57 @@ authorization_basic user pass =
# Content-Type
## 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 value = Header "Content-Type" value
## Header "Content-Type: application/json".
> Example
Create a header with content type "application/json".
Header.application_json
application_json : Header
application_json = here.content_type "application/json"
## 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 = here.content_type "application/octet-stream"
## 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 = here.content_type "application/x-www-form-urlencoded"
## 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 (boundary = "") =
if boundary == "" then here.content_type "multipart/form-data" else
here.content_type ("multipart/form-data; boundary=" + boundary)
## Header "Content-Type: text/plain".
> Example
Create a header with the content type "text/plain".
Header.text_plain
text_plain : Header
text_plain = here.content_type "text/plain"

View File

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

View File

@ -10,11 +10,115 @@ import Standard.Base.System.File
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
## 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
## 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 key val =
new_header = Header.new key val
@ -27,54 +131,54 @@ type Request
Pair acc False -> acc + [new_header]
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 new_headers =
update_header req new_header = req.with_header new_header.name new_header.value
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 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 json_body =
new_body = Request_Body.Json json_body
Request this.method this.uri this.headers new_body . with_headers [Header.application_json]
## Set body as vector of parts encoded as
"application/x-www-form-urlencoded".
## Set body as vector of parts encoded as "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 parts =
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]
## 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
## Request body with text.
Arguments:
- text: The plain text in the request body.
type Text text
## Request body with JSON.
Arguments:
- json: The JSON in the request body.
type Json json
## Request body with form data.
Arguments:
- form: The form data in the request body.
type Form form
## Request body with file data.
Arguments:
- file: The file data in the request body.
type File file
## Request body with binary.
Arguments:
- bytes: The binary data in the request body.
type Bytes bytes

View File

@ -9,6 +9,13 @@ polyglot java import org.enso.base.Http_Utils
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
## Get the response headers.
@ -25,6 +32,6 @@ type Response
code : Status_Code
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.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
## Response body
Arguments:
- bytes: The body of the response as binary data.
type Body bytes
## Convert response body to Text.
@ -17,7 +20,10 @@ type Body
to_json = Json.parse this.to_text
## Write response body to a File.
Arguments:
- file: The file to write the bytes to.
to_file : File -> File
to_file path =
path.write_bytes this.bytes
path
to_file file =
file.write_bytes this.bytes
file

View File

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

View File

@ -1,8 +1,17 @@
from Standard.Base import all
## 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 =
action . catch Panic.throw
## PRIVATE
Recovers from a panic.
recover_panic : Any -> Error
recover_panic error = Error.throw error

View File

@ -3,15 +3,23 @@ from Standard.Base import all
## Proxy settings.
type Proxy
## Proxy is disabled.
## The proxy is disabled.
type None
## Use a sysem proxy settings.
## Use the system proxy settings.
type System
## Use provided proxy.
## Use the provided proxy server.
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 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
## Syntax error when parsing a Uri.
Arguments:
- message: The error message for the URI syntax error.
type Syntax_Error message
## Converts the URI syntax error to a human-readable form.
Syntax_Error.to_display_text =
"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
type Uri
## Represents a Uniform Resource Identifier (URI) reference.
Arguments:
- internal_uri: The internal representation of the URI.
type Uri internal_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 = this
## Get scheme part of this Uri.
## Get the scheme part of this Uri.
> Example
Return the "http" part of the HTTP address.
@ -31,7 +66,7 @@ type Uri
scheme : Text ! Nothing
scheme = Internal.handle_nothing this.internal_uri.getScheme
## Get user info part of this Uri.
## Get the user info part of this Uri.
> Example
Return the "user:pass" part of the HTTP address.
@ -40,7 +75,7 @@ type Uri
user_info : Text ! Nothing
user_info = Internal.handle_nothing this.internal_uri.getUserInfo
## Get host part of this Uri.
## Get the host part of this Uri.
> Example
Return the "example.com" part of the HTTP address.
@ -49,7 +84,7 @@ type Uri
host : Text ! Nothing
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
Return the "user:pass@example.com" part of the HTTP address.
@ -58,7 +93,7 @@ type Uri
authority : Text ! Nothing
authority = Internal.handle_nothing this.internal_uri.getAuthority
## Get port part of this Uri.
## Get the port part of this Uri.
> Example
Return the "80" part of the HTTP address.
@ -75,7 +110,7 @@ type Uri
Internal.handle_nothing <|
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
Return the "/foo/bar" part of the HTTP address.
@ -84,7 +119,7 @@ type Uri
path : Text ! Nothing
path = Internal.handle_nothing this.internal_uri.getPath
## Get query part of this Uri.
## Get the query part of this Uri.
> Example
Return the "key=val" part of the HTTP address.
@ -93,7 +128,7 @@ type Uri
query : Text ! Nothing
query = Internal.handle_nothing this.internal_uri.getQuery
## Get fragment part of this Uri.
## Get the fragment part of this Uri.
> Example
Return the empty fragment of the HTTP address.
@ -102,46 +137,57 @@ type Uri
fragment : Text ! Nothing
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 = 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 = 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 = 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 = 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 = Internal.handle_nothing this.internal_uri.getRawFragment
## Convert this Uri to text.
> Example
Convert a URI to text.
Uri.new "https://example.com" . to_text
to_text : Text
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 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
== 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
## PRIVATE
Handle a nothing value.
Arguments:
- value: The value that may possibly be nothing.
handle_nothing : Any -> Any ! Nothing
handle_nothing value = case value of
Nothing -> Error.throw Nothing

View File

@ -2,7 +2,13 @@ from Standard.Base import all
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 object 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
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 key =
System.getenv key

View File

@ -10,121 +10,102 @@ polyglot java import java.nio.file.AccessDeniedException
polyglot java import java.nio.file.NoSuchFileException
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
## 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
## A generic IO error.
Arguments:
- message: The message for the error.
type Io_Error message
## PRIVATE
## UNSTABLE
Utility method for rewrapping Java exceptions into Enso panics.
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
Convert the File error to a human-readable format.
to_display_text : Text
to_display_text = case this of
No_Such_File_Error file -> "The file at " + file.path + " does not exist."
Access_Denied_Error file -> "You do not have permission to access the file at " + file.path + "."
Io_Error msg -> "An IO error has occurred: " + msg.to_text + "."
## PRIVATE
## Creates a new file object, pointing to the given path.
Utility method for running an action with Java exceptions mapping.
handle_java_exceptions file ~action =
err = Panic.recover action
r = err.catch (here.rethrow_java file)
r
Arguments:
- path: The path to the file that you want to create.
## 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
accidental scope capture with `Managed_Resource` finalizers.
close_stream : Any -> Nothing
close_stream stream =
stream.close
Nothing
## Open and read the file at the provided `path`.
## An output stream, allowing for interactive writing of contents into an
open file.
type Output_Stream
type Output_Stream file stream_resource
Arguments:
- path: The path of the file to open and read the contents of. It will
accept a textual path or a file.
## Writes a vector of bytes into the file at the current stream position.
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
? Module or Instance?
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 still work.
## 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
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
## Returns the current working directory (CWD) of the current program.
## An input stream, allowing for interactive reading of contents from an open
file.
type Input_Stream
type Input_Stream file stream_resource
> Example
Get the program's current working directory.
File.current_directory
current_directory : File
current_directory = File (Prim_Io.get_cwd)
## 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
## Returns the home directory of the current user.
## Reads _up to_ the provided number of bytes from the stream.
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
## 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
> Example
Get the current user's home directory.
File.home
home : File
home = here.new (Prim_Io.get_user_home)
type File
## PRIVATE
A type representing a file.
Arguments:
- prim_file: The internal representation of the 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 `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 open_options =
opts = open_options . map (_.to_java) . to_array
@ -133,13 +114,16 @@ type File
resource = Managed_Resource.register stream here.close_stream
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 `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 open_options =
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
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
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 open_options 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
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
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 open_options action =
Resource.bracket (this.new_input_stream open_options) (_.close) action
@ -185,16 +175,25 @@ type File
Text.from_utf_8 bytes
## 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 contents =
opts = [Option.Append, Option.Create]
this.with_output_stream opts (_.write_bytes contents)
## 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 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.
write_bytes : Vector.Vector -> Nothing ! File_Error
@ -203,14 +202,20 @@ type File
this.with_output_stream opts (_.write_bytes contents)
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.
Arguments:
- contents: The UTF-8 encoded text to write to the file.
If the file does not exist, it will be created.
write : Text -> Nothing ! File_Error
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
/ subpath = case subpath of
File prim -> File (this.prim_file.resolve prim)
@ -239,6 +244,11 @@ type File
create_directory = this.prim_file.createDirectories
## 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 = this.prim_file.isRegularFile
@ -288,38 +298,150 @@ type File
delete_if_exists : Nothing ! File_Error
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
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)
## ADVANCED
## 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:
- `path`: The path of the file to open and read the contents of. It will
accept a textual path or a file.
- file: The file object.
- 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?
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.
## PRIVATE
> 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
Utility method for running an action with Java exceptions mapping.
handle_java_exceptions file ~action =
err = Panic.recover action
r = err.catch (here.rethrow_java file)
r
## Returns the current working directory (CWD) of the current program.
current_directory : File
current_directory = File (Prim_Io.get_cwd)
## PRIVATE
## Returns the home directory of the current user.
home : File
home = here.new (Prim_Io.get_user_home)
Utility method for closing primitive Java streams. Provided to avoid
accidental scope capture with `Managed_Resource` finalizers.
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
the `File` type should be preferred.
type Option
## If the file is opened for `Write` access then bytes will be written to
the end of the file rather than the beginning.
type Append
## Create a new file if it does not exist.
type Create
## Create a new file, failing if the file already exists.
type Create_New
## Delete the underlying file on closing the stream.
type Delete_On_Close
## Requires that every update to the file's content be written
synchronously to the underlying storage device.
type Dsync
## Open for read access.
type Read
## Sparse file.
type Sparse
## Requires that every update to the file's content or metadata be written
synchronously to the underlying storage device.
type Sync
## If the file already exists and is opened for `Write` access,
the original contents will be removed.
type Truncate_Existing
## Open file for write access.
type Write
## PRIVATE
Convert this object into a representation understandable by the JVM.
to_java : StandardOpenOption
to_java = case this of
Append -> StandardOpenOption.APPEND
Create -> StandardOpenOption.CREATE

View File

@ -2,19 +2,20 @@ from Standard.Base import all
from Builtins import System
## A representation of the various operating systems on which Enso can run.
type Os
type Linux
type MacOS
type Windows
type Unknown
## 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
## The Linux operating system.
type Linux
## The macOS operating system.
type MacOS
## The Windows operating system.
type Windows
## An unknown operating system.
type Unknown
## Return the type of operating system.
@ -23,3 +24,12 @@ from_text os =
Platform.os
os : 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 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
The builder object that is used to create operating system processes.
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=""
## UNSTABLE
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 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
process.
Arguments:
- stdin: The standard input contents to pass to the process.
set_stdin : Text -> Builder
set_stdin stdin = Builder this.command this.arguments stdin
@ -40,18 +74,10 @@ type Builder
## UNSTABLE
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
## 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.
type Exit_Code
## The process exited with a success.
type Exit_Success
## The process exited with a failure.
Arguments:
- code: The exit code for the failure.
type Exit_Failure code
## 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
Exit_Success -> 0
Exit_Failure code -> code
## Create exit code from a number.
Arguments:
- code: The exit code you want to create.
> Example
Create failure exit code:
Create a failure exit code.
Exit_Code.from_number 1
Result in:
Exit_Failure 1
from_number : Number -> Exit_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.
Allows to access tables from a database.
Arguments:
- java_connection: the resource managing the underlying JDBC connection.
- dialect: the dialect associated with the database we are connected to.
Allows accessing tables from a database.
type Connection connection_resource dialect
## UNSTABLE
@ -106,6 +106,11 @@ type Connection
_ -> Error.throw err
## 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 query =
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
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 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
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 =
initial_size = 10
@ -158,16 +169,37 @@ create_builder sql_type =
Builder_Inferred (Java_Exports.make_inferred_builder initial_size)
type Builder
## PRIVATE
A builder that has an inferred column type at runtime.
Arguments:
- java_builder: The underlying builder object.
type Builder_Inferred java_builder
## PRIVATE
A builder that has an inferred column type at runtime.
Arguments:
- java_builder: The underlying builder object.
type Builder_Double java_builder
## PRIVATE
A builder that has an inferred column type at runtime.
Arguments:
- java_builder: The underlying builder object.
type Builder_Long java_builder
## PRIVATE
A builder that has an inferred column type at runtime.
Arguments:
- java_builder: The underlying builder object.
type Builder_Boolean java_builder
## PRIVATE
@ -202,6 +234,9 @@ type Builder
## PRIVATE
Seals the builder and returns a built Java-column.
Argument:
- name: The name of the column.
make_column : Text -> Java_Exports.Column
make_column name =
storage = this.java_builder.seal
@ -209,12 +244,24 @@ type Builder
## An error indicating that a supported dialect could not be deduced for the
provided URL.
Argument:
- url: The URL for which the dialect could not be deduced.
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
Creates a JDBC connection based on a URL and optionally username and
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 url properties = here.wrap_sql_errors <|
java_props = Properties.new
@ -228,37 +275,55 @@ create_jdbc_connection url properties = here.wrap_sql_errors <|
## PRIVATE
This cannot be a closure due to limitations of Managed_Resource.
Arguments:
- connection: The connection to close.
close_connection : Connection -> Nothing
close_connection connection =
connection.close
type Sql_Error
## UNSTABLE
Indicates an error with executing a query, update or connecting to the
database.
Wraps an SQLException from the Java drvier.
Arguments:
- java_exception: The underlying exception.
type Sql_Error java_exception
## UNSTABLE
Convert the SQL error to a textual representation.
to_text : Text
to_text = this.java_exception.getMessage
to_text = "There was an SQL error: " + this.java_exception.getMessage.to_text + "."
## UNSTABLE
Pretty print the SQL error.
to_display_text : Text
to_display_text = this.to_text
type Sql_Timeout_Error
## UNSTABLE
Indicates that an operation has timed out.
Arguments:
- java_exception: The underlying exception.
type Sql_Timeout_Error java_exception
## UNSTABLE
Convert the timeout error to a textual representation.
to_text : Text
to_text = this.java_exception.getMessage
to_text = "The SQL connection timed out: " + this.java_exception.getMessage + "."
## UNSTABLE
Pretty print the timeout error.
to_display_text : 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
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 =
result = Panic.recover action
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.
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:
- url: the URL to connect to.
- user: (optional) an username for authentication.
- password: (optional) a password for authentication.
- custom_properties: (optional) a vector of key-value Text pairs which can
- url: The URL to connect to.
- user: A username for authentication. Optional.
- password: A password for authentication. Optional.
- custom_properties: A vector of key-value Text pairs which can
set any other properties that can be used to configure the connection or
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 url user=Nothing password=Nothing custom_properties=[] =
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.
It is an alternative to `connect` that resolves a path to the database file.
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 =
url = "sqlite:" + file.absolute.path

View File

@ -15,6 +15,12 @@ type Column
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
other columns with operators. Expressions created in this way may be
materialized or used to apply filters, groupings etc. to tables from
@ -43,6 +49,7 @@ type Column
Arguments:
- show_rows: the number of initial rows that should be displayed.
print : Nothing
print show_rows=10 =
IO.println (this.display show_rows format_terminal=True)
IO.println ''
@ -93,6 +100,14 @@ type Column
## PRIVATE
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.
`operand_type` is only relevant if the operand is not a column, it
defaults to the current type if not provided.
@ -116,6 +131,11 @@ type Column
## PRIVATE
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 op_kind new_type=Nothing =
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"
## PRIVATE
Computes an aggregate operator.
Arguments:
- op_name: The name of the operator to compute.
compute_aggregate : Text
compute_aggregate op_name =
agg = here.make_aggregate this op_name
agg.to_vector . at 0
@ -171,109 +197,159 @@ type Column
## UNSTABLE
Element-wise equality comparison. 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`.
Element-wise equality comparison.
Arguments:
- 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
== other = this.make_binary_op "=" other new_type=Sql_Type.boolean
## UNSTABLE
Element-wise non-equality comparison. 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`.
Element-wise non-equality comparison.
Arguments:
- 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
!= other = this.make_binary_op "!=" other new_type=Sql_Type.boolean
## UNSTABLE
Element-wise order comparison. 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`.
Element-wise order comparison.
Arguments:
- 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
>= other = this.make_binary_op ">=" other new_type=Sql_Type.boolean
## UNSTABLE
Element-wise order comparison. 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`.
Element-wise order comparison.
Arguments:
- 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
<= other = this.make_binary_op "<=" other new_type=Sql_Type.boolean
## UNSTABLE
Element-wise order comparison. 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`.
Element-wise order comparison.
Arguments:
- 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
> other = this.make_binary_op ">" other new_type=Sql_Type.boolean
## UNSTABLE
Element-wise order comparison. 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`.
Element-wise order comparison.
Arguments:
- 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
< other = this.make_binary_op "<" other new_type=Sql_Type.boolean
## UNSTABLE
Element-wise addition. 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`.
Element-wise addition.
Arguments:
- 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
+ other = this.make_binary_op "+" other
## UNSTABLE
Element-wise subtraction. 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`.
Element-wise subtraction.
Arguments:
- 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
- other = this.make_binary_op "-" other
## UNSTABLE
Element-wise multiplication. 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`.
Element-wise multiplication.
Arguments:
- 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
* other = this.make_binary_op "*" other
## UNSTABLE
Element-wise division. 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`.
Element-wise division.
Arguments:
- 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
/ other = this.make_binary_op "/" other
## UNSTABLE
Element-wise boolean conjunction. 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`.
Element-wise boolean conjunction.
Arguments:
- 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
&& other = this.make_binary_op "AND" other
## UNSTABLE
Element-wise boolean disjunction. 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`.
Element-wise boolean disjunction.
Arguments:
- 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
|| other = this.make_binary_op "OR" other
@ -300,8 +376,13 @@ type Column
## UNSTABLE
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.
> Example
Select only the rows of `my_column` where the `status_column` column
has the value `"Valid"`
@ -325,6 +406,9 @@ type Column
## UNSTABLE
Returns the same column with changed name.
Arguments:
- new_name: The name to rename `this` column to.
rename : Text -> Column
rename new_name = case Helpers.ensure_name_is_sane new_name of
True ->
@ -339,8 +423,8 @@ type Column
Sorts the column according to the specified rules.
Arguments:
- order: specifies the default sort order for this operation.
- missing_last: specifies the default placement of missing values when
- order: Specifies the default sort order for this operation.
- missing_last: Specifies the default placement of missing values when
compared to non-missing ones. Note thet this argument is independent
from `order`, i.e. missing values will always be sorted according to
this rule, ignoring the ascending / descending setting.
@ -360,33 +444,42 @@ type Column
## UNSTABLE
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
values), the behaviour on these missing values is vendor specific.
Arguments:
- 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 other = this.make_binary_op "starts_with" other new_type=Sql_Type.boolean
## UNSTABLE
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
values), the behaviour on these missing values is vendor specific.
Arguments:
- 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 other = this.make_binary_op "ends_with" other new_type=Sql_Type.boolean
## UNSTABLE
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
values), the behaviour on these missing values is vendor specific.
Arguments:
- 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 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
type Aggregate_Column
## UNSTABLE
Wraps a column grouped by its index. 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)
Wraps a column grouped by its index.
Arguments:
- name: The name of the column.
- 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
## UNSTABLE
@ -409,8 +511,8 @@ type Aggregate_Column
Sums the values in each group.
Arguments:
- name_suffix: a suffix that will be appended to the original column
name to generate the resulting column name.
- name_suffix: a suffix that will be appended to the original column name
to generate the resulting column name.
sum : Text -> Column
sum name_suffix='_sum' =
here.make_aggregate this "SUM" name_suffix
@ -420,8 +522,8 @@ type Aggregate_Column
Computes the maximum element of each group.
Arguments:
- name_suffix: a suffix that will be appended to the original column
name to generate the resulting column name.
- name_suffix: a suffix that will be appended to the original column name
to generate the resulting column name.
max : Text -> Column
max name_suffix='_max' =
here.make_aggregate this "MAX" name_suffix
@ -431,8 +533,8 @@ type Aggregate_Column
Computes the minimum element of each group.
Arguments:
- name_suffix: a suffix that will be appended to the original column
name to generate the resulting column name.
- name_suffix: a suffix that will be appended to the original column name
to generate the resulting column name.
min : Text -> Column
min name_suffix='_min' =
here.make_aggregate this "MIN" name_suffix
@ -442,8 +544,8 @@ type Aggregate_Column
Computes the number of non-missing elements in each group.
Arguments:
- name_suffix: a suffix that will be appended to the original column
name to generate the resulting column name.
- name_suffix: a suffix that will be appended to the original column name
to generate the resulting column name.
count : Text -> Column
count name_suffix='_count' =
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.
Arguments:
- name_suffix: a suffix that will be appended to the original column
name to generate the resulting column name.
- name_suffix: a suffix that will be appended to the original column name
to generate the resulting column name.
mean : Text -> Column
mean name_suffix='_mean' =
here.make_aggregate this "AVG" name_suffix
## PRIVATE
Helper that returns the underlying column from before grouping.
A helper that returns the underlying column from before grouping.
ungrouped : Column
ungrouped =
new_ctx = this.context.set_groups []
@ -471,6 +573,13 @@ type Aggregate_Column
A helper method for creating an aggregated column by applying some
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 =
actual_new_type = if new_type.is_nothing then column.sql_type else new_type
expr = IR.Operation operation [column.expression]

View File

@ -15,14 +15,14 @@ type Dialect
Represents a specific SQL dialect.
It encapsulates dialect-specific code generation details allowing us to
support differing SQL dialects.
Arguments:
- name: name of the dialect.
- generate_sql: a function which generates SQL code from the internal
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
## PRIVATE
@ -98,5 +98,7 @@ sqlite =
Dialect "sqlite" (query -> Base_Generator.generate_query dialect query . build)
## PRIVATE
A vector of SQL dialects supported by the Database library.
supported_dialects : Vector Dialect
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
type Internal_Dialect
## PRIVATE
An internal representation of a SQL dialect.
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
builders for the arguments and should return a builder yielding the
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
usually consists of wrapping the name in quotes and escaping any quotes
within it.
# type Internal_Dialect (operation_map : Map Text (Vector Sql.Builder -> Sql.Builder))
# (identifier_wrapper : Text -> Sql.Builder)
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
overrides existing ones.
# extend_with : Vector [Text, Vector Sql.Builder -> Sql.Builder] -> Internal_Dialect
extend_with : Vector -> Internal_Dialect
extend_with mappings =
new_map = mappings.fold this.operation_map (m -> el -> m.insert (el.at 0) (el.at 1))
Internal_Dialect new_map this.wrap_identifier
@ -35,6 +39,9 @@ type Internal_Dialect
## PRIVATE
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 name =
arguments ->
@ -48,6 +55,9 @@ make_binary_op name =
## PRIVATE
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 name =
arguments ->
@ -61,6 +71,9 @@ make_unary_op name =
A helper function to create a unary operator which is added to the right of
the expression.
Arguments:
- name: The name of the unary operator.
make_right_unary_op : Text -> Vector Sql.Builder -> Sql.Builder
make_right_unary_op name =
arguments ->
@ -73,6 +86,9 @@ make_right_unary_op name =
## PRIVATE
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 name =
arguments ->
@ -81,6 +97,9 @@ make_function name =
## PRIVATE
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 code =
arguments ->
@ -90,8 +109,13 @@ make_constant code =
## PRIVATE
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
should work across most dialects.
with double-quote.
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 identifier =
escaped = identifier.replace '"' '""'
@ -118,6 +142,10 @@ base_dialect =
## PRIVATE
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 dialect expr = case expr of
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
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 dialect name =
wrapped = dialect.wrap_identifier name
@ -141,6 +173,10 @@ alias dialect name =
## PRIVATE
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 dialect from_spec = case from_spec of
IR.From_Table name as_name ->
@ -162,7 +198,13 @@ generate_from_part dialect from_spec = case from_spec of
## PRIVATE
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 -> Vector -> Sql.Builder
generate_order dialect order_description =
order_suffix = case order_description.second of
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
## 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 dialect ctx =
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
## 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 =
names = Sql.join ", " <| pairs.map (.first >> dialect.wrap_identifier)
values = Sql.join ", " <| pairs.map (.second >> here.generate_expression dialect)
@ -198,6 +255,10 @@ generate_insert_query dialect table_name pairs =
## PRIVATE
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 dialect query = case query of
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
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
the combination would be ill-formed.
check_integrity : (Table | Column) -> (Table | Column) -> Boolean
@ -20,9 +24,13 @@ check_integrity entity1 entity2 =
## PRIVATE
A helper function simplifying argument handling. 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.
A helper function simplifying argument handling.
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 x = case x of
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.
Arguments:
- text: The name that is not supported.
Currently the names can only include ASCII letters, numbers and the
underscore. This is a temporary limitation simplifying name handling. It will
be removed in a future version.
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
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
external names shown to the user, but as a temporary solution we only allow
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
expressions.
type Expression
## PRIVATE
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`.
- name: the name of the column directly in the table or its alias in a
sub-query.
# type Column (origin : Text) (name : Text)
# type Column (origin : Text) (name : Text)
type Column origin name
## PRIVATE
@ -50,9 +51,19 @@ type Internal_Column
## PRIVATE
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
## PRIVATE
Rename the internal column.
Arguments:
- new_name: The new name for the column.
rename : Text -> Internal_Column
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.
- limit: an optional maximum number of elements that the equery should
return.
# type Context (from_spec : From_Spec) (where_filters : Vector Expression)
# (orders : Vector [Expression, Order_Direction, Nulls_Order])
# (groups : Vector Expression) (meta_index : Vector Internal_Column)
# (limit : Nothing | Integer)
# type Context (from_spec : From_Spec) (where_filters : Vector Expression)
# (orders : Vector [Expression, Order_Direction, Nulls_Order])
# (groups : Vector Expression) (meta_index : Vector Internal_Column)
# (limit : Nothing | Integer)
type Context from_spec where_filters orders groups meta_index limit
## PRIVATE
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 new_index =
Context this.from_spec this.where_filters this.orders this.groups new_index this.limit
@ -99,6 +113,9 @@ type Context
## PRIVATE
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 new_filters =
Context this.from_spec new_filters this.orders this.groups this.meta_index this.limit
@ -106,13 +123,20 @@ type Context
## PRIVATE
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 =
Context this.from_spec this.where_filters new_orders this.groups this.meta_index this.limit
## PRIVATE
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 new_groups =
Context this.from_spec this.where_filters this.orders new_groups this.meta_index this.limit
@ -120,6 +144,9 @@ type Context
## PRIVATE
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 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.
# as_subquery : Text -> Vector (Vector Internal_Column) -> [IR.Sub_Query, Vector (Vector Internal_Column)]
as_subquery : Text -> Vector -> Vector
as_subquery alias column_lists =
rewrite_internal_column : Internal_Column -> Internal_Column
rewrite_internal_column column =
@ -169,7 +197,7 @@ type From_Spec
parts of the query, this is especially useful for example in
self-joins, allowing to differentiate between different instances of
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
## PRIVATE
@ -183,8 +211,8 @@ type From_Spec
- on: a list of expressions that will be used as join conditions, these
are usually be equalities between expressions from the left and right
sources.
# type Join (kind : Join_Kind) (left_spec : From_Spec)
# (right_spec : From_Spec) (on : Vector Expression)
# type Join (kind : Join_Kind) (left_spec : From_Spec)
# (right_spec : From_Spec) (on : Vector Expression)
type Join kind left_spec right_spec on
## PRIVATE
@ -285,16 +313,19 @@ type Query
A Select SQL query.
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
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 columns context
## PRIVATE
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
## PRIVATE
@ -302,14 +333,17 @@ type Query
An Insert SQL query that inserts a single row to the table.
Arguments:
- table_name: name of the table to insert to.
- pairs: a list of pairs consisting of a column name and and expression.
- table_name: The name of the table to insert to.
- pairs: A list of pairs consisting of a column name and and expression.
type Insert table_name pairs
## PRIVATE
Creates a query context that just fetches data from a table, without any
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 table_name =
Context (From_Table table_name table_name) [] [] [] [] Nothing
@ -317,15 +351,25 @@ make_ctx_from table_name =
## PRIVATE
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_type x =
Constant sql_type x
## PRIVATE
A helper function to subsitute names tables inside of expressions. It is used
for example when renaming a table during a join.
substitute_origin : Text -> Text -> Expression
A helper function to subsitute names tables inside of expressions.
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
Column origin name ->
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
which applies the original function to their expressions, leaving other
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 f col =
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
resulting vector without resizing it.
type Vector_Builder
## PRIVATE
A leaf in the vector builder.
Arguments:
- vec: The vector at the leaf.
type Leaf vec
## 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
## PRIVATE
@ -52,6 +65,9 @@ type Vector_Builder
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
of `this` and the argument.
++ : Vector_Builder Any | Vector Any -> Vector_Builder Any
@ -71,5 +87,8 @@ empty = Leaf []
## PRIVATE
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 vec = Leaf vec

View File

@ -4,8 +4,54 @@ import Standard.Database.Data.Internal.Vector_Builder
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.
type Sql_Type
## Represents an internal SQL data-type.
Arguments:
@ -35,24 +81,29 @@ type Sql_Type
## PRIVATE
Returns True if this type represents an integer. It only handles the
standard types so it may return false negatives for non-standard ones.
Returns True if this type represents an integer.
It only handles the standard types so it may return false negatives for
non-standard ones.
is_definitely_integer : Boolean
is_definitely_integer =
[Types.INTEGER, Types.SMALLINT, Types.TINYINT].contains this.typeid
## PRIVATE
Returns True if this type represents a boolean. It only handles the
standard types so it may return false negatives for non-standard ones.
Returns True if this type represents a boolean.
It only handles the standard types so it may return false negatives for
non-standard ones.
is_definitely_boolean : Boolean
is_definitely_boolean =
[Types.BOOLEAN, Types.BIT].contains this.typeid
## PRIVATE
Returns True if this type represents a floating point number. It only
handles the standard types so it may return false negatives for
Returns True if this type represents a floating point number.
It only handles the standard types so it may return false negatives for
non-standard ones.
is_definitely_double : Boolean
is_definitely_double =
@ -67,35 +118,51 @@ type Sql_Type
## UNSTABLE
A fragment of a SQL query.
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
the query.
type Sql_Fragment
## UNSTABLE
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
## UNSTABLE
A SQL fragment that represents an object which will be interpolated into
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 Statement
## UNSTABLE
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
interpolated for these parameters.
# type Statement (internal_fragments : Vector Sql_Fragment)
# type Statement (internal_fragments : Vector Sql_Fragment)
type Statement internal_fragments
## UNSTABLE
A vector of code fragments.
Consists of two types of values:
- Sql_Code_Part, representing parts of raw SQL code and
- 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
a list for values that should be substituted.
# prepare : [Text, Vector Any]
# prepare : [Text, Vector Any]
prepare =
to_code fragment = case fragment of
Sql_Code_Part code -> code
@ -155,18 +222,25 @@ type Statement
Json.from_pairs [["query", fragments]]
type Builder
## UNSTABLE
## PRIVATE
A Builder for SQL queries.
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.
Arguments:
- 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
## UNSTABLE
Concatenates two code fragments.
Arguments:
- other: The code fragment to append to `this`.
++ : Builder -> Builder
++ other = Builder (this.fragments ++ other.fragments)
@ -196,6 +270,10 @@ type Builder
## UNSTABLE
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.
prefix_if_present : Text | Builder -> Builder
prefix_if_present prefix =
@ -204,43 +282,13 @@ type Builder
_ -> here.code prefix
if this.is_empty then this else pref++this
## 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.
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
## PRIVATE
Merges neighboring code fragments to create a more compact representation of
the same code.
Arguments:
- fragments: The fragments to be merged together.
optimize_fragments : Vector Sql_Fragment -> Vector Sql_Fragment
optimize_fragments fragments =
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.
type Table
## PRIVATE
Represents a column-oriented table data structure backed by a database.
# type Table (name : Text) (connection : Connection)
# (internal_columns : Vector Internal_Column)
# (context : IR.Context)
Arguments:
- 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
## UNSTABLE
@ -50,7 +57,7 @@ type Table
## UNSTABLE
Converts this table to a JSON structure.
Converts this table into a JSON structure.
to_json : Json
to_json = case this.internal_columns.is_empty of
True ->
@ -60,15 +67,23 @@ type Table
## UNSTABLE
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 =
internal = this.internal_columns.find (p -> p.name == name)
this.make_column internal . map_error (_ -> No_Such_Column_Error name)
## 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
the same context.
Resolves the column name to a column within this table.
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 column = case column of
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
`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.
> Example
Select only the rows of `my_table` where the `"Status"` column has the
value `"Valid"`
@ -100,6 +121,9 @@ type Table
Returns a new Table that will include at most `max_rows` rows from the
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
`limit` method is deterministic only if the Table has been ordered (using
the `sort` method).
@ -129,8 +153,14 @@ type Table
## UNSTABLE
Sets the column value at the given name. If a column with the given name
already exists, it will be replaced. Otherwise a new column is added.
Sets the column value at the given name.
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 name column = case Helpers.ensure_name_is_sane name of
True ->
@ -156,6 +186,9 @@ type Table
## UNSTABLE
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 index = Panic.recover <|
new_index = (Helpers.unify_vector_singleton index).map (this.at >> .as_internal)
@ -174,7 +207,9 @@ type Table
## 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.
index : Column | Vector Column ! Materialized_Table.No_Index_Set_Error
index =
@ -188,26 +223,26 @@ type Table
Sorts the table according to the specified rules.
Arguments:
- by: specifies the columns used for reordering the table. This
argument may be one of:
- a text: the text is treated as a column name.
- a column: any column, which is an expression computed from this
table.
- an order rule: specifies both the sorting column and additional
settings, that will take precedence over the global parameters of
this sort operation. The `column` field of the rule may be a text
or a column, with the semantics described above.
- 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
used for breaking ties, etc.
- order: specifies the default sort order for this operation. All the
rules specified in the `by` argument will default to this setting,
unless specified in the rule.
- missing_last: specifies the default placement of missing values when
compared to non-missing ones. This setting may be overriden by the
particular rules of the `by` argument. Note thet this argument is
independent from `order`, i.e. missing values will always be sorted
according to this rule, ignoring the ascending / descending setting.
- by: Specifies the columns used for reordering the table. This
argument may be one of:
- a text: The text is treated as a column name.
- a column: Any column, which is an expression computed from this
table.
- an order rule: Specifies both the sorting column and additional
settings, that will take precedence over the global parameters of
this sort operation. The `column` field of the rule may be a text
or a column, with the semantics described above.
- 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
used for breaking ties, etc.
- order: Specifies the default sort order for this operation. All the
rules specified in the `by` argument will default to this setting,
unless specified in the rule.
- missing_last: Specifies the default placement of missing values when
compared to non-missing ones. This setting may be overriden by the
particular rules of the `by` argument. Note thet this argument is
independent from `order`, i.e. missing values will always be sorted
according to this rule, ignoring the ascending / descending setting.
> Example
Sorting `table` in ascending order by the value in column `'Quantity'`
@ -261,6 +296,9 @@ type Table
## UNSTABLE
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 columns =
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.
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
`other` with matching indexes. If the index in `other` is not unique,
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 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
@ -365,7 +403,9 @@ type Table
Returns an aggregate table resulting from grouping the elements by the
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 by=Nothing = Panic.recover <|
cols = case by of
@ -481,6 +521,9 @@ type Table
## PRIVATE
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 internal.name this.connection internal.sql_type internal.expression this.context
@ -488,11 +531,19 @@ type Table
## PRIVATE
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
## PRIVATE
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
## PRIVATE
@ -506,12 +557,14 @@ type Table
## PRIVATE
Inserts a new row to the table. It actually modifies the underlying table
in the database.
Inserts a new row to the table.
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.
Arguments:
- values: The values making up the row of the table.
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 values =
table_name = case this.context.from_spec of
@ -533,9 +586,15 @@ type Aggregate_Table
## UNSTABLE
Represents a table with grouped rows.
# type Aggregate_Table (name : Text) (connection : Connection)
# (internal_columns : Vector [Text, IR.Expression])
# (context : IR.Context)
Arguments:
- 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
## UNSTABLE
@ -555,6 +614,9 @@ type Aggregate_Table
## UNSTABLE
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 name =
internal = this.internal_columns.find (p -> p.name == name)
@ -563,7 +625,10 @@ type Aggregate_Table
## PRIVATE
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 =
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
type Integrity_Error
## UNSTABLE
Signalizes that an operation tried using objects coming from different
@ -591,10 +657,19 @@ type Integrity_Error
to_text : Text
to_text = this.object_description + " comes from a different context."
to_display_text : Text
to_display_text = this.to_text
## PRIVATE
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 =
ctx = IR.make_ctx_from table_name
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.
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.
- 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
`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
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.
display_dataframe : Materialized_Table.Table -> Integer -> Integer -> Boolean -> Text
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
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,
it throws a panic. It returns two vectors, one for each input. It assumes
that the names within each argument itself are unique.
@ -668,9 +749,15 @@ combine_names left_names right_names left_suffix right_suffix =
## PRIVATE
Transforms `preferred_names` names in such a way to not collide with `used_names`. If a name
from `preferred_names` does not collide with others, it is kept as is, otherwise numerical
suffixes are added.
Transforms `preferred_names` names in such a way to not collide with
`used_names`.
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 used_names preferred_names =
freshen currently_used name ix =
@ -686,7 +773,12 @@ fresh_names used_names preferred_names =
## 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 columns new_names =
columns.zip new_names col-> name->
@ -694,8 +786,15 @@ rename_columns columns new_names =
## PRIVATE
Ensures that the provided columns do not clash with the vector of names provided as first argument.
Original column names are kept if possible, but if they would clash, the columns are renamed.
Ensures that the provided columns do not clash with the vector of names
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 used_names columns =
fresh_names = here.fresh_names used_names (columns.map .name)

View File

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

View File

@ -30,7 +30,10 @@ type Write_Flag
## 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
## UNSTABLE
@ -45,25 +48,36 @@ type Write_Flag
## 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
## 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
## UNSTABLE
For PNG, it can be the compression level from 0 to 9. A higher value
means a smaller size and longer compression time.
Sets the compression level used when writing a PNG.
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
## UNSTABLE
For WEBP, this is a quality from 1 to 100 (the higher, the better).
By default (without any parameter) and for quality above 100 the lossless
compression is used.
Sets the quality used when writing a WEBP image.
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
## UNSTABLE
@ -74,8 +88,8 @@ type Write_Flag
`Read_Alpha_Channel` flag is specified.
Arguments:
- `location`: the file to read.
- `flags`: the read flags.
- location: the file to read.
- flags: the read flags.
> Example
Read the image.
@ -107,6 +121,10 @@ read location flags=[] =
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
Write the image with applying png compression.
Codecs.write path image
@ -131,3 +149,4 @@ Image.Image.write location flags=[] =
case e of
Polyglot_Error _ -> Panic.throw (File.Io_Error ('Failed to write to the file at ' + path + '.'))
err -> Panic.throw err

View File

@ -11,6 +11,10 @@ type Histogram
## UNSTABLE
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
## UNSTABLE
@ -26,7 +30,7 @@ type Histogram
Create a histogram for the specified channel of the image.
Arguments:
`channel`: the channel number.
- channel: the channel number.
> Example
Create a histogram.

View File

@ -13,6 +13,9 @@ type Image
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
pixel is represented with a vector of 1 to 4 values (channels).
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.
Arguments:
- `row`: the row index.
- `column`: the column index.
- row: the row index.
- column: the column index.
> Example
Get the value at the specified row and column.
@ -61,11 +64,9 @@ type Image
## UNSTABLE
Calculates the per-element sum of an image and a scalar or a matrix.
Matrix should have the same dimensions as the image.
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
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
@ -75,6 +76,8 @@ type Image
appropriate pixel (the element with the same row and column) of this
image.
The matrix should have the same dimensions as the image.
> Example
Add the constant to an image. Operation will add 0.1 to each channel
of the image.
@ -93,10 +96,9 @@ type Image
## UNSTABLE
Calculates the per-element difference between an image and a scalar or a matrix.
Matrix should have the same dimensions as the image.
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
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
@ -106,6 +108,8 @@ type Image
appropriate pixel (the element with the same row and column) of this
image.
The matrix should have the same dimensions as the image.
> Example
Subtract 0.5 from each channel of the image.
image - 0.5
@ -123,10 +127,9 @@ type Image
## UNSTABLE
Calculates the per-element product of an image and a scalar or a matrix.
Matrix should have the same dimensions as the image.
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
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
@ -136,6 +139,8 @@ type Image
appropriate pixel (the element with the same row and column) of this
image.
The matrix should have the same dimensions as the image.
> Example
Multiply each channel of the image by 2.
image * 2
@ -158,10 +163,9 @@ type Image
## UNSTABLE
Performs per-element division of an image and a scalar or a matrix.
Matrix should have the same dimensions as the image.
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
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
@ -171,6 +175,8 @@ type Image
appropriate pixel (the element with the same row and column) of this
image.
The matrix should have the same dimensions as the image.
> Example
Divide each channel of the image by 2.
image / 2
@ -194,7 +200,7 @@ type Image
Check the equality of two images.
Arguments:
- `that`: the matrix to compare with.
- that: the matrix to compare with.
? Implementation Note
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.
Arguments:
- `values`: the vector of numbers.
- `rows`: the number of rows in the resulting image.
- `channels`: the number of channels in the resulting image.
- values: the vector of numbers.
- rows: the number of rows 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
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
## 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 value function =
result = Mat.new
@ -22,6 +29,12 @@ core_op mat value function =
Image.Image result
## PRIVATE
Handles errors in `core_op`.
Arguments:
- error: The value to throw as an error.
core_op_handler : Any
core_op_handler error =
case error of
Matrix.Dimensions_Not_Equal -> Error.throw error

View File

@ -12,13 +12,22 @@ type Matrix_Error
## UNSTABLE
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
## 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
## UNSTABLE
Pretty-prints a matrix error to be readable by the users.
to_display_text : Text
to_display_text = case this of
Index_Out_Of_Bounds_Error rows columns index ->
@ -33,6 +42,9 @@ type Matrix
The matrix data type.
Arguments:
- opencv_mat: The internal representation of the matrix.
Each value of the matrix is represented with an array of
channels. In contrast to an Image data type, Matrix values are
not normalized.
@ -59,8 +71,8 @@ type Matrix
Get the matrix value at the specified row and column.
Arguments:
- `row`: the row index.
- `column`: the column index.
- row: the row index.
- column: the column index.
> Example
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.
Arguments:
- `rows`: the new number of rows.
- `channels`: the new number of channels.
- rows: the new number of rows.
- channels: the new number of channels.
> Example
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.
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
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
@ -124,10 +136,11 @@ type Matrix
## 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:
- `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
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
@ -153,10 +166,11 @@ type Matrix
## 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:
- `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
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
@ -190,7 +204,7 @@ type Matrix
Performs per-element division of two matrices or a matrix and a scalar.
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
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
@ -219,7 +233,7 @@ type Matrix
Check the equality of two matrices.
Arguments:
- `that`: the matrix to compare with.
- that: the matrix to compare with.
? Implementation Note
Two matrices considered equal when they have the same number of rows,
@ -234,8 +248,8 @@ type Matrix
the matrix becomes `max_value`.
Arguments:
- `min_value`: the minimum value in the resulting normalized range.
- `max_value`: the maximum 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.
> Example
Normalize a matrix from vector.
@ -277,9 +291,9 @@ type Matrix
Create a matrix with all elements set to zero.
Arguments:
- `rows`: the number of rows in the resulting matrix.
- `columns`: the number of columns in the resulitng matrix.
- `channels`: the number of channels in the resulting matrix.
- rows: the number of rows in the resulting matrix.
- columns: the number of columns in the resulitng matrix.
- channels: the number of channels in the resulting matrix.
> Example
Create a matrix.
@ -293,9 +307,9 @@ zeros rows columns channels=1 =
Create a matrix with all elements set to one.
Arguments:
- `rows`: the number of rows in the resulting matrix.
- `columns`: the number of columns in the resulitng matrix.
- `channels`: the number of channels in the resulting matrix.
- rows: the number of rows in the resulting matrix.
- columns: the number of columns in the resulitng matrix.
- channels: the number of channels in the resulting matrix.
> Example
Create a matrix.
@ -309,9 +323,9 @@ ones rows columns channels=1 =
Create an identity matrix containing ones on a main diagonal.
Arguments:
- `rows`: the number of rows in the resulting matrix.
- `columns`: the number of columns in the resulitng matrix.
- `channels`: the number of channels in the resulting matrix.
- rows: the number of rows in the resulting matrix.
- columns: the number of columns in the resulitng matrix.
- channels: the number of channels in the resulting matrix.
> Example
Create a matrix.
@ -325,9 +339,9 @@ identity rows columns channels=1 =
Create a matrix from the provided vector.
Arguments:
- `values`: the vector of numbers.
- `rows`: the number of rows in the resulting matrix.
- `channels`: the number of channels in the resulting matrix.
- values: the vector of numbers.
- rows: the number of rows in the resulting matrix.
- channels: the number of channels in the resulting matrix.
> Example
Create a matrix.
@ -335,3 +349,4 @@ identity rows columns channels=1 =
from_vector : Vector -> Integer -> Integer -> Matrix
from_vector values rows=1 channels=1 =
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
## 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 value function =
result = Mat.new
@ -21,6 +28,11 @@ core_op mat value function =
Matrix.Matrix result
## PRIVATE
Handles errors in `core_op`.
Arguments:
- error: The value to throw as an error.
core_op_handler error =
case error of
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
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:
- 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
will be set to `Nothing`.
- a GeoJSON object of type Feature. The format is described in rfc7946.
? Implementation Node
GeoJson support is partial.
? Implementation Note
The GeoJson support is only partial.
- Supported geometry objects are Position and Point. Rows containing
other geometry objects are not included in the resulting dataframe.
- Position arrays are truncated to 3 elements: longitude, latitude
and elevation.
- Nested properties are not supported and not included in the resulting
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 fields = case this of
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
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:
- a GeoJSON object of type FeatureCollection. The format is described in
rfc7946.
? Implementation Node
GeoJson support is partial.
? Implementation Note
The GeoJson support is only partial.
- Supported geometry objects are Position and Point. Rows containing
other geometry objects are not included in the resulting dataframe.
- Position arrays are truncated to 3 elements: longitude, latitude
and elevation.
- Nested properties are not supported and not included in the resulting
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 fields=Nothing =
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.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
## A representation of a column in a Table.
Arguments:
- java_column: The internal representation of the column.
type Column java_column
## Returns a text containing an ASCII-art table displaying this data.
Arguments:
- show_rows: the number of initial rows that should be displayed.
- format_terminal: whether ANSI-terminal formatting should be used
- show_rows: the number of initial rows that should be displayed.
- format_terminal: whether ANSI-terminal formatting should be used
display : Integer -> Boolean -> Text
display show_rows=10 format_terminal=False =
java_col = this.java_column
@ -34,97 +47,158 @@ type Column
## Prints an ASCII-art table with this data to the standard output.
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 =
IO.println (this.display show_rows format_terminal=True)
IO.println ''
## Element-wise equality comparison. 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`.
## Element-wise equality comparison.
Arguments:
- 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
== other =
here.run_vectorized_binary_op this "==" (==) other
## Element-wise non-equality comparison. 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`.
## Element-wise non-equality comparison.
Arguments:
- 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
!= other = (this == other).not
## Element-wise order comparison. 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`.
## Element-wise order comparison.
Arguments:
- 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
>= other =
here.run_vectorized_binary_op this ">=" (>=) other
## Element-wise order comparison. 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`.
## Element-wise order comparison.
Arguments:
- 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
<= other =
here.run_vectorized_binary_op this "<=" (<=) other
## Element-wise order comparison. 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`.
## Element-wise order comparison.
Arguments:
- 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
> other =
here.run_vectorized_binary_op this ">" (>) other
## Element-wise order comparison. 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`.
## Element-wise order comparison.
Arguments:
- 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
< other = here.run_vectorized_binary_op this "<" (<) other
## Element-wise addition. 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`.
## Element-wise addition.
Arguments:
- 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
+ other = here.run_vectorized_binary_op this '+' (+) other
## Element-wise subtraction. 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`.
## Element-wise subtraction.
Arguments:
- 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
- other = here.run_vectorized_binary_op this '-' (-) other
## Element-wise multiplication. 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`.
## Element-wise multiplication.
Arguments:
- 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
* other = here.run_vectorized_binary_op this '*' (*) other
## Element-wise division. 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`.
## Element-wise division.
Arguments:
- 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
/ other = here.run_vectorized_binary_op this '/' (/) other
## Element-wise boolean conjunction. 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`.
## Element-wise boolean conjunction.
Arguments:
- 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
&& other =
here.run_vectorized_binary_op this "&&" (&&) other
## Element-wise boolean disjunction. 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`.
## Element-wise boolean disjunction.
Arguments:
- 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
|| 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
provided default.
Arguments:
- default: The value to replace missing values with.
fill_missing : Any -> Column
fill_missing default =
storage = this.java_column.getStorage
@ -161,28 +238,40 @@ type Column
this.where this.is_missing.not
## 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 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`.
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 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`.
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 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
of results.
Arguments:
- function: The function to apply to each element of `this` column.
map : (Any -> Any) -> Column
map function =
storage = this.java_column.getStorage
@ -193,6 +282,11 @@ type Column
## Applies `function` to consecutive pairs of elements of `this` and `that`
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 that function =
s1 = this.java_column.getStorage
@ -203,6 +297,10 @@ type Column
## Returns a new column, containing the same elements as `this`, but with
the given name.
Arguments:
- name: The new name for the column.
rename : Text -> Column
rename name = Column (this.java_column.rename name)
## Returns the name of this column.
@ -222,6 +320,7 @@ type Column
count = this.length - this.count_missing
## Returns the index of this column, as a column (indexed by itself).
Throws `No_Index_Set_Error` if there is no index set.
index : Column ! Table.No_Index_Set_Error
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.
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
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 index =
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
`indexes`.
Arguments:
- indexes: A column containing boolean values that is used to mask
`this`.
This is useful for filtering the rows by given predicate.
> Example
@ -288,21 +392,21 @@ type Column
## Efficiently joins two tables based on either the index or the specified
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
`other` with matching indexes. If the index values in `other` are not
unique, 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 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 other on=Nothing drop_unmatched=False left_suffix='_left' right_suffix='_right' =
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.
Arguments:
- order: specifies the default sort order for this operation.
- missing_last: specifies the default placement of missing values when
compared to non-missing ones. Note thet this argument is independent
from `order`, i.e. missing values will always be sorted according to
this rule, ignoring the ascending / descending setting.
- comparator: function taking two items in this column and returning
an ordering. If specified, it is used instead of the natural
(`.compare_to`) ordering.
- order: specifies the default sort order for this operation.
- missing_last: specifies the default placement of missing values when
compared to non-missing ones. Note thet this argument is independent
from `order`, i.e. missing values will always be sorted according to
this rule, ignoring the ascending / descending setting.
- comparator: function taking two items in this column and returning
an ordering. If specified, it is used instead of the natural
(`.compare_to`) ordering.
> Example
Sorting `column` in ascending order.
@ -368,7 +472,8 @@ type Column
top of the resulting column.
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.
manhattan_comparator a b = (a.x.abs + a.y.abs) . compare_to (b.x.abs + b.y.abs)
column.sort comparator=manhattan_comparator
@ -449,10 +554,6 @@ type Column
mask = OrderBuilder.buildReversedMask this.length
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
on the contained values.
type Aggregate_Column
@ -462,12 +563,12 @@ type Aggregate_Column
with the provided `function`.
Arguments:
- function: the function used for value aggregation. Values belonging
to each group are passed to this function in a vector.
- skip_missing: controls whether missing values should be included
in groups.
- name_suffix: a suffix that will be appended to the original column
name to generate the resulting column name.
- function: the function used for value aggregation. Values belonging to
each group are passed to this function in a vector.
- skip_missing: controls whether missing values should be included in
groups.
- name_suffix: a suffix that will be appended to the original column name
to generate the resulting column name.
reduce : (Vector.Vector -> Any) -> Boolean -> Text -> Column
reduce function skip_missing=True name_suffix="_result" =
f arr = function (Vector.Vector arr)
@ -477,8 +578,8 @@ type Aggregate_Column
## Sums the values in each group.
Arguments:
- name_suffix: a suffix that will be appended to the original column
name to generate the resulting column name.
- name_suffix: a suffix that will be appended to the original column name
to generate the resulting column name.
sum : Text -> Column
sum name_suffix='_sum' =
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.
Arguments:
- name_suffix: a suffix that will be appended to the original column
name to generate the resulting column name.
- name_suffix: a suffix that will be appended to the original column name
to generate the resulting column name.
max : Text -> Column
max name_suffix='_max' =
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.
Arguments:
- name_suffix: a suffix that will be appended to the original column
name to generate the resulting column name.
- name_suffix: a suffix that will be appended to the original column name
to generate the resulting column name.
min : Text -> Column
min name_suffix='_min' =
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.
Arguments:
- name_suffix: a suffix that will be appended to the original column
name to generate the resulting column name.
- name_suffix: a suffix that will be appended to the original column name
to generate the resulting column name.
count : Text -> Column
count name_suffix='_count' =
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.
Arguments:
- name_suffix: a suffix that will be appended to the original column
name to generate the resulting column name.
- name_suffix: a suffix that will be appended to the original column name
to generate the resulting column name.
mean : Text -> Column
mean name_suffix='_mean' =
vec_mean v = if v.length == 0 then Nothing else
@ -530,14 +631,23 @@ type Aggregate_Column
such vectors.
Arguments:
- name_suffix: a suffix that will be appended to the original column
name to generate the resulting column name.
- name_suffix: a suffix that will be appended to the original column name
to generate the resulting column name.
values : Text -> Column
values name_suffix='_values' =
r = this.java_column.aggregate Nothing name_suffix Vector.Vector False
Column r
## 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
Column col2 ->
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)
## 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 =
s = column.java_column.getStorage
ix = column.java_column.getIndex
rs = s.map name fallback_fn
Column (Java_Column.new "Result" ix rs)
## PRIVATE
Keep this in sync with `org.enso.table.data.Storage.Type.LONG`
storage_type_long : Integer
storage_type_long = 1
## PRIVATE
Keep this in sync with `org.enso.table.data.Storage.Type.DOUBLE`
storage_type_double : Integer
storage_type_double = 2
## PRIVATE
Keep this in sync with `org.enso.table.data.Storage.Type.STRING`
storage_type_string : Integer
storage_type_string = 3
## PRIVATE
Keep this in sync with `org.enso.table.data.Storage.Type.BOOL`
storage_type_bool : Integer
storage_type_bool = 4
## 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 =
Vector.new storage.size ix->
if storage.isNa ix then Json.Null else
factory (storage.getItem ix)
## 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 =
tp = column.getType
if tp == Storage_Type_String then column.getItem ix else
column.getItem ix . to_text
## 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
## Pretty-prints the index out of bounds error.

View File

@ -1,29 +1,30 @@
from Standard.Base import all
type Order_Rule
## UNSTABLE
A rule used for sorting table-like structures.
Arguments:
- column: a value representing the data dimension by which this rule is
sorting. This type does not specify the underlying representation of
a column, assuming that the sorting engine defines its own column
representation.
- comparator: a function taking two elements of the data being sorted
on and returning an `Ordering`. The function may be `Nothing`, in
which case a natural ordering will be used. Note that certain table
backends (such us database connectors) may not support this field
being set to a non-`Nothing` value.
- order: specifies whether the table should be sorted in an ascending
or descending order. The default value of `Nothing` delegates the
decision to the sorting function. Can be set to
`Sort_Order.Ascending` or `Sort_Order.Descending` from the `Base`
library, to specify the ordering.
- missing_last: whether the missing values should be placed at the
beginning or end of the sorted table. Note that this argument is
independent from `order`, i.e. missing values will always be sorted
according to this rule, ignoring the ascending / descending setting.
The default value of `Nothing` delegates the decision to the sorting
function.
- column: a value representing the data dimension by which this rule is
sorting. This type does not specify the underlying representation of a
column, assuming that the sorting engine defines its own column
representation.
- comparator: a function taking two elements of the data being sorted on
and returning an `Ordering`. The function may be `Nothing`, in which
case a natural ordering will be used. Note that certain table backends
(such us database connectors) may not support this field being set to a
non-`Nothing` value.
- order: specifies whether the table should be sorted in an ascending or
descending order. The default value of `Nothing` delegates the decision
to the sorting function. Can be set to `Sort_Order.Ascending` or
`Sort_Order.Descending` from the `Base` library, to specify the
ordering.
- missing_last: whether the missing values should be placed at the
beginning or end of the sorted table. Note that this argument is
independent from `order`, i.e. missing values will always be sorted
according to this rule, ignoring the ascending / descending setting.
The default value of `Nothing` delegates the decision to the sorting
function.
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.
type Type
## A column storing text data.
type Text
## A column storing integer data.
type Integer
## A column storing decimal data.
type Decimal
## A column storing boolean data.
type Boolean
## A column storing arbitrary data.
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
## 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
## An error returned when getting an index but no index is set for that table.
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.
type Table
## A table.
Arguments:
- java_table: The internal java representation of the table.
type Table java_table
## Returns a text containing an ASCII-art table displaying this data.
Arguments:
- show_rows: the number of initial rows that should be displayed.
- format_terminal: whether ANSI-terminal formatting should be used
- show_rows: the number of initial rows that should be displayed.
- format_terminal: whether ANSI-terminal formatting should be used
display : Integer -> Boolean -> Text
display show_rows=10 format_terminal=False =
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.
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 =
IO.println (this.display show_rows format_terminal=True)
IO.println ''
@ -61,6 +117,7 @@ type Table
ADVANCED
Returns a Text used to display this table in the IDE by default.
Returns a JSON object containing useful metadata and previews of column
values.
to_default_visualization_data : Text
@ -74,6 +131,9 @@ type Table
Json.from_pairs [row_count, ['columns', cols]] . to_text
## 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 name = case this.java_table.getColumnByName name of
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
`indexes`.
This is useful for filtering the rows by given predicate.
Arguments:
- indexes: The column to mask the table by. This column should contain
boolean values (`True` or `False`) that determine whether or not the
corresponding row is kept.
This is useful for filtering the rows by given predicate.
> Example
Select only the rows of `my_table` where the `"Status"` column has the
value `"Valid"`
@ -97,8 +157,14 @@ type Table
where indexes =
Table (this.java_table.mask indexes.java_column)
## Sets the column value at the given name. If a column with the given name
already exists, it will be replaced. Otherwise a new column is added.
## Sets the column value at the given name.
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 name column = case column of
Vector.Vector _ ->
@ -112,6 +178,9 @@ type Table
Vector.Vector this.java_table.getColumns . map Column.Column
## 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 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
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
`other` with matching indexes. If the index values in `other` are not
unique, 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 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 other on=Nothing drop_unmatched=False left_suffix='_left' right_suffix='_right' =
case other of
@ -220,27 +289,27 @@ type Table
Sorts the table according to the specified rules.
Arguments:
- by: specifies the columns used for reordering the table. This
argument may be one of:
- a text: the text is treated as a column name.
- 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
table in a way that would result in sorting the given column.
- an order rule: specifies both the sorting column and additional
settings, that will take precedence over the global parameters of
this sort operation. The `column` field of the rule may be a text
or a column, with the semantics described above.
- 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
used for breaking ties, etc.
- order: specifies the default sort order for this operation. All the
rules specified in the `by` argument will default to this setting,
unless specified in the rule.
- missing_last: specifies the default placement of missing values when
compared to non-missing ones. This setting may be overriden by the
particular rules of the `by` argument. Note thet this argument is
independent from `order`, i.e. missing values will always be sorted
according to this rule, ignoring the ascending / descending setting.
- by: Specifies the columns used for reordering the table. This argument
may be one of:
- a text: The text is treated as a column name.
- 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
table in a way that would result in sorting the given column.
- an order rule: Specifies both the sorting column and additional
settings, that will take precedence over the global parameters of
this sort operation. The `column` field of the rule may be a text
or a column, with the semantics described above.
- 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
used for breaking ties, etc.
- order: Specifies the default sort order for this operation. All the
rules specified in the `by` argument will default to this setting,
unless specified in the rule.
- missing_last: Specifies the default placement of missing values when
compared to non-missing ones. This setting may be overriden by the
particular rules of the `by` argument. Note thet this argument is
independent from `order`, i.e. missing values will always be sorted
according to this rule, ignoring the ascending / descending setting.
> Example
Sorting `table` in ascending order by the value in column `'Quantity'`
@ -282,6 +351,14 @@ type Table
Table new_table
## 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
Text -> [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)
## 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 =
order_bool = case order of
Sort_Order.Ascending -> True
@ -317,9 +402,14 @@ type Table
## UNSTABLE
Concatenates `other` 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.
Concatenates `other` to `this`.
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 =
Table (this.java_table.concat other.java_table)
@ -390,10 +480,23 @@ type Table
Table <| this.java_table.applyMask mask
## 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
## Represents a table with grouped rows.
type Aggregate_Table
## A table type with grouped rows.
Arguments:
- java_table: The internal representation of the table.
type Aggregate_Table java_table
## Returns a vector of aggregate columns in this table.
@ -411,69 +514,44 @@ type Aggregate_Table
count = Column.Column this.java_table.count
## 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
Nothing -> Nothing
Nothing -> Error.throw Nothing
c -> Column.Aggregate_Column c
## Prints an ASCII-art table with this data to the standard output.
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 = this.values.print show_rows
## PRIVATE
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
Ensures that the `txt` has at least `len` characters by appending spaces at
the end.
Arguments:
- txt: The text to pad.
- len: The minimum length of the text.
pad : Text -> Integer -> Text
pad txt len =
true_len = txt.characters.length
txt + (" ".repeat (len - true_len))
## 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 =
case Platform.os of
## 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
([" " + 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
## PRIVATE
make_bool_builder : BoolBuilder
make_bool_builder = BoolBuilder.new
## PRIVATE
make_double_builder : NumericBuilder
make_double_builder initial_size = NumericBuilder.createDoubleBuilder initial_size
## PRIVATE
make_long_builder : NumericBuilder
make_long_builder initial_size = NumericBuilder.createLongBuilder initial_size
## PRIVATE
make_inferred_builder : NumericBuilder
make_inferred_builder initial_size = InferredBuilder.new initial_size
## PRIVATE
make_column : Text -> Storage -> Column
make_column name storage = Column.new name storage
## PRIVATE
make_table_without_columns : Integer -> Table
make_table_without_columns row_count =
index = DefaultIndex.new row_count
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.
Arguments
- has_header: Specifies whether the first line of the file should be
interpreted as a header, containing storage names. If set to `False`,
storage names will be automatically generated.
- prefix: text that should be prepended to automatically generated storage
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
inferred from the CSV header row or set manually.
- has_header: Specifies whether the first line of the file should be
interpreted as a header, containing storage names. If set to `False`,
storage names will be automatically generated.
- prefix: text that should be prepended to automatically generated storage
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
inferred from the CSV header row or set manually.
File.File.read_csv : Boolean -> Text -> Table
File.File.read_csv has_header=True prefix='C' =
parser_inst = Parser.create has_header prefix

View File

@ -1,139 +1,30 @@
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
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
Suite.run <|
Test.group "Number" <|
@ -141,6 +32,30 @@ Spec.print_report =
2+3 . should_equal 5
Test.specify "should define multiplication" <|
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 =
case pending of
Nothing ->
@ -157,6 +72,12 @@ group name ~behaviors pending=Nothing =
## 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
Suite.run <|
describe "Number" <|
@ -164,6 +85,7 @@ group name ~behaviors pending=Nothing =
2+3 . should_equal 5
it "should define multiplication" <|
2*3 . should_equal 6
specify : Text -> Any -> (Text | Nothing) -> Nothing
specify label ~behavior pending=Nothing =
result = case pending of
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)
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
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 =
recovery = Panic.recover <|
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 panic was thrown: " + ex.to_display_text + '\n' + maybeExc.get_stack_trace_text)
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
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
Cons h t -> @Tail_Call go t (Cons h acc)
Nil -> acc
res = go list Nil
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
Cons a b -> @Tail_Call go b (acc + a)
Nil -> acc
@ -15,21 +29,50 @@ sum_list = list ->
res = go list 0
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
Cons _ b -> @Tail_Call go b (acc + 1)
Nil -> acc
res = go list 0
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
@Tail_Call go (Cons (act number) results) number-1
res = here.reverse_list (go Nil this)
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 ->
single_call = _ ->
x1 = System.nano_time
@ -43,3 +86,4 @@ measure = ~act -> label -> iter_size -> num_iters ->
fmt = (avg / 1000000).format "%.2f"
IO.println (label + "/iteration:" + act_it_num.to_text + ": " + fmt + "ms")
num_iters.times iteration

View File

@ -6,12 +6,16 @@ import Standard.Visualization.Helpers
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
expected SQL type name and if it was possible to infer it, its expected Enso
typename.
Expected Enso types are inferred based on known SQL types and their mapping
to Enso types.
prepare_visualization : Table.IR.Query -> Json
prepare_visualization x = Helpers.recover_errors <|
prepared = x.to_sql.prepare
code = prepared.first
@ -29,8 +33,12 @@ prepare_visualization x = Helpers.recover_errors <|
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
types it will return `Nothing`.
find_expected_enso_type_for_sql : Sql_Type -> Text
find_expected_enso_type_for_sql sql_type =
if sql_type.is_definitely_integer then "Builtins.Main.Integer" 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
# TODO add an initial offset to fully support lazy visualizations
## PRIVATE
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.
prepare_visualization : Any -> Integer -> Json
prepare_visualization x max_rows = Helpers.recover_errors <| case x of
Dataframe_Table.Table _ ->
dataframe = x.take_start max_rows
@ -71,6 +77,7 @@ prepare_visualization x max_rows = Helpers.recover_errors <| case x of
`dataframe`.
- all_rows_count: the number of all rows in the underlying data, useful if
only a fragment is displayed.
make_json : Table -> Vector Column -> Integer -> Json
make_json dataframe indices all_rows_count =
columns = dataframe.columns
header = ["header", columns.map .name]

View File

@ -1,6 +1,7 @@
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.dsl.CachedContext;
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.VirtualFrame;
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.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.EpbLanguage;
import org.enso.interpreter.epb.EpbParser;
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 {
private final EpbParser.Result code;
private @Child ForeignFunctionCallNode foreign;

View File

@ -30,7 +30,7 @@ type Boolean
Arguments:
- 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
that even if this is False, it will also evaluate that. This is
for performance.
@ -46,7 +46,7 @@ type Boolean
Arguments:
- 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
that even if this is True, it will also evaluate that. This is
for performance.
@ -232,6 +232,10 @@ type Error
get_stack_trace_text = @Builtin_Method "Error.get_stack_trace_text"
## 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 = @Builtin_Method "Error.to_text"
@ -853,11 +857,6 @@ type Array
Arguments:
- 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
Get the element at index 1.
[1,2,3].to_array.at 1
@ -951,8 +950,8 @@ type Ref
## The root type of the Enso numeric hierarchy.
If a Number is expected, then the program can provide both a Decimal and
an Integer in this place.
If a Number is expected, then the program can provide either a Decimal or
an Integer in its place.
@Builtin_Type
type Number
@ -1497,7 +1496,9 @@ type Resource
@Builtin_Type
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.
Arguments:
@ -1520,17 +1521,25 @@ type Managed_Resource
@Builtin_Type
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.
Arguments:
- resource: The resource to be managed automatically.
- function: The action to be executed on resource to clean it up when
it is no longer in use.
> Example
Registering a managed resource.
Managed_Resource
register : Any -> (Any -> Nothing) -> Managed_Resource
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.
Arguments:
@ -1538,7 +1547,9 @@ type Managed_Resource
finalize : Managed_Resource -> Nothing
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.
Arguments:
@ -1548,7 +1559,9 @@ type Managed_Resource
with : Managed_Resource -> (Any -> Any) -> Any
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
managed resources system.

View File

@ -5,7 +5,7 @@ import Database_Tests.Codegen_Spec
import Database_Tests.Sqlite_Spec
import Database_Tests.Postgresql_Spec
main = Test.Suite.runMain <|
main = Test.Suite.run_main <|
Codegen_Spec.spec
Sqlite_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 . 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" <|
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
main = Test.Suite.runMain <|
main = Test.Suite.run_main <|
Geo_Spec.spec

View File

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

View File

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

View File

@ -40,7 +40,7 @@ import Tests.Network.Uri_Spec
import Tests.System.File_Spec
import Tests.System.Process_Spec
main = Test.Suite.runMain <|
main = Test.Suite.run_main <|
Any_Spec.spec
Array_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.Table_Spec
main = Test.Suite.runMain <|
main = Test.Suite.run_main <|
Geo_Map_Spec.spec
Helpers_Spec.spec
Histogram_Spec.spec