Moving distinct to Map (#3229)

* Moving distinct to Map

* Mixed Type Comparable Wrapper

* Missing Bracket
Still an issue with `Integer` in the mixed vector test

* PR comments

* Use naive approach for mixed types

* Enable pending test

* Performance timing function

* Handle incomparable types cleanly

* Tidy up the time_execution function

* PR comments.

* Change log
This commit is contained in:
James Dunkerley 2022-01-25 09:57:30 +00:00 committed by GitHub
parent 107128aeec
commit 8387375d83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 85 additions and 16 deletions

View File

@ -17,6 +17,8 @@
- [Implemented `Vector.distinct` allowing to remove duplicate elements from a - [Implemented `Vector.distinct` allowing to remove duplicate elements from a
Vector][3224] 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 [3153]: https://github.com/enso-org/enso/pull/3153
[3166]: https://github.com/enso-org/enso/pull/3166 [3166]: https://github.com/enso-org/enso/pull/3166
@ -25,6 +27,7 @@
[3193]: https://github.com/enso-org/enso/pull/3193 [3193]: https://github.com/enso-org/enso/pull/3193
[3208]: https://github.com/enso-org/enso/pull/3208 [3208]: https://github.com/enso-org/enso/pull/3208
[3224]: https://github.com/enso-org/enso/pull/3224 [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) # Enso 2.0.0-alpha.18 (2021-10-12)

View File

@ -9,7 +9,7 @@ polyglot java import java.time.Period as Java_Period
Arguments: Arguments:
- start_inclusive: The start time of the duration. - 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 > Example
An hour interval between two points in time. An hour interval between two points in time.
@ -26,6 +26,22 @@ between start_inclusive end_exclusive =
duration = Java_Duration.between start end duration = Java_Duration.between start end
Duration period duration 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 type Duration
## An amount of time in terms of years, months, days, hours, minutes, ## An amount of time in terms of years, months, days, hours, minutes,

View File

@ -1,7 +1,6 @@
from Standard.Base import all from Standard.Base import all
from Standard.Builtins import Array from Standard.Builtins import Array
from Standard.Builtins import Unsupported_Argument_Types
polyglot java import java.util.HashSet
## Creates a new vector of the given length, initializing elements using ## Creates a new vector of the given length, initializing elements using
the provided constructor function. the provided constructor function.
@ -728,6 +727,16 @@ type Vector
Arguments: Arguments:
- on: A projection from the element type to the value of that element - on: A projection from the element type to the value of that element
which determines the uniqueness criteria. 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 The returned unique elements are kept in the same order as they appeared
in the input. in the input.
@ -746,17 +755,22 @@ type Vector
[Pair 1 "a", Pair 2 "b", Pair 1 "c"] . distinct (on = _.first) == [Pair 1 "a", Pair 2 "b"] [Pair 1 "a", Pair 2 "b", Pair 1 "c"] . distinct (on = _.first) == [Pair 1 "a", Pair 2 "b"]
distinct : (Any -> Any) -> Vector Any distinct : (Any -> Any) -> Vector Any
distinct (on = x->x) = distinct (on = x->x) =
recovered = Panic.recover
builder = here.new_builder builder = here.new_builder
existing_elements = HashSet.new this.fold Map.empty existing->
item->
this.each elem-> key = on item
proj = on elem if (existing.get_or_else key False) then existing else
if existing_elements.contains proj then Nothing else builder.append item
existing_elements.add proj existing.insert key True
builder.append elem
builder.to_vector 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 ## UNSTABLE
@ -841,6 +855,19 @@ type Builder
this.append item this.append item
Nothing 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. ## Converts this builder to a vector containing all the appended elements.
> Example > Example
@ -903,3 +930,9 @@ Singleton_Error.to_display_text : Text
Singleton_Error.to_display_text = Singleton_Error.to_display_text =
"The vector " + this.vec.to_text + " has only one element." "The vector " + this.vec.to_text + " has only one element."
## UNSTABLE
An error indicating that the vector contains incomparable types.
type Incomparable_Values_Error

View File

@ -334,6 +334,21 @@ type Invalid_Array_Index_Error array index
@Builtin_Type @Builtin_Type
type Not_Invokable_Error target 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. ## Panics.
type Panic type Panic

View File

@ -256,13 +256,15 @@ spec = Test.group "Vectors" <|
Test.specify "should return a vector containing only unique elements" <| Test.specify "should return a vector containing only unique elements" <|
[1, 3, 1, 2, 2, 1].distinct . should_equal [1, 3, 2] [1, 3, 1, 2, 2, 1].distinct . should_equal [1, 3, 2]
["a", "a", "a"].distinct . should_equal ["a"] ["a", "a", "a"].distinct . should_equal ["a"]
[1, 1.0, 2, 2.0].distinct . should_equal [1, 2]
[].distinct . should_equal [] [].distinct . should_equal []
["a", 2].distinct . should_equal ["a", 2] Test.specify "should throw a clean error for incomparable types" <|
[2, "a", Integer, "a", 2].distinct . should_equal [2, "a", Integer] ["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 that implement compare_to" <|
Test.specify "should correctly handle distinct with custom types like Atoms" pending=structural_eq_reason <|
[T 1 2, T 3 3, T 1 2].distinct . should_equal [T 1 2, T 3 3] [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" <| Test.specify "should return a vector containing only unique elements up to some criteria" <|