November 25, 2016
On Wednesday, 23 November 2016 at 18:54:35 UTC, Igor Shirkalin wrote:
Igor, is the good Russian-speaking forum

https://vk.com/vk_dlang.

There are articles on GUI and other aspects of dlang.
November 25, 2016
On Wednesday, 23 November 2016 at 18:58:55 UTC, ketmar wrote:
>> We can define static array without counting the elements as following:
>>
>>
>> enum array_ = [1u,2,3,4];
>> uint[array_.length] static_array = array_;
>
> there are workarounds, of course. yet i'll take mine `uint[$] a = [1u,2,3,4];` over that quoted mess at any time, without second thought. ;-)

I think you may write it (I mean actual D) with using some template like this:

auto array = static_array!uint(1, 2, 3, 4)

Could you please help to write down this template in the best and clear manner?
November 25, 2016
On Friday, November 25, 2016 14:27:39 Igor Shirkalin via Digitalmars-d-learn wrote:
> On Wednesday, 23 November 2016 at 18:58:55 UTC, ketmar wrote:
> >> We can define static array without counting the elements as following:
> >>
> >>
> >> enum array_ = [1u,2,3,4];
> >> uint[array_.length] static_array = array_;
> >
> > there are workarounds, of course. yet i'll take mine `uint[$] a = [1u,2,3,4];` over that quoted mess at any time, without second thought. ;-)
>
> I think you may write it (I mean actual D) with using some
> template like this:
>
> auto array = static_array!uint(1, 2, 3, 4)
>
> Could you please help to write down this template in the best and clear manner?

That's easy. The problem is if you want it to have the same semantics as

uint[4] arr = [1, 2, 3, 4];

In particular, VRP (Value Range Propagation) is a problem. This compiles

ubyte[4] arr = [1, 2, 3, 4];

because each of the arguments is known to fit in a ubyte. However, making

auto arr = staticArray!ubyte(1, 2, 3, 4);

do the same without forcing a cast is difficult. And if you force the cast, then it's not equivalent anymore, because something like

ubyte[4] arr = [1, 2, 3, 900];

would not compile. And surprisingly, having the function take a dynamic array doesn't fix that problem (though maybe that's something that we could talk the dmd devs into improving). e.g.

auto arr = staticArray!ubyte([1, 2, 3, 4]);

doesn't compile either. The most straightforward implementations are something like

T[n] staticArray(T, size_t n)(auto ref T[n] arr)
{
    return arr;
}

or

auto staticArray(Args...)(Args args)
{
    CommonType!Args[Args.length] arr = [args];
    return arr;
}

but I don't know if the VRP problem is solvable or not without some compiler improvements. If there's a clever enough implementation to get VRP with a function like this with the current language, I haven't figured it out yet.

- Jonathan M Davis

November 25, 2016
On Friday, 25 November 2016 at 14:51:52 UTC, Jonathan M Davis wrote:
>> I think you may write it (I mean actual D) with using some
>> template like this:
>>
>> auto array = static_array!uint(1, 2, 3, 4)
>>
>> Could you please help to write down this template in the best and clear manner?
>
> That's easy. The problem is if you want it to have the same semantics as
>
> uint[4] arr = [1, 2, 3, 4];
>
> In particular, VRP (Value Range Propagation) is a problem. This compiles
>
> ubyte[4] arr = [1, 2, 3, 4];
>
> because each of the arguments is known to fit in a ubyte. However, making
>
> auto arr = staticArray!ubyte(1, 2, 3, 4);
>
> do the same without forcing a cast is difficult. And if you force the cast, then it's not equivalent anymore, because something like
>
> ubyte[4] arr = [1, 2, 3, 900];
>
> would not compile. And surprisingly, having the function take a dynamic array doesn't fix that problem (though maybe that's something that we could talk the dmd devs into improving). e.g.
To mine mind it is not a problem because when you write you think what you write (or you are right). Morover compiler will always tell you are wrong if you make 256 to be ubyte implicity.

>
> auto arr = staticArray!ubyte([1, 2, 3, 4]);
>
> doesn't compile either. The most straightforward implementations are something like
Why? Is it since [1, 2, 3, 4] is int[4] by default?

