Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Moving distinct to Map #3229

Merged
merged 11 commits into from
Jan 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions app/gui/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

- [Implemented `Vector.distinct` allowing to remove duplicate elements from a
Vector][3224]
- [Implemented `Duration.time_execution` allowing timing of the execution of an
- expression within the UI][3229]

[3153]: https://github.com/enso-org/enso/pull/3153
[3166]: https://github.com/enso-org/enso/pull/3166
Expand All @@ -25,6 +27,7 @@
[3193]: https://github.com/enso-org/enso/pull/3193
[3208]: https://github.com/enso-org/enso/pull/3208
[3224]: https://github.com/enso-org/enso/pull/3224
[3229]: https://github.com/enso-org/enso/pull/3229

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ polyglot java import java.time.Period as Java_Period

Arguments:
- start_inclusive: The start time of the duration.
- end_inclusife: The end time of the duration.
- end_inclusive: The end time of the duration.

> Example
An hour interval between two points in time.
Expand All @@ -26,6 +26,22 @@ between start_inclusive end_exclusive =
duration = Java_Duration.between start end
Duration period duration


## ADVANCED

Time the evaluation of a function, return a Pair of Duration and Result

Arguments:
- function: Function to execute.
time_execution : Any -> Pair Duration Any
time_execution ~function =
start = System.nano_time
result = Runtime.no_inline function
end = System.nano_time
duration = Duration (Java_Period.ofDays 0) (Java_Duration.ofNanos (end - start))
Pair duration result


type Duration

## An amount of time in terms of years, months, days, hours, minutes,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from Standard.Base import all
from Standard.Builtins import Array

polyglot java import java.util.HashSet
from Standard.Builtins import Unsupported_Argument_Types

## Creates a new vector of the given length, initializing elements using
the provided constructor function.
Expand Down Expand Up @@ -728,6 +727,16 @@ type Vector
Arguments:
- on: A projection from the element type to the value of that element
which determines the uniqueness criteria.
- on_problems: Specifies the behavior when a problem occurs during the
function.
By default, a warning is issued, but the operation proceeds.
If set to `Report_Error`, the operation fails with a dataflow error.
If set to `Ignore`, the operation proceeds without errors or warnings.
- warnings: A Warning_System instance specifying how to handle warnings.
This is a temporary workaround to allow for testing the warning
mechanism. Once the proper warning system is implemented, this
argument will become obsolete and will be removed. No user code should
use this argument, as it will be removed in the future.

The returned unique elements are kept in the same order as they appeared
in the input.
Expand All @@ -746,16 +755,21 @@ type Vector
[Pair 1 "a", Pair 2 "b", Pair 1 "c"] . distinct (on = _.first) == [Pair 1 "a", Pair 2 "b"]
distinct : (Any -> Any) -> Vector Any
distinct (on = x->x) =
builder = here.new_builder
existing_elements = HashSet.new

this.each elem->
proj = on elem
if existing_elements.contains proj then Nothing else
existing_elements.add proj
builder.append elem

builder.to_vector
recovered = Panic.recover
builder = here.new_builder
this.fold Map.empty existing->
item->
key = on item
if (existing.get_or_else key False) then existing else
builder.append item
existing.insert key True
builder.to_vector

recovered.map_error e-> case e of
No_Such_Method_Error _ _ -> Incomparable_Values_Error
Unsupported_Argument_Types _ -> Incomparable_Values_Error
Type_Error _ _ -> Incomparable_Values_Error
_ -> Panic.throw e


## UNSTABLE
Expand Down Expand Up @@ -841,6 +855,19 @@ type Builder
this.append item
Nothing

## Checks whether a predicate holds for at least one element of this builder.

Arguments:
- predicate: A function that takes a list element and returns a boolean
that says whether that value satisfies the conditions of the function.

exists : (Any -> Boolean) -> Boolean
exists predicate =
len = this.length
go idx found = if found || (idx >= len) then found else
@Tail_Call go idx+1 (predicate (this.to_array.at idx))
go 0 False

## Converts this builder to a vector containing all the appended elements.

> Example
Expand Down Expand Up @@ -903,3 +930,9 @@ Singleton_Error.to_display_text : Text
Singleton_Error.to_display_text =
"The vector " + this.vec.to_text + " has only one element."


## UNSTABLE

An error indicating that the vector contains incomparable types.

type Incomparable_Values_Error
15 changes: 15 additions & 0 deletions engine/runtime/src/main/resources/Builtins.enso
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,21 @@ type Invalid_Array_Index_Error array index
@Builtin_Type
type Not_Invokable_Error target

## An error that occurs when arguments used in a function call are invalid
types for the function.

Arguments:
- arguments: The passed arguments.
@Builtin_Type
type Unsupported_Argument_Types arguments

## An error that occurs when the specified module cannot be found.

Arguments:
- name: The module searched for.
@Builtin_Type
type Module_Does_Not_Exist name

## Panics.
type Panic

Expand Down
10 changes: 6 additions & 4 deletions test/Tests/src/Data/Vector_Spec.enso
Original file line number Diff line number Diff line change
Expand Up @@ -256,13 +256,15 @@ spec = Test.group "Vectors" <|
Test.specify "should return a vector containing only unique elements" <|
[1, 3, 1, 2, 2, 1].distinct . should_equal [1, 3, 2]
["a", "a", "a"].distinct . should_equal ["a"]
[1, 1.0, 2, 2.0].distinct . should_equal [1, 2]
jdunkerley marked this conversation as resolved.
Show resolved Hide resolved
[].distinct . should_equal []

["a", 2].distinct . should_equal ["a", 2]
[2, "a", Integer, "a", 2].distinct . should_equal [2, "a", Integer]
Test.specify "should throw a clean error for incomparable types" <|
["a", 2].distinct . should_fail_with Vector.Incomparable_Values_Error
[2, "a", Integer, "a", 2].distinct . should_fail_with Vector.Incomparable_Values_Error
[Pair 1 2, Pair 3 4].distinct . should_fail_with Vector.Incomparable_Values_Error

structural_eq_reason="Disabled until structural equality of Atoms is properly exposed through Polyglot."
Test.specify "should correctly handle distinct with custom types like Atoms" pending=structural_eq_reason <|
Test.specify "should correctly handle distinct with custom types like Atoms that implement compare_to" <|
[T 1 2, T 3 3, T 1 2].distinct . should_equal [T 1 2, T 3 3]

Test.specify "should return a vector containing only unique elements up to some criteria" <|
Expand Down