Skip to content

Commit

Permalink
Merge branch 'develop' into wip/MichaelMauderer/Execution_Context_Dro…
Browse files Browse the repository at this point in the history
…pdown_Menu
  • Loading branch information
mergify[bot] authored Apr 16, 2023
2 parents d92b5ef + b42e910 commit d8b6994
Show file tree
Hide file tree
Showing 39 changed files with 1,403 additions and 320 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,7 @@
- [Ensure calls involving warnings remain instrumented][6067]
- [One can define lazy atom fields][6151]
- [Replace IOContexts with Execution Environment and generic Context][6171]
- [Vector.sort handles incomparable types][5998]

[3227]: https://github.com/enso-org/enso/pull/3227
[3248]: https://github.com/enso-org/enso/pull/3248
Expand Down Expand Up @@ -792,6 +793,7 @@
[6067]: https://github.com/enso-org/enso/pull/6067
[6151]: https://github.com/enso-org/enso/pull/6151
[6171]: https://github.com/enso-org/enso/pull/6171
[5998]: https://github.com/enso-org/enso/pull/5998

# Enso 2.0.0-alpha.18 (2021-10-12)

Expand Down
6 changes: 3 additions & 3 deletions distribution/lib/Standard/Base/0.0.0-dev/src/Any.enso
Original file line number Diff line number Diff line change
Expand Up @@ -481,11 +481,11 @@ type Any

## PRIVATE
Checks if the comparators for the given objects are both of the same type. If so,
proceeds with the given action, and if not, throws `Type_Error`.
assert_same_comparators : Any -> Any -> (Any -> Any) -> Any ! Type_Error
proceeds with the given action, and if not, throws `Incomparable_Values` error.
assert_same_comparators : Any -> Any -> (Any -> Any) -> Any ! Incomparable_Values
assert_same_comparators this that ~action =
comp_this = Comparable.from this
comp_that = Comparable.from that
case Meta.is_same_object comp_this comp_that of
True -> action
False -> Error.throw (Type_Error.Error (Meta.type_of comp_this) comp_that "comp_that")
False -> Error.throw (Incomparable_Values.Error this that)
47 changes: 40 additions & 7 deletions distribution/lib/Standard/Base/0.0.0-dev/src/Data/Array.enso
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import project.Error.Error
import project.Errors.Common.Incomparable_Values
import project.Errors.Common.Not_Found
import project.Errors.Common.Index_Out_Of_Bounds
import project.Errors.Problem_Behavior.Problem_Behavior
import project.Meta
import project.Nothing.Nothing
import project.Panic.Panic
Expand Down Expand Up @@ -160,13 +161,17 @@ type Array
Arguments:
- order: The order in which the array elements are sorted.
- on: A projection from the element type to the value of that element
being sorted on.
being sorted on. If set to `Nothing` (the default),
identity function will be used.
- by: A function that compares the result of applying `on` to two
elements, returning an Ordering to compare them.
elements, returning an an `Ordering` if the two elements are comparable
or `Nothing` if they are not. If set to `Nothing` (the default argument),
`Ordering.compare _ _` method will be used.
- on_incomparable: A `Problem_Behavior` specifying what should happen if
two incomparable values are encountered.

By default, elements are sorted in ascending order.

By default, elements are sorted in ascending order, using the comparator
acquired from each element. A custom compare function may be passed to
the sort method.

This is a stable sort, meaning that items that compare the same will not
have their order changed by the sorting process.
Expand All @@ -178,12 +183,32 @@ type Array
- *Average Time:* `O(n * log n)`
- *Worst-Case Space:* `O(n)` additional

? Incomparable values
Incomparable values are either values with different comparators or with
the same comparator returning `Nothing` from its `compare` method.
See the documentation of the `Ordering` module for more info.

? Implementation Note
The sort implementation is based upon an adaptive, iterative mergesort
that requires far fewer than `n * log(n)` comparisons when the array
is partially sorted. When the array is randomly ordered, the
performance is equivalent to a standard mergesort.

? Multiple comparators
Elements with different comparators are incomparable by definition.
This case is handled by first grouping the `self` array into groups
with the same comparator, recursively sorting these groups, and then
merging them back together. The order of the sorted groups in the
resulting array is based on the order of fully qualified names of
the comparators in the `self` array, with the exception of the group
for the default comparator, which is always the first group.

Additionally, an `Incomparable_Values` dataflow error will be returned
if the `on_incomparable` parameter is set to `Problem_Behavior.Report_Error`,
or a warning attached if the `on_incomparable` parameter is set to
`Problem_Behavior.Report_Warning` in case of encountering incomparable
values.

