-
Notifications
You must be signed in to change notification settings - Fork 696
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Text format: type more operations #408
Comments
One subtle difference is that |
I agree that it's known from the function's context, but it's not clear that's particularly useful. When types were added the reasoning was that it made things easier to understand for developers, and I think the same applies for |
The original motivations had more to do with the predicted simplicity of implementation and interactions with binary format which I think are the higher priority. There are still some big pending choices to be made about the binary format (e.g., type-segregated opcode spaces, module-local opcode tables) so it's hard to really evaluate this atm. What is "easiest to understand for developers" sounds like a bikeshedfest since I don't think any of these options will significantly move the dial on overall understandability; for that you want source info. |
I'm only concerned with the textual format on this. It seems easier to read IMO, since it's consistent. |
Why are you singling out `return`? You could make the same argument for
`call`, `get_local`, `if`, or virtually any control operator. So it's not
clear to me what notion of consistency you have in mind.
Generally speaking, the fundamental difference between these and arithmetic
operators is as follows: arithmetic operators have a different semantics
for different types. Consequently, you want to be explicit about indexing
them with a type, because it selects an actual behaviour. That is not the
case for control operators or ones like `get_local` -- these are fully
_parametric_ in their types, i.e., the type does not affect their
behaviour. Consequently, there is no reason to include it.
Note also that putting types on `return` or other control operators
wouldn't easily scale to multiple values.
|
Ignoring control constructs,
It's subjective, but it seems like a win to me. The purpose of the S-expression syntax is to be explicit and easy to process with simple tools. Thoughts? |
I suppose my question would be the same: why single out that one? How are, say, calls any different? How does it help a simple consumer to have annotations on some but not the others? |
I temporarily excluded calls, returns, and other control constructs because I'm wondering if we shouldn't address those at a higher level. I've been thinking about a stack abstraction rather than having values as operands of returns and so on. We'd of course restrict the number and types of things on the stack, and we still have structured control flow, so it'd still be easily statically type-checkable and verifiable, but it'd simplify several things. For example, since the current thinking for multiple result values is It's just an idea at this point, but it is something I'm thinking about. |
Yeah, I think that Anyway, probably getting off-topic. |
Ok, so putting control constructs aside for the moment, should we add types to |
I'm singling out |
A parser of the s-expr language is already going to need to maintain a static function context (to resolve |
Catching type mistakes was one of the justifications to type operations in the first place. Can't use the same reason both ways ;-) I agree that for a parser this doesn't do much. I'm approaching this from the POV of someone who would read or write this wasm assembly, the consistency seems nicer to me (having just written some examples by hand). |
As I argued above, the fundamental difference is that (1) the types don't affect the operational meaning of these operators, so they are redundant information, and (2) they (or some of them) are not conceptually limited to a (finite) set of primitive types, but may eventually evolve to handle user-defined types or multiple values, which don't fit the limited format. |
@jfbastien Someone may have used that argument, but I actually don't think "catching (static) errors" should be a design goal (and it may actively work against other goals). Simplicity of spec, impl and codegen; this is what I think we should design for and I don't see |
I agree with @lukewagner regarding locals; verifying the AST requires a On Wed, Oct 14, 2015 at 10:17 AM, Luke Wagner notifications@github.com
|
I understand that the type isn't strictly required, that's not the reasoning I offered: I'm approaching this purely from the POV of reading / writing the textual format. I agree that multi-returns or UDTs would require expanding the signature, but that's true of the semantics of the entire text format. It's pretty easy to spec properly. The argument on "arithmetic needs the disambiguation, In fact, type does affect the semantics of multi-value |
If the text format is the extent of your concerns, it seems like we should table this discussion until we start defining the text format. |
IMO the text format should be made to contain the same information as the binary format does, unless there is a really good reason not to, so that the text format gives users some intuition about how the binary format works. Also, if I'm writing Wasm code, I don't want to write information that the assembler will immediately throw away. |
It sounds like the consensus is: redundant type checks aren't a design goal of the text format? |
Yes, I think so. I'd say the design goal is for the text format to contain the same amount of information as the binary format will (modulo naming things). |
On 14 October 2015 at 22:53, JF Bastien notifications@github.com wrote:
|
I agree that there's inconsistency here, but right now it's just in the S-expression format. We can talk about whether the text format the same amount of information as the binary format when we're designing a real text and binary format :-). |
Just a note: I realized that another specific example of what Andreas was mentioning above is the "opaque reference type" idea mentioned in GC.md: the only operations you'd be able to perform on these opaque types are precisely the ops like |
Why isn't
return
typed, e.g.i32.return
?I get that the type is implicit because of the function's signature, but where are we drawing the line on consistency?
i32.add
is typed because that allows us to ignore the operand subtree's expression.Should other operations be typed?
get_local
?break
?What about if type=expressions? Shouldn't all typed operations have an explicit type?
The text was updated successfully, but these errors were encountered: