Re: [ceylon-users] Comparing two Objects

30 views
Skip to first unread message

Ross Tate

unread,
Jul 19, 2015, 11:52:54 AM7/19/15
to ceylon...@googlegroups.com
Interestingly, yes it would actually be harmful. We proved that such features are the primary cause of undecidabilty of many type-system features. So, by recognizing they're not practical and not adding them to the language, you keep everything decidable. Plus, we're currently working on proving that this decision also allows you to add more features that are actually practical while keeping the compiler and the run-time system reliable.

On Saturday, July 18, 2015, John Vasileff <jo...@vasileff.com> wrote:
I agree that this use case doesn’t provide a compelling reason for a language change, since it is rare to need to recover self types. But would supporting these features really be harmful to the type system? I’ve thought of these proposals as a sort of meta programming rather than a more fundamental type system change, but perhaps I’m missing something.

More generally, I think they would help make meta programming safer with improved clarity, which I think is very relevant for Ceylon for things like web and persistence frameworks.

Keeping with the Comparable them, an apples-to-apples, uh, comparison:

Current:

shared [Object*] sortObjects([Object+] objects) {
    value comparableType = comparableTypeFor(objects.collect(type));

    // no discards, since we trust comparableTypeFor()
    value comparables = `function Iterable.narrow`.memberInvoke(
        objects, [comparableType]);

    value result = `function sort`.invoke([comparableType], comparables);
    assert (is [Object*] result);
    return result;
}

Proposed:

shared [Object*] sortObjects([Object+] objects) {
    alias T = comparableTypeFor(objects.collect(type));

    // safe since we trust comparableTypeFor()
    assert (T satisfies Comparable<T>);

    // safe with no discards, since we trust comparableTypeFor()
    value comparables = objects.narrow<T>();

    return sort(comparables);
}

I think the static type checking and code clarity in the second example is far superior.

For completeness, the implementation for `comparableTypeFor` that seems to work:

Type<Anything> comparableTypeFor([Type<Anything>+] types) {
    value t = types.fold<Type<Anything>?>(null)((a,b) {
        if (!exists a) {
            if (!b.subtypeOf(`Comparable<Nothing>`)) {
                throw Exception("oops, ``b`` does not satisfy Comparable");
            }
            return b;
        }
        else {
            // evidence of existence and prior checks ensure `apply<>(a)` is valid
            if (!b.subtypeOf(`interface Comparable`.apply<>(a))) {
                throw Exception("oops, ``b`` cannot be compared to ``a``");
            }
            return a.union(b);
        }
    });
    assert (exists t);
    return t;
}

John

On Jul 17, 2015, at 11:01 PM, Ross Tate <ro...@cs.cornell.edu> wrote:

Don't screw up your type system to satisfy this use case. This use case is exactly what gradual typing is designed for. Since you don't have gradual typing, then the first solution given is totally the correct one: you should just reflect on each object to get the compare method for that object and then supply that method with the appropriate object. If you really want to check that the compare method has Comparable's contract, then in each iteration you should grab the dynamic type of the second object and then check if the first object satisfies Comparable of that type.

I'm working from my phone for a while, so sorry if this is rudely terse!

On Friday, July 17, 2015, John Vasileff <jo...@vasileff.com> wrote:
Yeah, I cheated a bit by saying “homogeneous sequence” :)


