Nulls drive me mad

95 views
Skip to first unread message

Alexander Zimin

unread,
Jul 21, 2015, 7:27:17 AM7/21/15
to ceylon...@googlegroups.com
Why in else (see picture) ceylon can't deduce ii is not null? Even C# can.
why.png

Lucas Werkmeister

unread,
Jul 21, 2015, 7:37:40 AM7/21/15
to ceylon...@googlegroups.com
A better way to write that condition is:

Integer? ii = argStock(u);
if (exists ii) {
   
for (Integer t in 0..ii) {
       
assert (is Integer tt = days[t]);
        sum
+= tt;
   
}
   
return sum;
}
else {
   
return null;
}

Note that in an is condition, the syntax is “is Type value”, not “is value Type”. There is also an infix expression form, “value is Type”, but that one doesn’t narrow the type, and is usually not what you want.

I think that in Ceylon 1.2, the following would also work:

Integer? ii = argStock(u);
if (is Null ii) {
    return null;
}
else {
   
for (Integer t in 0..ii) {
       
assert (is Integer tt = days[t]);
        sum
+= tt;
   
}
   
return sum;

}

since the type would be narrowed in the else clause as well.

However, I think a better implementation of the entire function is:

shared Integer? dayPosition(Stock u) {
    if (exists ii = argStock(u)) {
        return sum(days[0..ii]);
    } else {
        return null;
    }
}


On 21.07.2015 13:27, Alexander Zimin wrote:
Why in else (see picture) ceylon can't deduce ii is not null? Even C# can.
--
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/49990c00-1d24-4f20-a4fa-b090edbe95ac%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Gavin King

unread,
Jul 21, 2015, 7:37:52 AM7/21/15
to ceylon...@googlegroups.com
Well, there's two things here:

1. The syntax for an "is" condition is:

if (is Null ii)

What you have written, "is ii Null", is a syntax error, which is why
you have the error:

Incorrect syntax: no viable alternative at token ii

On the token "ii".

2. Narrowing in the else block is a new feature of Ceylon 1.2:

https://github.com/ceylon/ceylon-spec/issues/74

In Ceylon 1.1, the code above is usually written like this:

Integer? ii = ... ;
if (exists ii) {
for (t in 0..ii) { ... }
}
else {
return null;
}




On Tue, Jul 21, 2015 at 1:27 PM, Alexander Zimin <fea...@gmail.com> wrote:
> Why in else (see picture) ceylon can't deduce ii is not null? Even C# can.
>
> --
> 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/49990c00-1d24-4f20-a4fa-b090edbe95ac%40googlegroups.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

Gavin King

unread,
Jul 21, 2015, 7:41:45 AM7/21/15
to ceylon...@googlegroups.com
On Tue, Jul 21, 2015 at 1:37 PM, 'Lucas Werkmeister' via ceylon-users
<ceylon...@googlegroups.com> wrote:

> However, I think a better implementation of the entire function is:
>
> shared Integer? dayPosition(Stock u) {
> if (exists ii = argStock(u)) {
> return sum(days[0..ii]);
> } else {
> return null;
> }
> }


Yeah, much better.

Or, in Ceylon 1.2,

shared Integer? dayPosition(Stock u)
=> if (exists ii = argStock(u))
then sum(days[0..ii])
else null;

Alexander Zimin

unread,
Jul 21, 2015, 8:20:04 AM7/21/15
to ceylon...@googlegroups.com
Thank you, this looked promising

shared Integer[] days;


shared Integer? dayPosition(Stock u)
    {
        if (exists ii = argStock(u))
        {
            return sum(days[0..ii]);
        }
        else
        {
            return null;
        }
    }

But fails in sum with "Argument must be assignable to parameter values of sum: Integer[] is not assignable to {Integer+}". And I rely on its correct working when ii => size(days).

By the way, why sum({}) is wrong and not simply 0. Where {Type+} is useful at all?

Gavin King

unread,
Jul 21, 2015, 9:23:10 AM7/21/15
to ceylon...@googlegroups.com
Ah, sure, so probably better to use the sum() function in
ceylon.math.integer, calling it like this:

sum(*days[0..ii])

The reason that you can't call the generic version of sum() in
ceylon.language with an empty iterable is that - being completely
generic - it doesn't have a zero value for the given type. Remember
that the given type Value could be some user-defined type like
Complex.
> --
> 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/99ae82a4-6854-40a3-b5ad-41592fececc8%40googlegroups.com.
>
> For more options, visit https://groups.google.com/d/optout.



Gavin King

unread,
Jul 21, 2015, 9:28:31 AM7/21/15
to ceylon...@googlegroups.com
Or, another option, FTR, is:

days[0..ii].reduce(plus)

At least, that works in Ceylon 1.2. IIRC, in Ceylon 1.1 you have to be
explicit and write it as:

days[0..ii].reduce(plus<Integer>)

Gavin King

unread,
Jul 21, 2015, 9:31:39 AM7/21/15
to ceylon...@googlegroups.com
Ooops, fold() is better than reduce() in this case. In Ceylon 1.2:

days[0..ii].fold(0)(plus)

In Ceylon 1.1:

days[0..ii].fold(0)(plus<Integer>)

Gavin King

unread,
Jul 21, 2015, 9:50:59 AM7/21/15
to ceylon...@googlegroups.com
Oh, and I guess it's also worth mentioning that there actually *is* an
simple idiom that would let you use the generic sum() function in
ceylon.language if all you have is an empty stream:


{Integer*} ints = ... ;
value total = sum(ints.follow(0));

By prepending 0 to the stream, you give sum() a starting value of the
right type.

Alexander Zimin

unread,
Jul 22, 2015, 6:26:40 AM7/22/15
to ceylon-users
The last one is a marvel. I'm surprised by the agility of your answers. I wouldn't expect Ritchie nor Gosling to answer my questions in a commuinity group.


вторник, 21 июля 2015 г., 16:50:59 UTC+3 пользователь Gavin King написал:
Reply all
Reply to author
Forward
0 new messages