Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

kdashg
Copy link
Contributor

@kdashg kdashg commented Apr 14, 2020

This can improve readability and intent-communication of e.g. if (cond) break;.
This comes from my own c++ style, where brackets are generally required,
except for (keyword) branch/jump statements.
We can choose to have a language with opinionated style and embed this
reasonable requirement into the grammar.

This can improve readability and intent-communication of e.g. `if (cond) break;`.
This comes from my own c++ style, where brackets are generally required,
except for (keyword) branch/jump statements.
We can choose to have a language with opinionated style and embed this
reasonable requirement into the grammar.
@kdashg kdashg added the wgsl WebGPU Shading Language Issues label Apr 14, 2020
@kdashg
Copy link
Contributor Author

kdashg commented Apr 14, 2020

This can help with concerns raised in #643.
cc: @dneto0

@kdashg kdashg changed the title Allow e.g. if (cond) break/continue/return/kill;. Allow e.g. if (cond) break/continue/return/kill; without brackets. Apr 14, 2020
@dneto0
Copy link
Contributor

dneto0 commented Apr 15, 2020

This works for me.

@dneto0
Copy link
Contributor

dneto0 commented Apr 15, 2020

The return and kill parts of this are probably overreach.

@kvark
Copy link
Contributor

kvark commented Apr 15, 2020

I don't think we have the evidence to suggest that a grammar complication is needed.
What is the scenario we are trying to avoid, exactly, by introducing this grammar?

@kdashg
Copy link
Contributor Author

kdashg commented Apr 15, 2020

if (c) break; is really really close to break if (c);, without adding an unusual new break form.

