munificent / ui-as-code

Design work on improving Dart's syntax for UI code
BSD 3-Clause "New" or "Revised" License
121 stars 11 forks source link

Choices.md uses incorrect Row API to argue against Argument Initializer Blocks #17

Open yjbanov opened 6 years ago

yjbanov commented 6 years ago

See Choices.md.

With Argument Initializer Blocks (ARB) the difference is actually this:

Before:

Row(
  children: [
    Text("1"),
    Text("2"),
    Text("3"),
  ],
);

After:

Row {
  children = [
    Text("1"),
    Text("2"),
    Text("3"),
  ];
};

Flutter code is really into named arguments and I think we should optimize for them. That's exactly what ARB does.

munificent commented 6 years ago

I should have been clearer but in that section I was also assuming that children had been turned into a rest parameter so that those child widgets get passed positionally.

If we use a named parameter, then then ARB still doesn't solve the problem because now the children are inside a list literal, not a block. How would you omit Text("2") from that list in your example? We'd need to add both ARBs for conditionally omitting entire named parameters at the block level and some other syntax for conditionally omitting list elements inside a list literal.

yjbanov commented 6 years ago

If we're allowed to assume some of the other proposals, then assuming control flow elements, it could be:

Row {
  children = [
    Text("1"),
    if (condition) Text("2"),
    Text("3"),
  ];
};

That said, I think we could go farther with AIB. As discussed in https://github.com/munificent/ui-as-code/issues/15#issuecomment-426851002 it would be great for blocks cover "child slot" properties too. That means constructing lists using blocks. yield does indeed look quite sub-optimal. We should also see if they combine with other proposals, such as optional semi-colons, value types (if they are anything like Golang's or Rust's structs, note that those languages do use { } to initialize them), etc.

AIB proposal came out as one possible first step towards the following "ideal" syntax:

Row {
  crossAxisAlignment = .center
  children {
    Text("1")
    if (condition) {
     Text("2")
    }
    Text("3")
  }
}

I'd be most in favor of proposals that take us towards something that's really great. I understand that we may have to think 3-5 years ahead while adding small features on a quarter-by-quarter basis, but I think it's worth it. Without a long-term vision we'll continue aggregating debt to be paid by our future selves.

That's one of the reasons I'm skeptical of rest args. They bring some short term fix on a single metric - line length of nested expressions - at the cost of a little readability. But I'm super fuzzy on what long-term vision they contribute to.

munificent commented 6 years ago

I'd be most in favor of proposals that take us towards something that's really great. I understand that we may have to think 3-5 years ahead while adding small features on a quarter-by-quarter basis

"Really great" was/is my goal too. I spent a lot of time trying to get to an insanely great block syntax that actually held together, but wasn't able to come up with anything that I didn't feel had fatal flaws. It's a really hard, constrained design space.

And we're particularly constrained by the fact that there already is a quite nice syntax for calling functions and it's being used like, billions of times, by users. Any new syntax that forces them to rewrite (automatically or not) those into an entirely new notation before they get to take advantage of it is a hard sell.

I do hope we can come up with something amazing for trailing block syntax, but I just couldn't so far and eventually ran out of time. Part of the reason I lean towards the control flow element proposal is because it at least still gives us the option of trying again in the future.

yjbanov commented 6 years ago

Yeah, I don't think control flow elements are in a conflict with blocks. Totally happy if control flow elements go first and the blocks idea bake a little longer.

munificent commented 6 years ago

Yeah, I don't think control flow elements are in a conflict with blocks.

Good to hear! That's my feeling too.