It takes equal advantage of ascending and descending runs in the array,
making it much simpler to merge two or more sorted arrays: simply
concatenate them and sort.
Expand All @@ -197,8 +222,16 @@ type Array
Sorting an array of `Pair`s on the first element, descending.

[Pair 1 2, Pair -1 8].to_array.sort Sort_Direction.Descending (_.first)
sort : Sort_Direction -> (Any -> Any) -> (Any -> Any -> Ordering) -> Vector Any ! Incomparable_Values
sort self (order = Sort_Direction.Ascending) (on = x -> x) (by = (Ordering.compare _ _)) = Vector.sort self order on by

> Example
Sorting an array with elements with different comparators. Values `1`
and `My_Type` have different comparators. `1` will be sorted before `My_Type`
because it has the default comparator.

[My_Type.Value 'hello', 1].to_array.sort == [1, My_Type.Value 'hello'].to_array
sort : Sort_Direction -> (Any -> Any)|Nothing -> (Any -> Any -> (Ordering|Nothing))|Nothing -> Problem_Behavior -> Vector Any ! Incomparable_Values
sort self (order = Sort_Direction.Ascending) on=Nothing by=Nothing on_incomparable=Problem_Behavior.Ignore =
Vector.sort self order on by on_incomparable

## Creates a new `Vector` with only the specified range of elements from the
input, removing any elements outside the range.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ invert_range_selection ranges length needs_sorting =
Empty subranges are discarded.
sort_and_merge_ranges : Vector Range -> Vector Range
sort_and_merge_ranges ranges =
sorted = ranges.filter (range-> range.is_empty.not) . sort on=(.start)
sorted = ranges.filter (range-> range.is_empty.not) . sort on=(_.start)
if sorted.is_empty then [] else
current_ref = Ref.new sorted.first
builder = Vector.new_builder
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import project.Data.Text.Text
import project.Data.Locale.Locale
import project.Errors.Common.Arithmetic_Error
import project.Errors.Common.Incomparable_Values
import project.Error.Error
import project.Nothing.Nothing
import project.Panic.Panic
Expand Down Expand Up @@ -279,6 +280,9 @@ type Number

## Checks equality of numbers, using an `epsilon` value.

! Error Conditions
If either of the arguments is `Number.nan`, an `Incomparable_Values` error is raised.

Arguments:
- that: The number to check equality against.
- epsilon: The value by which `self` and `that` can be separated by before
Expand All @@ -288,7 +292,7 @@ type Number
Check if 1 is equal to 1.0000001 within 0.001.

1.equals 1.0000001 epsilon=0.001
equals : Number -> Number -> Boolean
equals : Number -> Number -> Boolean ! Incomparable_Values
equals self that epsilon=0.0 =
(self == that) || ((self - that).abs <= epsilon)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ type Ordering
Greater

## Compares to values and returns an Ordering
compare : Any -> Any -> Ordering ! (Incomparable_Values | Type_Error)
compare : Any -> Any -> Ordering ! Incomparable_Values
compare x y =
if x < y then Ordering.Less else
if x == y then Ordering.Equal else
Expand Down
67 changes: 51 additions & 16 deletions distribution/lib/Standard/Base/0.0.0-dev/src/Data/Vector.enso
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import project.Data.Filter_Condition.Filter_Condition
import project.Data.List.List
import project.Data.Map.Map
import project.Data.Numbers.Integer
import project.Data.Ordering.Ordering
import project.Data.Ordering.Sort_Direction.Sort_Direction
import project.Data.Pair.Pair
import project.Data.Range.Range
Expand All @@ -17,12 +16,20 @@ import project.Errors.Common.Not_Found
import project.Errors.Common.Type_Error
import project.Error.Error
import project.Errors.Illegal_Argument.Illegal_Argument
import project.Errors.Problem_Behavior.Problem_Behavior
import project.Function.Function
import project.Math
import project.Meta
import project.Nothing.Nothing
import project.Panic.Panic
import project.Random
import project.Warning.Warning

import project.IO

## We have to import also conversion methods, therefore, we import all from the Ordering
module
from project.Data.Ordering import all
from project.Data.Boolean import Boolean, True, False
from project.Data.Index_Sub_Range import Index_Sub_Range, take_helper, drop_helper

Expand Down Expand Up @@ -841,13 +848,17 @@ type Vector a
Arguments:
- order: The order in which the vector elements are sorted.
- on: A projection from the element type to the value of that element
being sorted on.
being sorted on. If set to `Nothing` (the default),
identity function will be used.
- by: A function that compares the result of applying `on` to two
elements, returning an Ordering to compare them.
elements, returning an an `Ordering` if the two elements are comparable
or `Nothing` if they are not. If set to `Nothing` (the default argument),
`Ordering.compare _ _` method will be used.
- on_incomparable: A `Problem_Behavior` specifying what should happen if
two incomparable values are encountered.

