October 07

On Sunday, 6 October 2024 at 10:19:55 UTC, Nick Treleaven wrote:

>

On Saturday, 5 October 2024 at 17:26:59 UTC, Steven Schveighoffer wrote:

>

It’s the semicolon. As soon as the closing brace, the declaration is over. You would have to invent new syntax.

Maybe type tuple syntax will support this:

struct EntityDef
{
    (int hp) stats;
}

EntityDef ed;
int x = ed.stats.hp;

Let's focus on what exist today, i'm not looking for working on my game in 10 years

I'm working on it TODAY, therefore i need a today's solution

October 07

On Monday, 7 October 2024 at 08:05:59 UTC, ryuukk_ wrote:

>

I'm working on it TODAY, therefore i need a today's solution

import std.typecons;

struct EntityDef
{
    Tuple!(int, "hp") stats;
}

void main()
{
    EntityDef ed;
    int x = ed.stats.hp;
}
October 07

On Monday, 7 October 2024 at 09:22:20 UTC, Nick Treleaven wrote:

>

On Monday, 7 October 2024 at 08:05:59 UTC, ryuukk_ wrote:

>

I'm working on it TODAY, therefore i need a today's solution

import std.typecons;

struct EntityDef
{
    Tuple!(int, "hp") stats;
}

void main()
{
    EntityDef ed;
    int x = ed.stats.hp;
}

Okay, i notice a pattern with Dlang

We went from trying to do that:

struct EntityDef
{
    struct
    {
        int hp;
    } stats;
}

to getting suggested to do that instead:

struct Foo
{
    int bar;

    //struct {/*
    Baz baz;
    struct Baz
    {
        auto opAssign(int value)
          => baz = value;//*/
        int baz;
    }
}

void main()
{
    Foo foo;
    foo.bar = 7;
    foo.baz = 42;

    imported!"std.stdio".writeln(foo); /*
    with opAssign()      Anonymous
    Foo(7, Baz(42))  or  Foo(7, 42)    */
}

to getting suggested to now do that:

import std.typecons;

struct EntityDef
{
    Tuple!(int, "hp") stats;
}

void main()
{
    EntityDef ed;
    int x = ed.stats.hp;
}

Wich ends up improting a 11k LOC module: https://github.com/dlang/phobos/blob/master/std/typecons.d#L11092

Wich traverse god knows how many templates

Only just because i wanteed to do:

struct EntityDef
{
    struct
    {
        int hp;
    } stats;
}

Why wanting to complicate everything?

I know i'm not a professional developper, i do this as a hobby, so i must be missing something

But something tells me that i'm not missing anything, i can't pin point it just yet!

October 07

On Sunday, 6 October 2024 at 05:41:10 UTC, ryuukk_ wrote:

>

There is no new syntax to invent

instead of writing this error:

onlineapp.d(8): Error: no identifier for declarator `stats`

you generate a random identifier and assign it

    extern(D) static Identifier generateAnonymousId(const(char)[] name)

https://github.com/dlang/dmd/blob/master/compiler/src/dmd/identifier.d#L165

I'm very far from being bright, but i know simple logic

The problem is not the ability to generate an id, the problem is that the declaration is over. Anything after the closing brace is a new declaration.

Whitespace is not significant in D, so you have to invent a new syntax to to mean the declaration continues.

D sees this:

struct {
  int x;
  int y;
} something;

as this:

struct {
  int x;
  int y;
}
// DECLARATION OF ANONYMOUS STRUCT OVER.

something;  // this is something different, unrelated to the struct above.

One declaration defines an anonymous struct, and one that is a new declaration something;. Or if you are in a function, something; is treated as a statement.

You can't change existing syntax, as that would break code, so you need new syntax.

C allows this because structs are required to end with a semicolon. So the compiler knows the thing after the brace is part of the same declaration.

-Steve

October 07

On Saturday, 5 October 2024 at 06:35:57 UTC, ryuukk_ wrote:

>

all other C like languages allow me to be concise

Which one btw? Except C++

C#, Go and Zig seems against this functionality..

October 08

On Monday, 7 October 2024 at 19:34:00 UTC, Sergey wrote:

>

On Saturday, 5 October 2024 at 06:35:57 UTC, ryuukk_ wrote:

>

all other C like languages allow me to be concise

Which one btw? Except C++

C#, Go and Zig seems against this functionality..

Don't lie brother

go:

package main

import "fmt"

