Thread overview
Feedback Thread: DIP 1039--Static Arrays with Inferred Length--Community Review Round 1
Jan 06
Basile B.
Jan 06
Basile B.
Jan 06
Luhrel
Jan 06
Tim
Jan 06
Dukc
Jan 06
Dukc
January 06
This is the feedback thread for the first round of Community Review of DIP 1039, "Static Arrays with Inferred Length".

===================================
**THIS IS NOT A DISCUSSION THREAD**

Posts in this thread must adhere to the feedback thread rules outlined in the Reviewer Guidelines (and listed at the bottom of this post).

https://github.com/dlang/DIPs/blob/master/docs/guidelines-reviewers.md

That document also provides guidelines on contributing feedback to a DIP review. Please read it before posting here. If you would like to discuss this DIP, please do so in the discussion thread:

https://forum.dlang.org/post/ucqyqkvaznbxkasvdjpx@forum.dlang.org
==================================

You can find DIP 1038 here:

https://github.com/dlang/DIPs/blob/c06ce7f144b3dabf363d1896ddcd31a2a6b7c969/DIPs/DIP1039.md

The review period will end at 11:59 PM ET on January 20, or when I make a post declaring it complete. Feedback posted to this thread after that point may be ignored.

At the end of this review round, the DIP will be moved into the Post-Community Round 1 state. Significant revisions resulting from this review round may cause the DIP manager to require another round of Community Review, otherwise the DIP will be queued for the Final Review.

==================================
Posts in this thread that do not adhere to the following rules will be deleted at the DIP author's discretion:

* All posts must be a direct reply to the DIP manager's initial post, with only two exceptions:

    - Any commenter may reply to their own posts to retract feedback contained in the original post

    - The DIP author may (and is encouraged to) reply to any feedback solely to acknowledge the feedback with agreement or disagreement (preferably with supporting reasons in the latter case)

* Feedback must be actionable, i.e., there must be some action the DIP author can choose to take in response to the feedback, such as changing details, adding new information, or even retracting the proposal.

* Feedback related to the merits of the proposal rather than to the contents of the DIP (e.g., "I'm against this DIP.") is allowed in Community Review (not Final Review), but must be backed by supporting arguments (e.g., "I'm against this DIP because..."). The supporting arguments must be reasonable. Obviously frivolous arguments waste everyone's time.

* Feedback should be clear and concise, preferably listed as bullet points (those who take the time to do an in-depth review and provide feedback in the form of answers to the questions in the documentation linked above will receive much gratitude). Information irrelevant to the DIP or which is not provided in service of clarifying the feedback is unwelcome.
January 06
On Wednesday, 6 January 2021 at 09:23:34 UTC, Mike Parker wrote:
> This is the feedback thread for the first round of Community Review of DIP 1039, "Static Arrays with Inferred Length".

I'd like to see a rationale for this restriction:

---
int[$] bar(int[2] arr)              // Error: not allowed in functions declarations
{
    return [3, 4];
}
---

as `int[$]` would be like `auto` but with a "hint" on how to convert the result.
It looks reasonable not to allow it, in a first time, however. AFAIK dmd internal does not contain anything giving some hint on the return type inferrence.
Also if I trust the comment "not allowed in functions declarations" then

---
void bar(int[$] arr = [1,2]);
---

would be rejected as this use case is like a variable declaration with initializer so the dollar substitution at compile-time is possible.

1. Globally the examples are used to describe the semantics but there is not enough of them. There should be a clear behavior defined for each place where a type can be used. Why is this allowed here, why not here.

2. For now the DIP does not explain what was the problem with the first attempt and how the new design addresses the problem that lead the work to be reverted.

To conclude, even if the change looks ok, the document lacks of accuracy.
January 06
I would like to see a good argument for why it isn't sufficient with a library constructor function in combination with auto.

D has too many features already, so one has to demonstrate that a library solution is inconvenient or that there are contexts where that does not work.

Also, it would be helpful to get an idea of how this would improve existing code bases (e.g. examples from existing code bases).

January 06
On Wednesday, 6 January 2021 at 10:19:01 UTC, Basile B. wrote:
> ---
> void bar(int[$] arr = [1,2]);
> ---
>
> would be rejected as this use case is like a variable

Sorry to prevent any misunderstanding I meant to write

"would be rejected **but** as this use case is like a variable "



January 06
Gosh I'm in the feedback thread. You can delete my previous post.

On Wednesday, 6 January 2021 at 10:19:01 UTC, Basile B. wrote:
> ...