>
> T[n] staticArray(T, size_t n)(auto ref T[n] arr)
> {
>     return arr;
> }
>
> or
>
> auto staticArray(Args...)(Args args)
> {
>     CommonType!Args[Args.length] arr = [args];
>     return arr;
> }
Great! Thank you. I should take more precise look at std.traits

>
> but I don't know if the VRP problem is solvable or not without some compiler improvements. If there's a clever enough implementation to get VRP with a function like this with the current language, I haven't figured it out yet.
>
> - Jonathan M Davis
As I noticed, to my mind it is not a hindrance to write deliberate things.

- Igor Shirkalin

November 25, 2016
On Friday, 25 November 2016 at 07:17:18 UTC, MGW wrote:
> On Wednesday, 23 November 2016 at 18:54:35 UTC, Igor Shirkalin wrote:
> Igor, is the good Russian-speaking forum
>
> https://vk.com/vk_dlang.
>
> There are articles on GUI and other aspects of dlang.

Thank you, I'll tale a look at it for sure.
November 25, 2016
On 11/25/16 15:51, Jonathan M Davis via Digitalmars-d-learn wrote:
> On Friday, November 25, 2016 14:27:39 Igor Shirkalin via Digitalmars-d-learn wrote:
>> I think you may write it (I mean actual D) with using some
>> template like this:
>>
>> auto array = static_array!uint(1, 2, 3, 4)
>>
>> Could you please help to write down this template in the best and clear manner?
> 
> That's easy. The problem is if you want it to have the same semantics as
> 
> uint[4] arr = [1, 2, 3, 4];
> 
> In particular, VRP (Value Range Propagation) is a problem. This compiles
> 
> ubyte[4] arr = [1, 2, 3, 4];
> 
> because each of the arguments is known to fit in a ubyte. However, making
> 
> auto arr = staticArray!ubyte(1, 2, 3, 4);
> 
> do the same without forcing a cast is difficult. [...]

   enum T[N] staticArray(T, alias ELS, size_t N=ELS.length) = ELS;
   auto arr = staticArray!(ubyte, [1, 2, 3, 4]);

artur
November 25, 2016
On Friday, November 25, 2016 15:59:48 Igor Shirkalin via Digitalmars-d-learn wrote:
> On Friday, 25 November 2016 at 14:51:52 UTC, Jonathan M Davis
> > auto arr = staticArray!ubyte([1, 2, 3, 4]);
> >
> > doesn't compile either. The most straightforward implementations are something like
>
> Why? Is it since [1, 2, 3, 4] is int[4] by default?

It's because [1, 2, 3, 4] is inferred to be int[], and _then_ the compiler tries to instantiate the templated function, whereas with

ubyte[4] = [1, 2, 3, 4];

the compiler looks at is one thing and determines that the array literal can be ubyte[], and it works. And if staticArray is a variadic template instead of taking an array literal, e.g.

auto arr = staticArray!ubyte(1, 2, 3, 4);

then the values all get inferred to be int, and when it tries to assign the arguments to the ubyte[4], it doesn't compile, because they're int and not ubyte, which then means that you're forced to either cast the elements to ubyte at the call site

auto arr = staticArray!ubyte(cast(ubyte)1,
                             cast(ubyte)2,
                             cast(ubyte)3,
                             cast(ubyte)4);

or staticArray itself has to do the cast, but if staticArray itself does the cast, then something like

auto arr = staticArray!ubyte(1, 2, 900);

would compile without error, and you'd end up with whatever cast(ubyte)900 is. I'd _like_ to be able to find a way to make it so that the semantics of the staticArray function are identical to

ubyte[4] = [1, 2, 3, 4];

except that the length is inferred, and I'm coming to the conclusion that it's not possible. That being the case, I'm leaning towards going with

T[n] staticArray(T, size_t n)(auto ref T[n] arr)
{
    return arr;
}

and opening an enhancement request to make the compiler smart enough that

auto arr = staticArray!ubyte([1, 2, 3, 4]);

would work. I don't see

auto arr = staticArray!ubyte(1, 2, 3, 4);

ever working unless the symbols being passed in could be examined at compile time, and I don't think that they can be - just their types.

- Jonathan M Davis

