winglang / wing

A programming language for the cloud ☁️ A unified programming model, combining infrastructure and runtime code into one language ⚑
https://winglang.io
Other
4.94k stars 194 forks source link

Anonymous structs #5731

Open skyrpex opened 7 months ago

skyrpex commented 7 months ago

Use Case

Currently, we can't define structs like this:

struct Props {
  credentials: {
    clientId: str;
    clientSecret: str;
  };
}

The workaround is to define every nested struct separately, and name every single one of them! Not the best UX out there.

struct Credentials {
  clientId: str;
  clientSecret: str;
}

struct Props {
  credentials: Credentials;
}

Proposed Solution

Allow nesting anonymous structs:

struct Props {
  credentials: {
    clientId: str;
    clientSecret: str;
  };
}

But also allow anonymous struts like this one:

let person = { name: str; last: str }.tryParseJson(req.body);
log(person.name);
log(person.last);

Implementation Notes

No response

Component

Language Design

Community Notes

eladb commented 7 months ago

Would it be be useful to be able to also define anonymous structs even if they are not nested?

let person = { name: str; last: str }.tryParseJson(req.body);
log(person.name);
log(person.last);
skyrpex commented 7 months ago

Would it be be useful to be able to also define anonymous structs even if they are not nested?


let person = { name: str; last: str }.tryParseJson(req.body);

log(person.name);

log(person.last);

Sure it would 😍

MarkMcCulloh commented 7 months ago

let person = { name: str; last: str }.tryParseJson(req.body);

I also think this would be neat, but it's probably worth splitting off into a different issue due to the implementation challenges. Anon structs in unambiguous type areas would be a good/easier start (e.g. also allowing Array<{ name: str; last: str }>).

The difficulty with allowing it in possible-expression spots is that it would require us to disambiguate { name: str; last: str } as the parser would see this as a JSON literal expression.

Chriscbr commented 7 months ago

Several other languages also support anonymous classes and anonymous structs, so I can see the appeal.

Stylistically, my preference is to see types named when possible since names can serve documentation and can encourage more readable code (and more readable error messages). It's related to why I find this:

let total = map(Array<Student>.fromJson(Json.parse(body)), (s) => s.name).sorted();

a bit less readable than

let data = Json.parse(body);
let students = Array<Student>.fromJson(data);
let studentNames = map(students, (s) => s.name);
studentNames.sort();

But this is mostly personal taste, I'll admit.

IMO it could be beneficial to revisit this after we address some of the other issues that are functionally limiting structs in Wing (like https://github.com/winglang/wing/issues/3686 and https://github.com/winglang/wing/issues/1796), since it could be trickier implement these if we add anonymous structs first.