As for kill and return, I think it makes sense to include them as control-flow keyword branches. if (cond) return; is an early-out pattern I use a lot in systems programming, at least. (kill I'm less attached to, but it fit the pattern of the group) Individual project style can (as always) forbid them if desired.

This proposal splits the difference between being opinionated/strict and flexible/expressive.

@RobinMorisset
Copy link
Contributor

Although I am not in favor of removing braces after an if as a general rule, I would be willing to accept a PR that allows it for the case where there is just a break/continue/return/kill statement in the branch.

But this is not at all what this pull request does. I see several issues with its changes to the grammar:

  • It keeps the construct "break if (foo)". So now something like "if (foo) break if (bar);" would be legal, and that looks unreadable to me.
  • It removes break/continue/return/kill from the list of normal statements, so that they can only be used inside a branch, and as the only thing inside that branch. I don't want to have to write "if (true) return x;" whenever I want to return x !
  • It refers to a keyword_stmt class which does not appear to be defined anywhere.
  • Because it modifies body_stmt it also allows a bare keyword as the only body of a function, which seems syntactically weird to me.

For each of those I'd like to know whether it is intended or just an accident.
Replacing keyword_stmt by branch_stmt would fix 2 and 3, so I think that was the original intent.

@grorg
Copy link
Contributor

grorg commented May 12, 2020

This was discussed at the 2020-05-12 meeting.

Copy link
Member

@dj2 dj2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with Robin that this should also remove the break if(); syntax so we have only one way to do it.

I'm ok with allowing this as a limited exception, but I don't want to see this used as a reason to allow things like the following for consistency:

if (a)
  i = i + 1;


body_stmt:
: BRACKET_LEFT statements BRACKET_RIGHT
| branch_stmt
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be too general as this makes it grammatically correct to say

fn foo() -> f32
   return 2.3;

Seems like we should have an if_body_stmt and then we need to update the if section so you can't do something like:

if (a)
  break;
else if (b)
  continue;
else
 kill;

as I don't think that should be allowed?

@kvark
Copy link
Contributor

kvark commented May 19, 2020

There is a loophole in this approach:

bool my_crazy_function() {
 // do crazy uniform-restricted things
}
...
if (break_condition) return my_crazy_function();

Unless we have special rules for the return expressions in the uniform control flow analysis, the expression has to adhere to the same restrictions as anything else in a if (break_condition) { block of code } block.

I could see 3 solutions to this:

  • restrict if (...) return to a limited form, without general expressions
  • modify the uniform control flow analysis (unless it already treats return conditions specifically?)
  • always require braces for if {}

@pow2clk
Copy link

pow2clk commented May 20, 2020

I expressed concern regarding this change for the dangling-else problem. I wanted to look into it further to convince myself it was or was not an issue. As I read the grammar, I see that this change introduces no way to follow an if (cond) with another if(cond2) without including a bracket which would prevent any ambiguity.

I think @dj2 makes a good point that this would introduce a rather strange function definition. As such, I'd support the introduction of if_body_stmt as a fairly minor alteration to this change. I confess that either way, as it stands, I don't think the concern I raised should be the driving force to prevent this limited alteration.

Apologies if I came on too strong earlier. Nevertheless, I feel this additional consideration has been beneficial.

@grorg
Copy link
Contributor

grorg commented Jun 2, 2020

Discussed at the 2020-06-02 meeting.

@kvark kvark changed the base branch from master to main June 23, 2020 13:15
@grorg
Copy link
Contributor

grorg commented Sep 29, 2020

Discussed at the 2020-09-29 meeting.

@litherum
Copy link
Contributor

With required braces, the dangling else problem is naturally solved. We should not make a change which creates the dangling else problem.

Also, consider something like

if (foo)
    /* take an early out! */
    break;

This code is unclear.

@kdashg
Copy link
Contributor Author

kdashg commented Nov 3, 2020

I believe this PR does not have a dangling-else problem, as you cannot write if (foo) if (bar) else. According to Wikipedia's Dangling Else article, this sort of functionally similar to how ALGOL 60 avoids this issue.

Possible solutions are:

  • [...]
  • Disallowing the statement following a "then" to be an "if" itself (it may however be a pair of statement brackets containing only an if-then-clause). This approach is followed by ALGOL 60.

Allowed:

if (foo) {
  if (bar) return -1;
  else return 1;
}

if (foo) {
  if (bar) return -1;
  else {
    return i + 1;
  }
}
if (foo) {
  if (bar) {
    return -1;
  } else return i + 1;
}

if (foo)
  // early out
  return -1;

@grorg
Copy link
Contributor

grorg commented Dec 8, 2020

Discussed at the 2020-12-08 meeting.

Resolution: Land this as is unless people speak up by next week.

@kvark
Copy link
Contributor

kvark commented Dec 8, 2020

We discussed this for a long time, and I think the discussion has evolved a bit.
On the last call this was positioned as a convenience feature (quality of life).
My concern with this is still - that it's not necessary, it can be added after MVP, and it's highly controversial in existing languages like C++.

Edit: the de-factor standard C++ code formatter - Clang-tidy - has a rule "readability-braces-around-statements" specifically to handle that, and it's enabled by default. Mozilla's ./mach static-analysis also warns about it.

@Diggsey
Copy link

Diggsey commented Dec 8, 2020

It seems like WGSL syntax is heavily inspired by Rust, which has managed to get by just fine without such syntax. Adding this has the downside of precluding other possible syntax extensions, and it also introduces unnecessary special-cases into the grammar (in order to avoid the dangling-else problem).

You need only look at Javascript to see the problems with adding too much syntax too quickly. It is much better to start with a simpler grammar, and extend it later with sugar and "nice to haves" once you have a body of real code against which you can evaluate the benefit of any potential additions.

@dj2
Copy link
Member

dj2 commented Dec 10, 2020

Thinking about this some more, I think it falls into the bucket of "we can't undo this later, but we can add it later". The change itself is simple enough, but it isn't strictly adding anything that can't be done without it and being in the can't undo bucket, I think we should punt this to post MVP.

@kdashg
Copy link
Contributor Author

kdashg commented Dec 18, 2020

We discussed this for a long time, and I think the discussion has evolved a bit.
On the last call this was positioned as a convenience feature (quality of life).
My concern with this is still - that it's not necessary, it can be added after MVP, and it's highly controversial in existing languages like C++.

Edit: the de-factor standard C++ code formatter - Clang-tidy - has a rule "readability-braces-around-statements" specifically to handle that, and it's enabled by default. Mozilla's ./mach static-analysis also warns about it.

FWIW, unsurprisingly I have fought to get this warning disabled for certain directories in Gecko, where the prevailing style embraces succinct braceless early-outs. I feel relatively strongly about this requirement being overly restrictive and generally supported merely via personal opinions and strawman arguments like goto-fail.

I know we all have opinions here, but this isn't a choice between how your code will be written, but rather whether one camp's code style is allowed to be written at all. The most equitable thing is to support both camps, absent anything particularly onerous.

I don't think we will have more data here unless we allow this for MVP and check if people use it. This is a minor enough papercut that people (me) will grumble when writing it, but it won't end up on any powerpoint slides about pain-points. However, it seems easy enough to spec and support, and @dneto0 and I are already extant users requesting it for two different reasons.

I propose we take this now, and if we run into any onerous aspects here, we can remove it before v1.

@Diggsey
Copy link

Diggsey commented Dec 18, 2020

this isn't a choice between how your code will be written, but rather whether one camp's code style is allowed to be written at all.

It's not really a style question if it doesn't exist in the language to begin with. Perhaps it should be possible to omit brackets entirely and use indentation to delimit blocks: that's required in python after all.

The problem with this argument is that WGSL is not python, or C++, or any other language.

I propose we take this now, and if we run into any onerous aspects here, we can remove it before v1.

Adding every possible feature and then removing them later is a bad way to design a language and invites code breakage for no benefit.

@kdashg
Copy link
Contributor Author

kdashg commented Dec 18, 2020

We are at the stage of language development where we are deciding what styles are and aren't allowed, and this is exactly that sort of style question.

I agree that we should not add literally everything, but I've made my case that this makes the cut.

@kdashg
Copy link
Contributor Author

kdashg commented Dec 18, 2020

Specifically, at this point there has been consensus that this is tolerable, spec-able, and implementable, so I'm looking for any arguments that it's onerous or unduly risky such that we should not proceed with the consensus that we have already reached, even if it was a weak consensus.

@Diggsey
Copy link

Diggsey commented Dec 18, 2020

We are at the stage of language development where we are deciding what styles are and aren't allowed, and this is exactly that sort of style question.

From what I've seen, most of the spec is fairly minimalist and driven from an actual need. For example, clearly you need some way in the language to manage control flow, therefore you need if, while, etc. You don't need two ways to write an if statement.

I agree that we should not add literally everything, but I've made my case that this makes the cut.

All you said is that you feel strongly about it, and that it's possible to implement. I don't doubt either of those things, but the same argument applies to almost everything.

Significant whitespace is clearly possible to implement since python has it, and I guarantee there exist people who feel strongly about that (having encountered several wanting to add this feature to Rust and C++).

The barrier to entry for new features, especially early on like this should be far higher than a personal preference.

@kdashg
Copy link
Contributor Author

kdashg commented Jan 12, 2021

Given that we don't need this now, there's rough consensus that we probably want to hold off on it for now, but that we can add it later. Maybe people will express positive interest in it, or maybe we'll just feel like adding it, but we're inundated with work right now and this is probably low priority.

@kdashg
Copy link
Contributor Author

kdashg commented Jan 12, 2021

Fwiw @Diggsey I don't think this has the same bar as other sophisticated "new features", as it's ultimately a minor quality-of-life improvement, while also being fairly trivial to implement.
With my API design hat on, this is something that I think is valuable, I just also happen to be a vocal user who's asking for it.

@Kangz
Copy link
Contributor

Kangz commented Mar 21, 2022

@kdashg I think this PR could be closed since WGSL now supports paren-less control flow, which means conflicts with bracket-less control flow. (though we could allow control flow to be either of bracket-less or paren-less, but ew?)

@kainino0x kainino0x closed this Aug 25, 2022
ben-clayton pushed a commit to ben-clayton/gpuweb that referenced this pull request Sep 6, 2022
* api,validation,state,device_mismatched plan

- Add validation test plan for one device using objects from another
  device in all APIs where an object is passed.
- Split tests to each API file.
- The APIs and Objects include:
  - GPUDevice:
    createPipelineLayout with BGLs
    createBindGroup with {BGL, BindResource(buffer,sampler,texture,etc.)}
    createComputePipeline(Async) with {PipelineLayout, ShaderModule}
    createRenderPipeline(Async) with {PipelineLayout, ShaderModule}
  - GPUCommandEncoder:
    beginRenderPass with {Texture views in attachments, OcclusionQuerySet}
    copyBufferToBuffer with Buffers
    copyBufferToTexture/copyTextureToBuffer with {Buffer, Texture} (test in image_copy/)
    copyTextureToTexture with Textures
    writeTimestamp/resolveQuerySet with QuerySet
  - GPUProgrammablePassEncoder
    setBindGroup {with, without} Uint32Array with BindGroup
    x = {compute pass, render pass, render bundle}
  - GPUComputePassEncoder
    setPipeline with ComputePipeline
    beginPipelineStatisticsQuery/writeTimestamp with QuerySet
  - GPURenderEncoderBase
    setPipeline with RenderPipeline
    setIndexBuffer/setVertexBuffer with Buffer
    drawIndirect/drawIndexedIndirect with Buffer
    beginPipelineStatisticsQuery/writeTimestamp with QuerySet
    x = {render pass, render bundle}
  - GPURenderPassEncoder
    executeBundles with RenderBundles
  - GPUQueue
    submit with CommandBuffers
    writeBuffer with Buffer
    writeTexture with Texture (test in image_copy/)
    copyExternalImageToTexture with Texture

* Address comments

* Update src/webgpu/api/validation/encoding/cmds/setBindGroup.spec.ts

Co-authored-by: Kai Ninomiya <[email protected]>

* Update src/webgpu/api/validation/encoding/queries/general.spec.ts

Co-authored-by: Kai Ninomiya <[email protected]>

* Update src/webgpu/api/validation/queue/submit.spec.ts

Co-authored-by: Kai Ninomiya <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal wgsl WebGPU Shading Language Issues
Projects
None yet
Development

Successfully merging this pull request may close these issues.