diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Ordering.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Ordering.enso index 4c0d77aad817..649460808659 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Ordering.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Data/Ordering.enso @@ -3,13 +3,11 @@ import project.Data.Numbers.Integer import project.Data.Numbers.Number import project.Error.Error import project.Errors.Common.Incomparable_Values -import project.Errors.Common.Type_Error import project.Errors.Illegal_State.Illegal_State import project.Errors.Unimplemented.Unimplemented import project.Meta import project.Meta.Atom import project.Nothing.Nothing -import project.Panic.Panic from project.Data.Boolean import Boolean, False, True from project.Internal.Ordering_Helpers import all @@ -124,11 +122,11 @@ type Comparable ``` new value:Any comparator:Any -> Comparable = Comparable.By value comparator - compare self that:Comparable = case Meta.is_same_object self.comparator that.comparator of - True -> self.comparator.compare self.value that.value - False -> Error.throw (Incomparable_Values.Error self that) + compare self that -> Ordering ! Incomparable_Values = + Ordering.compare self that - hash self -> Integer = self.comparator.hash self.value + hash self -> Integer = + self.comparator.hash self.value ## PRIVATE Default implementation of a _comparator_. @@ -158,7 +156,8 @@ type Default_Comparator comparator. It is assumed that the given atom has a custom comparator, that is a comparator different than `Default_Comparator`. hash_callback : Atom -> Integer - hash_callback atom = (Comparable.from atom).hash atom + hash_callback atom = + Comparable.from atom . hash ## PRIVATE A callback allowing to compare two atoms with a custom comparator. @@ -182,17 +181,8 @@ type Ordering ## A representation that the first value orders as greater than the second. Greater - ## PRIVATE - ADVANCED - Compares values and returns an Ordering. - compare : Any -> Any -> Ordering ! Incomparable_Values - compare x y = - safe_predicate ~action -> Boolean = Panic.catch Type_Error action=action (_-> False) - - if safe_predicate xy then Ordering.Greater else - Error.throw (Incomparable_Values.Error x y) + ## Compares values and returns an Ordering. + compare x y -> Ordering ! Incomparable_Values = compare_with_comparators x y ## GROUP Conversions ICON convert diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Internal/Ordering_Helpers.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Internal/Ordering_Helpers.enso index dcc219374900..c8da5ae1beb0 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Internal/Ordering_Helpers.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Internal/Ordering_Helpers.enso @@ -3,9 +3,12 @@ private import project.Any.Any from project.Data.Boolean import Boolean, False, True from project.Data.Ordering import all +import project.Errors.Common.Type_Error import project.Errors.Common.Incomparable_Values import project.Error.Error +import project.Panic.Panic import project.Meta +from project.Function import identity ## PRIVATE Checks if the comparators for the given objects are both of the same type. If so, @@ -18,6 +21,18 @@ assert_same_comparators this that ~action = True -> action comp_this.comparator False -> Error.throw (Incomparable_Values.Error this that) +compare_with_comparators this that -> Ordering ! Incomparable_Values = + any_result = Panic.catch Type_Error handler=identity <| + comp_this = Comparable.from this + comp_that = Comparable.from that + + if Meta.is_same_object comp_this.comparator comp_that.comparator then + comp_this.comparator.compare comp_this.value comp_that.value + + case any_result of + result:Ordering -> result + _ -> Error.throw (Incomparable_Values.Error this that) + ## PRIVATE type Positive_Integer_Comparator ## PRIVATE @@ -30,7 +45,7 @@ type Positive_Integer_Comparator ## PRIVATE type Ordering_Comparator ## PRIVATE - compare x y = (Comparable.from x.to_sign).compare y.to_sign + compare x:Ordering y:Ordering = Ordering.compare x.to_sign y.to_sign ## PRIVATE - hash x = x.to_sign + hash x:Ordering = x.to_sign diff --git a/distribution/lib/Standard/Table/0.0.0-dev/src/Value_Type.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Value_Type.enso index 4cc51264f491..8c8c962d2b49 100644 --- a/distribution/lib/Standard/Table/0.0.0-dev/src/Value_Type.enso +++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Value_Type.enso @@ -40,7 +40,7 @@ type Bits type Bits_Comparator ## PRIVATE compare : Bits -> Bits -> Ordering - compare x y = Comparable.from x.to_integer . compare x.to_integer y.to_integer + compare x y = Ordering.compare x.to_integer y.to_integer ## PRIVATE hash : Bits -> Integer diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/EqualsAtomNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/EqualsAtomNode.java index eec8f8d0d81b..8bfcdd37031a 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/EqualsAtomNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/meta/EqualsAtomNode.java @@ -99,25 +99,26 @@ boolean equalsAtomsWithCustomComparator( var ctx = EnsoContext.get(this); var args = new Object[] {cachedComparator, self, other}; var result = invokeNode.execute(compareFn, null, State.create(ctx), args); - assert orderingOrNull(this, ctx, result, compareFn); + assert orderingOrNullOrError(this, ctx, result, compareFn); return ctx.getBuiltins().ordering().newEqual() == result; } @TruffleBoundary - private static boolean orderingOrNull(Node where, EnsoContext ctx, Object obj, Function fn) { + private static boolean orderingOrNullOrError( + Node where, EnsoContext ctx, Object obj, Function fn) { var type = TypeOfNode.getUncached().execute(obj); - if (type == ctx.getBuiltins().ordering().getType() || type == ctx.getBuiltins().nothing()) { + if (type == ctx.getBuiltins().ordering().getType()) { + return true; + } + if (type == ctx.getBuiltins().nothing()) { + return true; + } + if (type == ctx.getBuiltins().dataflowError()) { return true; - } else { - var msg = - "Expecting Ordering or Nothing, but got: " - + obj - + " with type " - + type - + " calling " - + fn; - throw ctx.raiseAssertionPanic(where, msg, null); } + var msg = + "Expecting Ordering or Nothing, but got: " + obj + " with type " + type + " calling " + fn; + throw ctx.raiseAssertionPanic(where, msg, null); } @Specialization( diff --git a/test/Base_Tests/src/Data/Ordering/Comparator_Spec.enso b/test/Base_Tests/src/Data/Ordering/Comparator_Spec.enso index 737d815fb33c..a0b078ad2a60 100644 --- a/test/Base_Tests/src/Data/Ordering/Comparator_Spec.enso +++ b/test/Base_Tests/src/Data/Ordering/Comparator_Spec.enso @@ -16,9 +16,7 @@ type Ord # The comparison is reverted, i.e., `x < y` gives result for `y.number < x.number`. type Ord_Comparator compare x:Ord y:Ord = - cx = Comparable.from x.number - cy = Comparable.from y.number - cx.compare cy + Ordering.compare x.number y.number hash x = (Comparable.from x.number) . hash Comparable.from (that:Ord) = Comparable.new that Ord_Comparator diff --git a/test/Table_Tests/src/Common_Table_Operations/Join/Join_Spec.enso b/test/Table_Tests/src/Common_Table_Operations/Join/Join_Spec.enso index e205a9ba2e53..1dce40415abd 100644 --- a/test/Table_Tests/src/Common_Table_Operations/Join/Join_Spec.enso +++ b/test/Table_Tests/src/Common_Table_Operations/Join/Join_Spec.enso @@ -19,10 +19,9 @@ type My_Type type My_Type_Comparator compare my_1 my_2 = - comp = Comparable.from my_1.x - comp.compare (my_1.x + my_1.y) (my_2.x + my_2.y) + Ordering.compare (my_1.x + my_1.y) (my_2.x + my_2.y) - hash my_type = Comparable.from my_type.x . hash (my_type.x + my_type.y) + hash my_type = Comparable.from (my_type.x + my_type.y) . hash Comparable.from (that:My_Type) = Comparable.new that My_Type_Comparator diff --git a/test/Table_Tests/src/In_Memory/Table_Spec.enso b/test/Table_Tests/src/In_Memory/Table_Spec.enso index 65323f4725f9..0e27b1cb972e 100644 --- a/test/Table_Tests/src/In_Memory/Table_Spec.enso +++ b/test/Table_Tests/src/In_Memory/Table_Spec.enso @@ -31,11 +31,11 @@ type My_Comparator compare left right = left_sum = left.x + left.y right_sum = right.x + right.y - (Comparable.from left_sum) . compare left_sum right_sum + Ordering.compare left_sum right_sum hash my = sum = my.x + my.y - Comparable.from sum . hash sum + Comparable.from sum . hash Comparable.from (that:My) = Comparable.new that My_Comparator