type EntityDef struct {
    stats struct {
        hp int
    }
}

func main() {

    def := EntityDef{}
    def.stats.hp = 42

    fmt.Println(def)
}

zig:

const std = @import("std");

const EntityDef = struct {
    stats: struct {
        hp: i32,
    },
};

pub fn main() void {
    const def = EntityDef {
        .stats = .{
            .hp = 42
        }
    };
    std.debug.print("{}\n", .{def});
}
October 08

On Tuesday, 8 October 2024 at 07:07:44 UTC, ryuukk_ wrote:

>

On Monday, 7 October 2024 at 19:34:00 UTC, Sergey wrote:

>

On Saturday, 5 October 2024 at 06:35:57 UTC, ryuukk_ wrote:

>

all other C like languages allow me to be concise

Which one btw? Except C++

C#, Go and Zig seems against this functionality..

Don't lie brother

Thanks. when I googled "nested unnamed structs" it showed me some rejected DIPs

October 08

On Monday, 7 October 2024 at 18:06:30 UTC, Steven Schveighoffer wrote:

>

On Sunday, 6 October 2024 at 05:41:10 UTC, ryuukk_ wrote:

>

There is no new syntax to invent

instead of writing this error:

onlineapp.d(8): Error: no identifier for declarator `stats`

you generate a random identifier and assign it

    extern(D) static Identifier generateAnonymousId(const(char)[] name)

https://github.com/dlang/dmd/blob/master/compiler/src/dmd/identifier.d#L165

I'm very far from being bright, but i know simple logic

The problem is not the ability to generate an id, the problem is that the declaration is over. Anything after the closing brace is a new declaration.

Whitespace is not significant in D, so you have to invent a new syntax to to mean the declaration continues.

D sees this:

struct {
  int x;
  int y;
} something;

as this:

struct {
  int x;
  int y;
}
// DECLARATION OF ANONYMOUS STRUCT OVER.

something;  // this is something different, unrelated to the struct above.

One declaration defines an anonymous struct, and one that is a new declaration something;. Or if you are in a function, something; is treated as a statement.

You can't change existing syntax, as that would break code, so you need new syntax.

C allows this because structs are required to end with a semicolon. So the compiler knows the thing after the brace is part of the same declaration.

-Steve

Nonono, you overthink it

Store last anonamous struct

When you see a field without a type, you assign it with that anonymous struct

D people love to complicate everything

Keep things simple and solve people's problem

Stop trying to write essays about simple stuff

ALl the languages have solved this, D will now have move constructor lol, yet can't do basics well

October 08

On Tuesday, 8 October 2024 at 15:10:54 UTC, ryuukk_ wrote:

>

Nonono, you overthink it

Store last anonamous struct

When you see a field without a type, you assign it with that anonymous struct

It doesn't work this way. The parser would have to lookahead to see if the next 2 tokens are an identifier and semicolon. And then close out the declaration in that case.

It could possibly be unambiguous, but I suspect there may be ambiguities with current grammar.

D grammar is mostly free of lookahead, but there are exceptions. It keeps things cleaner.

I'm not saying I don't want this kind of feature, I'm saying I think you need new syntax. What's wrong with new syntax? This in itself is new syntax (to D).

I've asked for struct lambdas in the past, in the context of passing a model to a template. This would be similar.

-Steve

October 08

On Monday, 7 October 2024 at 17:20:00 UTC, ryuukk_ wrote:

>

We went from trying to do that:

struct EntityDef
{
    struct
    {
        int hp;
    } stats;
}

to getting suggested to do that instead:

struct Foo
{
    int bar;

    //struct {/*
    Baz baz;
    struct Baz
    {
        auto opAssign(int value)
          => baz = value;//*/
        int baz;
    }
}

void main()
{
    Foo foo;
    foo.bar = 7;
    foo.baz = 42;

    imported!"std.stdio".writeln(foo); /*
    with opAssign()      Anonymous
    Foo(7, Baz(42))  or  Foo(7, 42)    */
}

I understand you, but you misunderstood me. You probably brought up a problem that can't be solved quickly (or ever). I wanted to acknowledge D's praise and bring a different perspective. Would this solution work for you?

template Foo() { int hp; }
struct EntityDef
{
  mixin Foo stats;
}

void main()
{
  auto num = EntityDef(41);
  assert(num.stats.hp == 41);

  with(num)
  {
    stats.hp = 42;
    assert(stats.hp == 42);
  }
}

SDB@79