November 25, 2016
On Friday, November 25, 2016 17:03:32 Artur Skawina via Digitalmars-d-learn wrote:
> On 11/25/16 15:51, Jonathan M Davis via Digitalmars-d-learn wrote:
> > On Friday, November 25, 2016 14:27:39 Igor Shirkalin via
> > Digitalmars-d-learn>
> > wrote:
> >> I think you may write it (I mean actual D) with using some
> >> template like this:
> >>
> >> auto array = static_array!uint(1, 2, 3, 4)
> >>
> >> Could you please help to write down this template in the best and clear manner?
> >
> > That's easy. The problem is if you want it to have the same semantics as
> >
> > uint[4] arr = [1, 2, 3, 4];
> >
> > In particular, VRP (Value Range Propagation) is a problem. This compiles
> >
> > ubyte[4] arr = [1, 2, 3, 4];
> >
> > because each of the arguments is known to fit in a ubyte. However, making
> >
> > auto arr = staticArray!ubyte(1, 2, 3, 4);
> >
> > do the same without forcing a cast is difficult. [...]
>
>    enum T[N] staticArray(T, alias ELS, size_t N=ELS.length) = ELS;
>    auto arr = staticArray!(ubyte, [1, 2, 3, 4]);

That won't work with variables. e.g.

ubyte a;
auto arr = staticArray!(ubyte, [1, 2, 3, 4, a]);

would fail to compile. It only works when all of the values are known at compile time, whereas

ubyte a;
ubyte[5] arr = [1, 2, 3, 4, a];

would compile just fine.

- Jonathan M Davis

November 25, 2016
On Friday, November 25, 2016 08:26:11 Jonathan M Davis via Digitalmars-d- learn wrote:
> and opening an enhancement request to make the compiler smart enough that
>
> auto arr = staticArray!ubyte([1, 2, 3, 4]);
>
> would work.

Opened: https://issues.dlang.org/show_bug.cgi?id=16779

And regardless of this particular use case, it's something that arguably should work.

- Jonathan M Davis

November 25, 2016
On 11/25/16 17:30, Jonathan M Davis via Digitalmars-d-learn wrote:
> On Friday, November 25, 2016 17:03:32 Artur Skawina via Digitalmars-d-learn wrote:
>> On 11/25/16 15:51, Jonathan M Davis via Digitalmars-d-learn wrote:
>>> On Friday, November 25, 2016 14:27:39 Igor Shirkalin via
>>> Digitalmars-d-learn>
>>> wrote:
>>>> I think you may write it (I mean actual D) with using some
>>>> template like this:
>>>>
>>>> auto array = static_array!uint(1, 2, 3, 4)
>>>>
>>>> Could you please help to writeown this template in the best and clear manner?
>>>
>>> That's easy. The problem is if you want it to have the same semantics as
>>>
>>> uint[4] arr = [1, 2, 3, 4];
>>>
>>> In particular, VRP (Value Range Propagation) is a problem. This compiles
>>>
>>> ubyte[4] arr = [1, 2, 3, 4];
>>>
>>> because each of the arguments is known to fit in a ubyte. However, making
>>>
>>> auto arr = staticArray!ubyte(1, 2, 3, 4);
>>>
>>> do the same without forcing a cast is difficult. [...]
>>
>>    enum T[N] staticArray(T, alias ELS, size_t N=ELS.length) = ELS;
>>    auto arr = staticArray!(ubyte, [1, 2, 3, 4]);
> 
> That won't work with variables. e.g.
> 
> ubyte a;
> auto arr = staticArray!(ubyte, [1, 2, 3, 4, a]);
> 
> would fail to compile. It only works when all of the values are known at compile time, whereas
> 
> ubyte a;
> ubyte[5] arr = [1, 2, 3, 4, a];
> 
> would compile just fine.

Now you're trying to change the scope. Of course this is a hack, that's only useful in certain contexts, such as initializing static arrays with known values, which this subthread is about.

It actually makes the source code (look) worse; having to use lots of such module- or project-local hacks doesn't scale, and is a symptom of language problems.

The point, however, was that that is the only way to get VRP - the
values must be available at CT for VRP to work effectively.
Your suggestion to "fix" VRP would break CTFE (different implicit
conversions would be allowed at CT and RT) and could result in
code compiling or not depending on the function arguments used,
possibly in a very unintuitive way (eg depending on if the function
args values happened to be CTFE-able).

artur