By default, elements are sorted in ascending order.

By default, elements are sorted in ascending order, using the comparator
acquired from each element. A custom compare function may be passed to
the sort method.

This is a stable sort, meaning that items that compare the same will not
have their order changed by the sorting process.
Expand All @@ -859,12 +870,32 @@ type Vector a
- *Average Time:* `O(n * log n)`
- *Worst-Case Space:* `O(n)` additional

? Incomparable values
Incomparable values are either values with different comparators or with
the same comparator returning `Nothing` from its `compare` method.
See the documentation of the `Ordering` module for more info.

? Implementation Note
The sort implementation is based upon an adaptive, iterative mergesort
that requires far fewer than `n * log(n)` comparisons when the vector
is partially sorted. When the vector is randomly ordered, the
performance is equivalent to a standard mergesort.

? Multiple comparators
Elements with different comparators are incomparable by definition.
This case is handled by first grouping the `self` vector into groups
with the same comparator, recursively sorting these groups, and then
merging them back together. The order of the sorted groups in the
resulting vector is based on the order of fully qualified names of
the comparators in the `self` vector, with the exception of the group
for the default comparator, which is always the first group.

Additionally, an `Incomparable_Values` dataflow error will be returned
if the `on_incomparable` parameter is set to `Problem_Behavior.Report_Error`,
or a warning attached if the `on_incomparable` parameter is set to
`Problem_Behavior.Report_Warning` in case of encountering incomparable
values.

It takes equal advantage of ascending and descending runs in the array,
making it much simpler to merge two or more sorted arrays: simply
concatenate them and sort.
Expand All @@ -878,16 +909,20 @@ type Vector a
Sorting a vector of `Pair`s on the first element, descending.

[Pair 1 2, Pair -1 8].sort Sort_Direction.Descending (_.first)
sort : Sort_Direction -> (Any -> Any) -> (Any -> Any -> Ordering) -> Vector Any ! Incomparable_Values
sort self (order = Sort_Direction.Ascending) (on = x -> x) (by = (Ordering.compare _ _)) =
comp_ascending l r = by (on l) (on r)
comp_descending l r = by (on r) (on l)
compare = if order == Sort_Direction.Ascending then comp_ascending else
comp_descending

new_vec_arr = self.to_array.sort_builtin compare
if new_vec_arr.is_error then Error.throw new_vec_arr else
Vector.from_polyglot_array new_vec_arr

> Example
Sorting a vector with elements with different comparators. Values `1`
and `My_Type` have different comparators. `1` will be sorted before `My_Type`
because it has the default comparator.

[My_Type.Value 'hello', 1].sort == [1, My_Type.Value 'hello']
sort : Sort_Direction -> (Any -> Any)|Nothing -> (Any -> Any -> (Ordering|Nothing))|Nothing -> Problem_Behavior -> Vector Any ! Incomparable_Values
sort self (order = Sort_Direction.Ascending) on=Nothing by=Nothing on_incomparable=Problem_Behavior.Ignore =
comps = case on == Nothing of
True -> self.map it-> Comparable.from it
False -> self.map it-> Comparable.from (on it)
compare_funcs = comps.map (it-> it.compare)
self.sort_builtin order.to_sign comps compare_funcs by on on_incomparable.to_number

## UNSTABLE
Keeps only unique elements within the vector, removing any duplicates.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,11 @@ type Problem_Behavior
warnings = Warning.get_all result . map .value
cleared_result = Warning.set result []
self.attach_problems_after cleared_result warnings

## PRIVATE
Returns a mapping of Problem_Behavior constructors to an integer.
Used for sending the number to Java, rather than sending the atom.
to_number self = case self of
Ignore -> 0
Report_Warning -> 1
Report_Error -> 2
2 changes: 1 addition & 1 deletion distribution/lib/Standard/Test/0.0.0-dev/src/Problems.enso
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ from Standard.Base import all
from project import Test
import project.Extensions

## Returns values of warnings attached to the value.Nothing
## Returns values of warnings attached to the value.
get_attached_warnings v =
Warning.get_all v . map .value

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ private HostEnsoUtils() {
/**
* Extracts a string representation for a polyglot exception.
*
* @param exexception the exception
* @param ex the exception
* @return message representing the exception
*/
public static String findExceptionMessage(Throwable ex) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.GenerateUncached;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
Expand All @@ -26,6 +27,7 @@
name = "type_of",
description = "Returns the type of a value.",
autoRegister = false)
@GenerateUncached
public abstract class TypeOfNode extends Node {

public abstract Object execute(@AcceptsError Object value);
Expand Down
Loading

0 comments on commit d8b6994

Please sign in to comment.