July 01, 2022

On Friday, 1 July 2022 at 19:03:25 UTC, Paul Backus wrote:

>
struct A {}
struct B {}

void f(A) {}
void f(B) {}

f({}); // ambiguous

Why is this more problematic than e.g.:

void f(int[])
{
}

void f(byte[])
{
}

void main()
{
    f([]); // Nice ambiguity error
}

?

>

void g(A) {}
void g(int) {}

g({}); // not ambiguous, but potentially confusing

void h(A, B) {}

h({}, {}); // not ambiguous, but potentially confusing

Same:

void h(A[], B[]);
h([], []);
July 01, 2022

On Friday, 1 July 2022 at 20:21:45 UTC, Max Samukha wrote:

>

Why is this more problematic than e.g.:

void f(int[])
{
}

void f(byte[])
{
}

void main()
{
    f([]); // Nice ambiguity error
}

It's not. I'd say they're both equally problematic.

Array literals are useful enough in general that we're willing to accept this problematic special case in order to have them. It's not obvious to me that the proposed {} meets the same standard. Maybe if the proposal were for some kind of "struct literals", rather than just {} by itself, it would be more attractive.

July 01, 2022

On Friday, 1 July 2022 at 19:21:28 UTC, ryuukk_ wrote:

>

A a = {};

that works because it is unambiguous in struct init context.
Whereas {} anywhere else is an empty function literal.
That's also the reason why D cannot use { } for tuples.

Now one could make that case that an empty function literal is useless and so is one containing a sequence of values, without a return statement.

and you could reasonably introduce c++ like braced value sequences to be used as initialization expressions.

As far as I can see that wouldn't clash with existing syntax.

July 02, 2022

On Friday, 1 July 2022 at 11:51:57 UTC, ryuukk_ wrote:

>
    void reset()
    {
        state.end_index = 0;
        state.buffer_list = {};
    }

It is much easier to read, i do not use constructors or RAII, and i feel like i'm being penalized because i want to keep things simple

I also like simple things. But I don't think it should be that simple!

>

Why it's not a confusion here?, we don't do things like this:

   stuff(byte(1), int(1215145415));
```d

It already supports something like this:

struct POW(byte n)
{
  int result;

  this(int pow)
  {
    print(int(pow), byte(n));
  }

  void print(int pow, byte num)
  {
    import std.stdio : writefln;
    this.result = num^^pow;
    writefln("%s", result);
  }
  void reset() {}
}

void main()
{
  auto square = POW!127(2); // "16129"
  //square.init; // Error: `POW(0)` has no effect
  square.writefln!"%s"; // POW!cast(byte)127(16129)
}

SDB@79

July 02, 2022

On Friday, 1 July 2022 at 21:01:43 UTC, Paul Backus wrote:

>

On Friday, 1 July 2022 at 20:21:45 UTC, Max Samukha wrote:

>

Why is this more problematic than e.g.:

void f(int[])
{
}

void f(byte[])
{
}

void main()
{
    f([]); // Nice ambiguity error
}

It's not. I'd say they're both equally problematic.

I really don't see what is problematic with this (except for the FUD spread by some C++ gurus).

>

Array literals are useful enough in general that we're willing to accept this problematic special case in order to have them. It's not obvious to me that the proposed {} meets the same standard. Maybe if the proposal were for some kind of "struct literals", rather than just {} by itself, it would be more attractive.

'{}' by itself would be bad.

July 02, 2022

On Friday, 1 July 2022 at 20:21:45 UTC, Max Samukha wrote:

>

On Friday, 1 July 2022 at 19:03:25 UTC, Paul Backus wrote:

>
struct A {}
struct B {}

void f(A) {}
void f(B) {}

f({}); // ambiguous

Why is this more problematic than e.g.:

void f(int[])
{
}

void f(byte[])
{
}

void main()
{
    f([]); // Nice ambiguity error
}

?

[] has type noreturn[] [1], so the conversion to other array types will work naturally through the type system. {} would need special casing outside the type system, or a new type created just for it. (Assuming {} as an empty function literal was deprecated).

[1] https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1034.md#the-type-of-the-empty-array-literal

July 02, 2022

On Saturday, 2 July 2022 at 11:26:23 UTC, Nick Treleaven wrote:

>

{} would need special casing outside the type system, or a new type created just for it. (Assuming {} as an empty function literal was deprecated).

How it works in C++ is that it is a list for the constructor, so if D wants to do this then the compiler should type {} as a parameter list.

E.g. in C++ it works like this:

tuple<int,double,tuple<float,string>> f() {
    return {0,1.0,{3.14f,"hello"}};
}

Or

using A = tuple<int,double,tuple<float,string>>;

void f(A x){}

int main()
{
    f({0,1.0,{3.14f,"hello"}});
}

Ambiguities are not a big deal, just prefix with the type:

f(A{0,1.0,{3.14f,"hello"}});
July 02, 2022

On Saturday, 2 July 2022 at 13:59:39 UTC, Ola Fosheim Grøstad wrote:

>

if D wants to do this then the compiler should type {} as a parameter list.

A parameter list of zero parameters?

struct S{}

void f();
void f(S s);

f({}); // which gets called?
July 02, 2022

On Friday, 1 July 2022 at 11:51:57 UTC, ryuukk_ wrote:

>

It is much easier to read

I have seen this as an argument multiple times. I always imply "easy to understand" if I see such argument. Unfortunately, "easy to read" often come with "easy to understand" not included. As it is in this case.. imo.

July 02, 2022

On Saturday, 2 July 2022 at 15:00:41 UTC, Nick Treleaven wrote:

>

On Saturday, 2 July 2022 at 13:59:39 UTC, Ola Fosheim Grøstad wrote:

>

if D wants to do this then the compiler should type {} as a parameter list.

A parameter list of zero parameters?

struct S{}

void f();
void f(S s);

f({}); // which gets called?

It is a parameter list for the constructor of S, so F(S s) gets called.