Skip to content
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

overeager typechecking of generic types. #5067

Open
ChrisDodd opened this issue Dec 16, 2024 · 3 comments
Open

overeager typechecking of generic types. #5067

ChrisDodd opened this issue Dec 16, 2024 · 3 comments
Labels
p4-spec Topics related to the P4 specification (https://github.com/p4lang/p4-spec/).

Comments

@ChrisDodd
Copy link
Contributor

Consider the following program with a generic function (minor change of testdata/p4_16_samples/function.p4):

T max<T>(in T left, in T right) {
    if (left > right)
        return left;
    return right;
}

control c(out bit<16> b) {
    apply {
        b = max(16w10, 16w12);
    }
}

control ctr(out bit<16> b);
package top(ctr _c);

top(c()) main;

It fails with error message

function2.p4(2): [--Werror=type-error] error: left > right: not defined on T and T
    if (left > right)
        ^^^^^^^^^^^^

However, it would seem to be ok, as the max function is only ever instantiated with bit<16> for T, which should be ok. If you replace the explicitly typed constants as max(10, 12), you get even more errors, even though that should be ok too.

@vlstill
Copy link
Contributor

vlstill commented Dec 16, 2024

However, it would seem to be ok, as the max function is only ever instantiated with bit<16> for T, which should be ok.

Yes, but that would require instantiating the function first, and only then type checking it (like C++ templates). Instead, the P4 function has to type check for the generic types, and there are essentially no allowed operations on values of generic type.

I believe the P4 inliner also needs types to inline functions.


Usually, there are 2 approaches that programming languages with parametric polymorphism (type parameters) take:

  • Type check functions separately, with the generic types. This usually requires some system of constraints for generic types, that declare that only generic types that implement certain operations (or inherit from certain base interface) can use used in the given generic function. The type checker can then completely typecheck the function based on these requirements.

  • Type check functions only in the context of their calls, with the concrete types. C++ templates are probably the most prominent examples, with all the power and trouble (and compiler complexity) that brings. This also means that the same line can type check once, and then fail to type check for another invocation.

Certainly it would be useful to have ability to write a function like the max that you have written. I would suggest P4 should go the first direction, and we should get some way to specify sets of supported operations on types. But certainly this is a topic for language design first.

@asl
Copy link
Contributor

asl commented Dec 16, 2024

  • Type check functions only in the context of their calls, with the concrete types. C++ templates are probably the most prominent examples, with all the power and trouble (and compiler complexity) that brings. This also means that the same line can type check once, and then fail to type check for another invocation.

Actually, modern compilers do some semantic checks on uninstantiated templates. The C++ standard even requires this up to some extent (the code in the template is required to be semantically correct, so it should for example, reference undeclared functions). This often causes troubles with legacy code since the uninstantiated templates might stop compile :)

@jafingerhut
Copy link
Contributor

Usually, there are 2 approaches that programming languages with parametric polymorphism (type parameters) take:

  • Type check functions separately, with the generic types. This usually requires some system of constraints for generic types, that declare that only generic types that implement certain operations (or inherit from certain base interface) can use used in the given generic function. The type checker can then completely typecheck the function based on these requirements.
  • Type check functions only in the context of their calls, with the concrete types. C++ templates are probably the most prominent examples, with all the power and trouble (and compiler complexity) that brings. This also means that the same line can type check once, and then fail to type check for another invocation.

Certainly it would be useful to have ability to write a function like the max that you have written. I would suggest P4 should go the first direction, and we should get some way to specify sets of supported operations on types. But certainly this is a topic for language design first.

FYI, there have been discussions in the P4 language design work group in past years regarding whether P4 the language, and/or p4c the implementation, should do one of those or the other.

Me, I personally kind of like the flexibility that "expand, then type check" gives the P4 developer. It seems to me it would easily allow a parser or control to be written with constructor parameters that could be used as bitwidths of bit<W> types, among other things (maybe that is already possible today, and I just haven't checked in a long time, with p4c).

I do not want to incorrectly put words in the mouths of others, but if I recall correctly I believe at least Nate Foster, and perhaps some others, are more in favor of the "type check everything before inlining/expanding" approach.

I do not recall all the pros vs. cons of these two approaches, but if someone wanted to create such a list, I'd be happy to review and add anything I thought of, to the list.

@fruffy fruffy added the p4-spec Topics related to the P4 specification (https://github.com/p4lang/p4-spec/). label Dec 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
p4-spec Topics related to the P4 specification (https://github.com/p4lang/p4-spec/).
Projects
None yet
Development

No branches or pull requests

5 participants