p4-spec icon indicating copy to clipboard operation
p4-spec copied to clipboard

Should `...` be supported in structure-valued expressions?

Open jafingerhut opened this issue 3 years ago • 9 comments

It seems like a fairly small and useful generalization of the current language spec to explicitly allow , ... inside of a structure-valued expression (only at the end, just before the closing }). This proposal is that would be supported in structure-valued expressions, which can appear anywhere that an R-value is needed with a struct or header type.

A strict reading of the current language spec in https://p4.org/p4-spec/docs/P4-16-v1.2.2.html#sec-initializing-with-default-values only allows ... in initialization expressions, seems to imply in spec version 1.2.2 that ... is only allowed in initializations.

jafingerhut avatar Mar 07 '22 23:03 jafingerhut

This PR is for review if people believe the answer to the question raised by this issue should be "yes": https://github.com/p4lang/p4-spec/pull/1031

jafingerhut avatar Mar 08 '22 03:03 jafingerhut

This is not an easy topic. We just merged a very complex PR in the compiler which deals with such cases, often by generating errors. Consider an expression like { a = 2, ... } == { b = 3, ... }. This has an infinite number of completions; it is not clear what the missing fields are, although we can guarantee that the expression evaluates to false for any well-typed completion.

mihaibudiu avatar Mar 08 '22 05:03 mihaibudiu

Let me just provide some context here. Besides the variables that we explicitly instantiate inside parsers or controls, we also have parameters, such as hdr and meta structs. The latter almost always requires explicit initialization and, in fact, that's precisely what prompted the initial requests, because in the real data plane programs, this struct can be huge.

If we just allow these constructs as initializers, then this important case will not be covered.

vgurevich avatar Mar 08 '22 05:03 vgurevich

In a case like {a=2, ...} == {b=3, ...}, it seems reasonable to make that an error since there is no way for the compiler to determine what the type of the two structure-valued expressions should be.

If the compiler just said "These structure-valued expressions must have a (typeRef) prefix to specify their type", does that make the resulting semantics more straightforward? And is it perhaps straightforward to determine when that proposed error message can be issued? It seems to me quite reasonable if the compiler gives up if it isn't "obvious" what the types should be.

jafingerhut avatar Mar 08 '22 05:03 jafingerhut

The point I am trying to make is that we have to be careful what we put in the spec. I have also tried to implement support for something like {a = 2} == {a = 2}, and even this is tricky, because you cannot just generate an associated struct type for these expressions, since structs cannot have int fields.

mihaibudiu avatar Mar 08 '22 05:03 mihaibudiu

But yes, if the type is specified explicitly things are simpler.

mihaibudiu avatar Mar 08 '22 05:03 mihaibudiu

By the way, this is the point I made at the LDWG yesterday. Some of the options we are considering, like this one, do not specify the type of the value. And that can make things more complicated.

My comment was dismissed with a response that the compiler already handles this in type inference.

I do agree we can separate type inference from the semantics of fully-typed terms. And that's a good principle to follow. But type inference gets very tricky. And even if we settle on a conservative inference scheme, I worry the result will be unintuitive for programmers -- relatively small changes to the programs can cause the type checker to flip from accepting to rejecting a program, or vice versa.

jnfoster avatar Mar 08 '22 13:03 jnfoster

Personally, I am perfectly fine if every structure-valued expression must be preceded by an explicit (typeRef), by the way. Are all of the difficulties and issues being discussed here have a root cause that this (typeRef) is optional?

jafingerhut avatar Mar 08 '22 14:03 jafingerhut

Part of my confusion stems from the fact that the current spec for structure-valued expressions (without ... allowed inside of them) says that (typeRef) is optional. Are the concerns being raised here applicable to the current spec as written, especially this sentence in Section 8.12 "Structure-valued expressions"?

"For a structure-valued expression typeRef is the name of a struct or header type. The typeRef can be omitted if it can be inferred from context, e.g., when initializing a variable with a struct type."

jafingerhut avatar Mar 08 '22 16:03 jafingerhut

Closing this issue, since https://github.com/p4lang/p4-spec/pull/1251 was merged to address it.

jafingerhut avatar May 02 '23 15:05 jafingerhut