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

Enforce conversion method return type & redefine Comparable #10468

Merged
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
c18439e
Enforce conversion method return type
JaroslavTulach Jul 8, 2024
280b7a7
Define Comparator.new factory method
JaroslavTulach Jul 8, 2024
e908a32
Use comparator field of Comparable.By atom
JaroslavTulach Jul 8, 2024
8b659bf
Wrap results of Comparable.from into Comparable.new
JaroslavTulach Jul 8, 2024
5ed87b2
Extract comparator from the Comparable.By second field
JaroslavTulach Jul 8, 2024
4443559
More precise invocation of the comparator
JaroslavTulach Jul 8, 2024
99182bc
Removing extra space
JaroslavTulach Jul 8, 2024
c224121
Comparable.from . compare fix in Day_Of_Week
JaroslavTulach Jul 8, 2024
d4d5f96
Fixing Ordering_Spec
JaroslavTulach Jul 8, 2024
18dde9b
Make sure callbacks are initialized
JaroslavTulach Jul 8, 2024
a639364
Convert to Comparable both arguments before comparing
JaroslavTulach Jul 9, 2024
e527c89
Micro Comparable also needs By constructor
JaroslavTulach Jul 9, 2024
22781c5
Note in changelog
JaroslavTulach Jul 9, 2024
2ae4514
Proper Comparable.from in EqualsConversionsTest
JaroslavTulach Jul 9, 2024
32bf2a3
Convert to Comparable first in Statistics_Spec
JaroslavTulach Jul 9, 2024
fdfd866
Fixing the Comparator_Spec
JaroslavTulach Jul 9, 2024
f5f1b91
Have to return Foo from Foo.from now
JaroslavTulach Jul 9, 2024
091b0fd
Ordering.compare is the preferred way to compare two objects and get …
JaroslavTulach Jul 9, 2024
76fdb98
Merging with develop and its Dictionary
JaroslavTulach Jul 9, 2024
31b33b2
Moving #10468 entry to the Next Release
JaroslavTulach Jul 9, 2024
b652893
Use Ordering.compare in Table.Sorting benchmark
JaroslavTulach Jul 9, 2024
c192129
Hiding Default_Comparator from the APIs
JaroslavTulach Jul 10, 2024
f2efc5c
Comparable is an opaque (SPI only) type
JaroslavTulach Jul 10, 2024
ecfcece
Documenting use of Comparable.new
JaroslavTulach Jul 10, 2024
bd3126b
Moving less_than_bultin outside of Comparable
JaroslavTulach Jul 10, 2024
a2c4def
Missing @Specialization for non-Enso BigInteger TruffleObjects
JaroslavTulach Jul 10, 2024
e7ce96e
Merge remote-tracking branch 'origin/develop' into wip/jtulach/Enforc…
JaroslavTulach Jul 10, 2024
1c50f06
Fixing signature
JaroslavTulach Jul 10, 2024
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
27 changes: 9 additions & 18 deletions distribution/lib/Standard/Base/0.0.0-dev/src/Any.enso
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ from project.Data.Boolean import Boolean, False, True
from project.Data.Ordering import all
from project.Data.Range.Extensions import all
from project.Function import const
from project.Internal.Ordering_Helpers import assert_same_comparators

## Any is the universal top-type, with all other types being subsumed by it.

Expand Down Expand Up @@ -195,8 +196,8 @@ type Any
a > 147
> : Any -> Boolean ! Incomparable_Values
> self that =
assert_same_comparators self that <|
case (Comparable.from self).compare self that of
assert_same_comparators self that comparator->
case comparator.compare self that of
Ordering.Greater -> True
Nothing -> Error.throw (Incomparable_Values.Error self that)
_ -> False
Expand Down Expand Up @@ -225,8 +226,8 @@ type Any
a >= 147
>= : Any -> Boolean ! Incomparable_Values
>= self that =
assert_same_comparators self that <|
case (Comparable.from self).compare self that of
assert_same_comparators self that comparator->
case comparator.compare self that of
Ordering.Equal -> True
Ordering.Greater -> True
Nothing -> Error.throw (Incomparable_Values.Error self that)
Expand Down Expand Up @@ -255,8 +256,8 @@ type Any
a < 147
< : Any -> Boolean ! Incomparable_Values
< self that =
assert_same_comparators self that <|
case (Comparable.from self).compare self that of
assert_same_comparators self that comparator->
case comparator.compare self that of
Ordering.Less -> True
Nothing -> Error.throw (Incomparable_Values.Error self that)
_ -> False
Expand Down Expand Up @@ -287,8 +288,8 @@ type Any
a < 147
<= : Any -> Boolean ! Incomparable_Values
<= self that =
assert_same_comparators self that <|
case (Comparable.from self).compare self that of
assert_same_comparators self that comparator->
case comparator.compare self that of
Ordering.Equal -> True
Ordering.Less -> True
Nothing -> Error.throw (Incomparable_Values.Error self that)
Expand Down Expand Up @@ -505,13 +506,3 @@ type Any
_ = warning_type
self

## 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 `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 (Incomparable_Values.Error this that)
Original file line number Diff line number Diff line change
Expand Up @@ -1059,10 +1059,10 @@ handle_unsupported_argument_types ~action =
Error.throw (Arithmetic_Error.Error "Exponent out of range 0..999999999 (inclusive)")

## PRIVATE
Comparable.from (_ : Decimal) = Decimal_Comparator
Comparable.from (that : Decimal) = Comparable.new that Decimal_Comparator

## PRIVATE
Comparable.from (_ : Number) = Decimal_Comparator
Comparable.from (that : Number) = Comparable.new that Decimal_Comparator

## PRIVATE
Decimal.from (that : Text) = Decimal.from_string that
Expand Down
4 changes: 2 additions & 2 deletions distribution/lib/Standard/Base/0.0.0-dev/src/Data/Json.enso
Original file line number Diff line number Diff line change
Expand Up @@ -367,12 +367,12 @@ type JS_Object_Comparator
hash obj =
values_hashes = obj.field_names.map field_name->
val = obj.get field_name
Comparable.from val . hash val
Comparable.from val . hash
# Return sum, as we don't care about ordering of field names
values_hashes.fold 0 (+)

## PRIVATE
Comparable.from (_:JS_Object) = JS_Object_Comparator
Comparable.from (that:JS_Object) = Comparable.new that JS_Object_Comparator

## PRIVATE
Render the JS_Object to Text with truncated depth.
Expand Down
12 changes: 2 additions & 10 deletions distribution/lib/Standard/Base/0.0.0-dev/src/Data/Numbers.enso
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import project.Panic.Panic
from project.Data.Boolean import Boolean, False, True
from project.Internal.Number_Builtins import all
from project.Widget_Helpers import make_number_format_selector
from project.Internal.Ordering_Helpers import Positive_Integer_Comparator

polyglot java import java.lang.Double
polyglot java import java.lang.Long
Expand Down Expand Up @@ -1288,13 +1289,4 @@ Positive_Integer.from (that : Integer) = Positive_Integer.new that
Integer.from (that : Positive_Integer) = that.integer

## PRIVATE
type Positive_Integer_Comparator
## PRIVATE
compare x y =
Comparable.from x.integer . compare x.integer y.integer

## PRIVATE
hash x = Comparable.from x.integer . hash x.integer

## PRIVATE
Comparable.from (_:Positive_Integer) = Positive_Integer_Comparator
Comparable.from (that:Positive_Integer) = Comparable.new that Positive_Integer_Comparator
33 changes: 23 additions & 10 deletions distribution/lib/Standard/Base/0.0.0-dev/src/Data/Ordering.enso
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ 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

## Provides custom ordering, equality check and hash code for types that need it.

Expand Down Expand Up @@ -109,6 +110,26 @@ from project.Data.Boolean import Boolean, False, True
the custom comparator whenever equality or hash code is needed.
@Builtin_Type
type Comparable
private By value:Any comparator:Any

##
Creates new comparable instance for given `value` and
a `comparator` with two static methods what work on the
type `T` of the provided `value`:

```
type Comparator T
compare : T -> T -> (Ordering|Nothing)
hash : T -> Integer
```
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)

hash self -> Integer = self.comparator.hash self.value

## PRIVATE
Called as a callback from internal engine code for an atom with a custom
comparator. It is assumed that the given atom has a custom comparator, that is
Expand Down Expand Up @@ -147,7 +168,7 @@ type Default_Comparator
hash x = Comparable.hash_builtin x

## PRIVATE
Comparable.from (_:Any) = Default_Comparator
Comparable.from (that:Any) = Comparable.new that Default_Comparator

## Types representing the ordering of values.
@Builtin_Type
Expand Down Expand Up @@ -213,12 +234,4 @@ type Ordering
if sign > 0 then Ordering.Greater else Ordering.Less

## PRIVATE
type Ordering_Comparator
## PRIVATE
compare x y = (Comparable.from x.to_sign).compare x.to_sign y.to_sign

## PRIVATE
hash x = x.to_sign

## PRIVATE
Comparable.from (_:Ordering) = Ordering_Comparator
Comparable.from (that:Ordering) = Comparable.new that Ordering_Comparator
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ type Day_Of_Week_Comparator
hash x = x.to_integer

## PRIVATE
Comparable.from (_:Day_Of_Week) = Day_Of_Week_Comparator
Comparable.from (that:Day_Of_Week) = Comparable.new that Day_Of_Week_Comparator

## PRIVATE
Convert from an integer to a Day_Of_Week
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,8 @@ check_start_valid start length function =

sort vector order on by on_problems:Problem_Behavior =
comps = case on == Nothing of
True -> vector.map it-> Comparable.from it
False -> vector.map it-> Comparable.from (on it)
True -> vector.map it-> Comparable.from it . comparator
False -> vector.map it-> Comparable.from (on it) . comparator
compare_funcs = comps.map (it-> it.compare)
vector.sort_builtin order.to_sign comps compare_funcs by on (on_problems_to_number on_problems)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
private

import project.Any.Any
from project.Data.Boolean import Boolean, False, True
from project.Data.Ordering import all
import project.Errors.Common.Incomparable_Values
import project.Error.Error
import project.Meta

## 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 `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.comparator comp_that.comparator of
True -> action comp_this.comparator
False -> Error.throw (Incomparable_Values.Error this that)

## PRIVATE
type Positive_Integer_Comparator
## PRIVATE
compare x y =
Comparable.from x.integer . compare y.integer

## PRIVATE
hash x = Comparable.from x.integer . hash

## PRIVATE
type Ordering_Comparator
## PRIVATE
compare x y = (Comparable.from x.to_sign).compare y.to_sign

## PRIVATE
hash x = x.to_sign
Original file line number Diff line number Diff line change
Expand Up @@ -228,4 +228,4 @@ type Header_Comparator
Comparable.from key . hash key

## PRIVATE
Comparable.from (_:Header) = Header_Comparator
Comparable.from (that:Header) = Comparable.new that Header_Comparator
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ type URI_Comparator
Comparable.from txt . hash txt

## PRIVATE
Comparable.from (_:URI) = URI_Comparator
Comparable.from (that:URI) = Comparable.new that URI_Comparator

## PRIVATE
type Invalid_Query_String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,4 @@ type From_Spec_Comparator
_ -> Default_Comparator.hash x

## PRIVATE
Comparable.from (_ : From_Spec) = From_Spec_Comparator
Comparable.from (that : From_Spec) = Comparable.new that From_Spec_Comparator
2 changes: 1 addition & 1 deletion distribution/lib/Standard/Image/0.0.0-dev/src/Image.enso
Original file line number Diff line number Diff line change
Expand Up @@ -489,4 +489,4 @@ type Image_Comparator
hash x = x.opencv_mat.hashCode

## PRIVATE
Comparable.from (_:Image) = Image_Comparator
Comparable.from (that:Image) = Comparable.new that Image_Comparator
Original file line number Diff line number Diff line change
Expand Up @@ -450,4 +450,4 @@ type Matrix_Comparator
hash x = x.opencv_mat.hashCode

## PRIVATE
Comparable.from (_:Matrix) = Matrix_Comparator
Comparable.from (that:Matrix) = Comparable.new that Matrix_Comparator
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ type Unordered_Multi_Value_Key_Comparator
hash x = x.hash_code

## PRIVATE
Comparable.from (_:Unordered_Multi_Value_Key) = Unordered_Multi_Value_Key_Comparator
Comparable.from (that:Unordered_Multi_Value_Key) = Comparable.new that Unordered_Multi_Value_Key_Comparator

## PRIVATE
An Enso implementation mirroring `OrderedMultiValueKey` from the Java
Expand Down Expand Up @@ -94,4 +94,4 @@ type Ordered_Multi_Value_Key_Comparator
Error.throw (Illegal_State.new "Ordered_Multi_Value_Key is not intended for usage in unordered collections.")

