March 26
On Friday, 26 March 2021 at 15:51:41 UTC, Per Nordlöw wrote:
> Can you elaborate on what you mean by "compile-time checked optional types"?

Like `if let` in Swift:
https://www.hackingwithswift.com/sixty/10/2/unwrapping-optionals

This form ensures at compile time that a runtime check has made in code that accesses the value held by the optional.

(There's also a `guard let` form to unwrap into a variable in the current scope that requires you to terminate the current scope when the optional is empty).

March 26
On Friday, 26 March 2021 at 15:53:39 UTC, Steven Schveighoffer wrote:
> Notice that it's an assert, which means it can be removed in correctly-written programs. If you return an Optional, emptiness MUST be checked on every access to an element, even when you know (or have proven) it's not empty.

An optional would have an `unwrap` method for this purpose, which also only asserts it is not empty and returns a value.
March 26
On 3/26/21 3:20 PM, Nick Treleaven wrote:
> On Friday, 26 March 2021 at 15:53:39 UTC, Steven Schveighoffer wrote:
>> Notice that it's an assert, which means it can be removed in correctly-written programs. If you return an Optional, emptiness MUST be checked on every access to an element, even when you know (or have proven) it's not empty.
> 
> An optional would have an `unwrap` method for this purpose, which also only asserts it is not empty and returns a value.

That could be possible if the Optional type lazily fetches the value/empty status, in which case now you are dealing with delegates and/or closures. I don't think this is the right path.

-Steve
March 27
On Saturday, 27 March 2021 at 01:06:37 UTC, Steven Schveighoffer wrote:
> That could be possible if the Optional type lazily fetches the value/empty status, in which case now you are dealing with delegates and/or closures. I don't think this is the right path.

You are of course right that returning an optional must eagerly fetch a value. I was just responding to you saying you have to check an optional is empty before accessing the value - you don't.
March 27
On 3/27/21 5:50 AM, Nick Treleaven wrote:
> On Saturday, 27 March 2021 at 01:06:37 UTC, Steven Schveighoffer wrote:
>> That could be possible if the Optional type lazily fetches the value/empty status, in which case now you are dealing with delegates and/or closures. I don't think this is the right path.
> 
> You are of course right that returning an optional must eagerly fetch a value. I was just responding to you saying you have to check an optional is empty before accessing the value - you don't.

I meant on every call to `front`. With the current system, you can avoid this by disabling asserts. With the proposed system, in order to properly construct the Optional, emptiness must be checked. The only way to defer this check to the user is to have Optional be lazily constructed.

-Steve
March 29
On Wednesday, 24 March 2021 at 19:23:21 UTC, Per Nordlöw wrote:
> What's the motive behinds D's range design choice of needing
>
>     if (!empty)
>     {
>         // use front or back
>     }
>
> instead of having front returning an optional/maybe type with enforced pattern matching?
>
> Lack of builtin Optional type?
>
> Choosing the Optional path would have avoided the need for putting error diagnostics such as
>
> https://github.com/dlang/phobos/commit/9bd2f2ba8ff1124a044560c4e6912a13cb5ac694
>
> in the standard library of such an alternative solution.

Hello! It is a good idea what are you talking about. But I agree that it's better to implement it as some method using UFCS. So this will not break anything.

Also I want to say that for me most of the times I check for *non empty* rather than *empty*. So every time I need to write exclamation mark before it. It is not very comfortable. But the problem is that I can't say antonym for the word *empty*. It actually shall not be antonym, but the word that say that this range should have at least one element. My variants are: hasNext, hasFront, hasMore, hasAny or smth like that.
The problemme with *empty* is that it has some *negative* meaning. But I read somewhere recommendations to prefer *positive* words for boolean flags except for rare cases where *negative* flags are simplier to work with, because of domain area where it's used.
But I believe that range is not such a case. And I explained by my own experience that mostly I test for *hasMore* then for *empty*.

Sorry for slightly off-topic post ;-)
March 29
On 3/24/21 3:23 PM, Per Nordlöw wrote:
> What's the motive behinds D's range design choice of needing
> 
>      if (!empty)
>      {
>          // use front or back
>      }
> 
> instead of having front returning an optional/maybe type with enforced pattern matching?

Efficiency. It would be impossible to iterate an array as a range without copying each and every element thereof.

We investigated a few other possibilities, such as returning a pointer to the next element or null. But that has problems related to safety and escaping pointers.
March 30
On Tuesday, 30 March 2021 at 00:51:44 UTC, Andrei Alexandrescu wrote:
> We investigated a few other possibilities, such as returning a pointer to the next element or null. But that has problems related to safety and escaping pointers.

Does -preview=dip1000 help at all with these issues? If so, might be worth revisiting.
March 30
On Tuesday, 30 March 2021 at 00:51:44 UTC, Andrei Alexandrescu wrote:
> We investigated a few other possibilities, such as returning a pointer to the next element or null. But that has problems related to safety and escaping pointers.

I'm eager to experiment with compiler diagnostics that, for a growing number of cases, detects calls to X.front/back and X.popFront/popBack when X is `empty`.

What criteria would need to be fulfilled on `X` and its range interface members in order for such a diagnostics to kick in?
March 30
On Tuesday, 30 March 2021 at 00:51:44 UTC, Andrei Alexandrescu wrote:
> Efficiency. It would be impossible to iterate an array as a range without copying each and every element thereof.

Most likely affects performance in non-release mode, at least.

I wonder what the generated assembly looks like in Rust for a similar case...
1 2 3 4 5 6