> On Jul 17, 2015, at 12:50 PM, Gavin King <gavin...@gmail.com> wrote:
>
> Not quite right, since the runtime type of objects.first is not
> necessarily a supertype of the runtime type of the other objects. You
> would need to iterate the objects and form a union of their types
> somehow. (That's possible in principle if we provided the right APIs.)
>
> On Fri, Jul 17, 2015 at 4:30 AM, John Vasileff <jo...@vasileff.com> wrote:
>> I just realized that this problem raises an interesting use case for a
>> couple proposed enhancements.
>>
>> https://github.com/ceylon/ceylon-spec/issues/1359
>> https://github.com/ceylon/ceylon-spec/issues/560
>>
>> The idea is that we would create a type alias for the unknown type of the
>> objects, check to see if the type is Comparable, and then perform operations
>> that require Comparables on instances of this type without using the
>> metamodel api:
>>
>> shared void printSorted(objects) {
>>    "Must be a homogeneous sequence"
>>    [Object+] objects;
>>
>>    // Create a type reference for the element type of `objects`
>>    alias T = type(objects.first);
>>
>>    // Test to see if `T` really is `Comparable`
>>    if (!T satisfies Comparable<T>) {
>>        throw Exception("oops, we expected Comparables");
>>    }
>>    else {
>>        // In this block, `T satisfies Comparable<T>`
>>
>>        "A correctly type container of our Comparables (discarding non-Ts)"
>>        {T*} ourComparables = objects.narrow<T>();
>>
>>
>>
>>        // Sort (because we can!), and print
>>        print(sort(ourComparables));
>>    }
>> }
>>
>> John
>>
>> On Jul 16, 2015, at 4:04 PM, Dietmar Höhmann <d...@it-con.biz> wrote:
>>
>> Thanks John, your solution works perfectly.
>>
>> BUT only on JVM :-( on JS it throws:
>>
>> /home/dietmar/Software/eclipse/plugins/com.redhat.ceylon.dist.repo_1.1.0.v20141013-1416/repo/ceylon/language/1.1.0/ceylon.language-1.1.0.js:5498
>> if (a[i]!==undefined && !is$(a[i],val_t))throw
>> IncompatibleTypeException$meta$
>>                                               ^
>> ceylon.language.meta.model::IncompatibleTypeException "Wrong type for
>> argument 0, expected ceylon.language::Integer got ceylon.language::Integer"
>>
>> This is most likely a bug in the language module.
>>
>> The background for all this is: I have a nice little script interpreter I'm
>> porting from C# to Ceylon. And I don't have any chance to predict the types
>> the script will later use. In general I'm absolutely with you: Make
>> applications as type safe as possible. But this is a special case. I guess I
>> need to put all the dynamic parts in a separate module that uses the meta
>> model on JVM and dynamic blocks on JS.
>>
>>
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "ceylon-users" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to ceylon-users...@googlegroups.com.
>> To post to this group, send email to ceylon...@googlegroups.com.
>> Visit this group at http://groups.google.com/group/ceylon-users.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/ceylon-users/1725155c-b37e-4693-8b44-8021ba37e148%40googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "ceylon-users" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to ceylon-users...@googlegroups.com.
>> To post to this group, send email to ceylon...@googlegroups.com.
>> Visit this group at http://groups.google.com/group/ceylon-users.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/ceylon-users/B061CF78-A690-40BE-8B5C-0121C93494D9%40vasileff.com.
>>
>> For more options, visit https://groups.google.com/d/optout.
>
>
>
> --
> Gavin King
> ga...@ceylon-lang.org
> http://profiles.google.com/gavin.king
> http://ceylon-lang.org
> http://hibernate.org
> http://seamframework.org
>
> --
> You received this message because you are subscribed to the Google Groups "ceylon-users" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to ceylon-users...@googlegroups.com.
> To post to this group, send email to ceylon...@googlegroups.com.
> Visit this group at http://groups.google.com/group/ceylon-users.
> To view this discussion on the web visit https://groups.google.com/d/msgid/ceylon-users/CAP7PoCe2G0w7D%2Bwsd%3DVrewCjY%3Dntr9TiCwa3AoWOVFQ4mzcD9A%40mail.gmail.com.
> For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "ceylon-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceylon-users...@googlegroups.com.
To post to this group, send email to ceylon...@googlegroups.com.
Visit this group at http://groups.google.com/group/ceylon-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceylon-users/50F57CBC-AC7C-49FB-97AF-388222942D2C%40vasileff.com.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "ceylon-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceylon-users...@googlegroups.com.
To post to this group, send email to ceylon...@googlegroups.com.
Visit this group at http://groups.google.com/group/ceylon-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceylon-users/CABnofR5g1m5qz1YLUfEopM%2BkJ3VKftdugD9XXK3NqQ20WBZzCQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "ceylon-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceylon-users...@googlegroups.com.
To post to this group, send email to ceylon...@googlegroups.com.
Visit this group at http://groups.google.com/group/ceylon-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceylon-users/BC9F9FE1-51E5-4144-A054-51DD3D56AC65%40vasileff.com.
For more options, visit https://groups.google.com/d/optout.

John Vasileff

unread,
Jul 19, 2015, 12:04:32 PM7/19/15
to ceylon...@googlegroups.com
I don’t follow. Is this about writing down Comparable<Integer>, as in https://github.com/ceylon/ceylon-spec/issues/816#issuecomment-36179274 ? Or is it that one of


causes a problem? I thought you were ok with the latter two, at least from a decidability standpoint.


John

Ross Tate

unread,
Jul 19, 2015, 11:37:11 PM7/19/15
to ceylon...@googlegroups.com
It's the first. Using Comparable<Whatever> as a type rather than just as a type constraint can cause problems with decidability. Of course, not all used cause undecidabilty, but it's better to be consistent throughout the language rather than have a bunch of corner cases in the specification.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceylon-users/2BD31CC3-B1BA-44D6-9F45-0F8FAD6F9A66%40vasileff.com.
Reply all
Reply to author
Forward
0 new messages