I agree with 1. (It's totally clear for me, but not for you, so I need to rewrite a part of the DIP), but not with 2. because the partial deduction in the first attempt not implemented in this DIP.
January 06
On Wednesday, 6 January 2021 at 09:23:34 UTC, Mike Parker wrote:
> This is the feedback thread for the first round of Community Review of DIP 1039, "Static Arrays with Inferred Length".

The DIP should specify if arrays of char, wchar or dchar will contain a terminating '\0' and if it is included in the length. One example from the DIP already does this for one case:
char[$] a1 = "cerise";              // OK, `$` is replaced with `6` at compile time

Will a1 have a terminating '\0' after the string, which is not not included in the length?
Will an array literal of characters like ['c', 'e', 'r', 'i', 's', 'e'] behave the same?

The DIP would be very useful when porting C code to D, but a different behaviour for terminating '\0' could result in bugs.
January 06
On Wednesday, 6 January 2021 at 09:23:34 UTC, Mike Parker wrote:
> This is the feedback thread for the first round of Community Review of DIP 1039, "Static Arrays with Inferred Length".

I'm slightly against this. The concept is sound per se, but I feel it might not pass the usefulness-to-weight ratio. `std.array.staticArray` can already handle most of the problems described, and it does work in betterC - I just tested with LDC 1.20.1 targeting WebAssembly. while there are remaining cases (`auto fun(int[$] = [1,2,3])` isn't easy to represent now), I suspect they are a bit too trivial to justify a new feature.

On to refining the feature if it's accepted anyway. This should work:
```
int[$] bar(int[2] arr)              // Error: not allowed in functions declarations
{
    return arr ~ [3, 4];
}
```
Why? because you can use `auto` as return type. `Type[$]` should IMO work anywhere `auto` does. Of course this applies only if length of the returned array can be determined at compile time, as in this example.

I do agree that this should probably not work:
```
void bar(T)(T[$] a){}
```
...but I'd include the reasoning. That is, `auto a` would not be allowed either, and one can already achieve the same thing this way:
```
void bar(T, size_t TLen)(T[TLen] a){}
```

You need to mention that this DIP will break code in this, admittedly rare, case:
```
int[] x = something;
int y = something[0 .. staticArrFunc(cast(int[$])[1,2,3])];
```

I wonder if `$` should be allowed inside an expression, like this:
```
int[$+2] a = [1,2,3]; //static array of [1,2,3,0,0]
```
January 06
On Wednesday, 6 January 2021 at 17:54:34 UTC, Dukc wrote:
> You need to mention that this DIP will break code in this, admittedly rare, case:
> ```
> int[] x = something;
> int y = something[0 .. staticArrFunc(cast(int[$])[1,2,3])];
> ```

should be:
```
int[] x = something;
int[] y = x[0 .. staticArrFunc(cast(int[$])[1,2,3])];
```


January 08
The DIP massively fails to provide a good rationale why std.array.staticArray is insufficient. It looks unpleasant, but does the job in practically all cases demonstrated in the examples a1 through a6.

Example a1 currently doesn't work exactly because staticArray returns immutable(char)[6], not char[6]. One needs a char-specific function that is trivial to write:

    C[n] staticCharArray(C, size_t n)(auto ref const(C)[n] charArray)
    {
        return charArray;
    }

Then, example a1 can be written as:
    auto a1 = "cerise".staticCharArray;
    static assert(is(typeof(a1) == char[6]));

Example a2 needs enum, but as long as someone knows what they're doing, enum int[] is fine:
    enum int[] d = [1, 2, 3]; // enum instead of const
    auto a2 = d.staticArray;
    static assert(is(typeof(a2) == int[3]));

Example a3 is straightforward the primary use case for staticArray:
    auto a3 = [1,2,3].staticArray;

Example a4 is, too.
    auto a4 = [[1,2].staticArray, [3, 4]];
    pragma(msg, typeof(a4)); // int[2][]

Example a5 is the first one that's actually painful to work around:
    enum a5DefaultValue = [1,2].staticArray;
    void foo(typeof(a5DefaultValue) a5 = a5DefaultValue)
    {
        static assert(is(typeof(a5) == int[2]));
    }
I think this is rather an argument for allowing type deducted defaulted function parameters generally, not only static arrays.

Example a6 is the prime use-case for auto type deduction:
    int[2] bar() { return [1,2]; }
    auto a6 = bar();
    static assert(is(typeof(a6) == int[2]));

This feature would have a reasonable chance of being accepted some years ago. Since this is the feedback thread, here's my constructive feedback:

A. You maybe need better examples. Ease of reading and writing code can be an argument. You may want to state it somewhere. Unfortunately, this isn't a very good one. If you can come up with examples where workarounds are at least slightly more unpleasant than the one for Example a5 (that don't look too artificial), it might work out.
B. The DIP says that int[2] and int[$] may end up the same thing, but document different intent. IMO, this is the best argument this DIP has. An immediate case where this is relevant is as a function return type. As an example, opSlice (as the lowering of the double-dots in xs[0 .. 1]) returns size_t[2]. It won't ever return another number of size_t, so size_t[$] would be wrong conceptually. Other functions returning static arrays might return T[4], but the 4 isn't particular to the use case. If it might change, this can be documented using T[$] so that uses of the function don't rely on the 4 too much.
This is merely an example I came up with thinking for a minute. There could be much better examples.
C. The DIP really must address the fact that what is gained is very minor. Therefore, the difficulty of the implementation and its maintenance in the compiler code plays a huge role. If you can provide an implementation that most people would agree isn't that big of a deal having in the compiler, that would be really valuable.
January 09
On Wednesday, 6 January 2021 at 09:23:34 UTC, Mike Parker wrote:
> You can find DIP 1038 here:

Typo, should be 1039