## PRIVATE
Comparable.from (_:Ordered_Multi_Value_Key) = Ordered_Multi_Value_Key_Comparator
Comparable.from (that:Ordered_Multi_Value_Key) = Comparable.new that Ordered_Multi_Value_Key_Comparator
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ type Bits_Comparator
hash x = Comparable.from x.to_integer . hash x.to_integer

## PRIVATE
Comparable.from (_:Bits) = Bits_Comparator
Comparable.from (that:Bits) = Comparable.new that Bits_Comparator

## Represents the different possible types of values within Table columns.

Expand Down Expand Up @@ -487,10 +487,10 @@ type Value_Type
type Auto

## The type representing the column type being explicitly selected by the user.
Arguments:
- type: The type of columns to select.
Arguments:
- type: The type of columns to select.
type By_Type
## The type representing the column type being explicitly selected by the user.
Arguments:
Arguments:
- type: The type of columns to select.
By_Type type:Value_Type
2 changes: 1 addition & 1 deletion distribution/lib/Standard/Test/0.0.0-dev/src/Group.enso
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,4 @@ type Group_Comparator
text_comp = Comparable.from g.name
text_comp.hash g.name

Comparable.from (_:Group) = Group_Comparator
Comparable.from (that:Group) = Comparable.new that Group_Comparator
Original file line number Diff line number Diff line change
Expand Up @@ -484,4 +484,29 @@ public void illegalPrivateConversion() throws Exception {
runMethod.execute(0);
assertThat(out.toString(), containsString(expectedErrMsg));
}

@Test
public void resultOfConversionIsTypeChecked() throws Exception {
var code =
"""
type First_Type
type Other_Type

First_Type.from (that:Other_Type) = 42
run value -> First_Type = Other_Type
""";
var module = ctx.eval(LanguageInfo.ID, code);
var runMethod = module.invokeMember(Module.EVAL_EXPRESSION, "run");
try {
var r = runMethod.execute(0);
fail("We don't expect any result, but exception: " + r);
} catch (PolyglotException ex) {
assertThat(
ex.getMessage().toLowerCase(),
AllOf.allOf(containsString("type"), containsString("error")));
var typeError = ex.getGuestObject();
assertEquals("Expected type", "First_Type", typeError.getMember("expected").toString());
assertEquals("Got wrong value", 42, typeError.getMember("actual").asInt());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import org.enso.interpreter.runtime.callable.argument.CallArgumentInfo;
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.data.Type;
import org.enso.interpreter.runtime.data.atom.Atom;
import org.enso.interpreter.runtime.data.atom.StructsLibrary;
import org.enso.interpreter.runtime.error.PanicException;
import org.enso.interpreter.runtime.library.dispatch.TypeOfNode;
import org.enso.interpreter.runtime.scope.ModuleScope;
Expand Down Expand Up @@ -140,8 +142,15 @@ private static Object convertor(EnsoContext ctx, Function convFn, Object value)
InvokeFunctionNode.build(
argSchema, DefaultsExecutionMode.EXECUTE, ArgumentsExecutionMode.EXECUTE);
var state = State.create(ctx);
return node.execute(
convFn, null, state, new Object[] {ctx.getBuiltins().comparable(), value});
var by =
node.execute(convFn, null, state, new Object[] {ctx.getBuiltins().comparable(), value});
if (by instanceof Atom atom
&& atom.getConstructor() == ctx.getBuiltins().comparable().getBy()) {
var structs = StructsLibrary.getUncached();
return structs.getField(atom, 1);
} else {
return null;
}
}

/**
Expand Down Expand Up @@ -175,14 +184,14 @@ private static boolean findConversionImpl(
UnresolvedConversion.build(selfScope).resolveFor(ctx, comparableType, thatType);
var betweenBoth = UnresolvedConversion.build(selfScope).resolveFor(ctx, selfType, thatType);

if (isDefinedIn(selfScope, fromSelfType)
&& isDefinedIn(selfScope, fromThatType)
&& convertor(ctx, fromSelfType, self) == convertor(ctx, fromThatType, that)
&& betweenBoth != null) {
return true;
} else {
return false;
if (isDefinedIn(selfScope, fromSelfType) && isDefinedIn(selfScope, fromThatType)) {
var c1 = convertor(ctx, fromSelfType, self);
var c2 = convertor(ctx, fromThatType, that);
if (c1 == c2 && c1 != null && betweenBoth != null) {
return true;
}
}
return false;
}

@Specialization(
Expand Down
Loading
Loading