Search code examples
rakudesign-by-contract

Does Perl 6 natively support Design by Contract?


It is listed as a language with native DbC support on the Wikipedia beside Eiffel and Spec#, but I can't find any mention whatsoever in the docs or in the test suite.


Solution

  • 2019 Update

    Imo, no.

    Because I don't think 6.d "implements most DbC features natively" for a reasonable definition of "most" I've removed it from the Wikipedia Design by Contract page.

    (If you think it should be put back in the native section despite this SO and my notes above and below, please make sure it appears in alphabetical order.)

    I think:

    • P6 has raw materials that should be reusable to "implement most of DbC".

    • A natural start would be a userland module. (Which would then naturally fit on the Wikipedia page, but in the Languages with third-party support section).)

    A sketch of what I'm thinking follows.

    1. ORing preconditions and ANDing postconditions/invariants in the context of routine composition/inheritance/delegation:

    • Implementing a way to dynamically call (or perhaps just statically refer to) just the PRE statements/blocks and, separately, just the POST statements/blocks, of "relevant ancestor" routines.

    • Determining "relevant ancestors". For a class hierarchy (or object delegation chain) that doesn't involve multiple dispatch, "relevant ancestors" is presumably easy to determine based on the callsame mechanism. But it feels very different in the general case where there can be many "competing" candidates based on the very different paradigm of multiple dispatch. Are they all "relevant ancestors", such that it's appropriate to combine all their PRE and POST conditions? I currently think not.

    • Modifying routine selection/dispatch. See eg OO::Actors for what might be a template for how to do so most performantly. The goal is that, per DbC rules, the PRE statements/blocks of a winning routine and its "relevant ancestors" are logically ORed together and POST statements/blocks are logically ANDed.

    • Supporting class level PRE and POST blocks. One can already write PRE and POST blocks in a class, but they are associated with construction of the class, not subsequent calls to methods within the class. For the latter the following S04 speculation seems to be the ticket:

    It is conjectured that PRE and POST submethods in a class could be made to run as if they were phasers in any public method of the class. This feature is awaiting further exploration by means of a ClassHOW extension.

    Original answer

    Check out Block Phasers, in particular the PRE and POST phasers. I haven't used them, and it's something like 25 years since I read the Eiffel book, but they look the part to me.

    The PRE and POST phasers are tested in S04-phasers/pre-post.t. I see at least one bug TODO.

    It would be wonderful if you would check out the doc, experiment with them (maybe using an online P6 evaluator), and report back so we can see what you think of them, hear if you encountered the TODO'd bug or any others, and decide what to do:

    • The Wikipedia page says it lists "Languages that implement most DbC features natively". Presumably the "most" qualifier is subjective. Does P6 implement all (or "most") DbC features natively? If not, it presumably needs to be removed from the Wikipedia page.

    • Unless we decide the P6 does DbC claim is bogus, we presumably need to add 'DbC' and 'Design by Contract' into the doc and doc index. (Presumably you searched for one or both of those, didn't find a match, and that's what led you to think you couldn't find them, right?)

    • We also need examples for PRE and POST regardless of whether or not they're officially considered to be DbC features. But we already know that in the sense that P6 has power out the wazoo and much of it still isn't documented as part of official p6doc despite many folk contributing. There's a lot to do! If you can come up with a couple really nice, simple examples using PRE and POST, perhaps developed from what you see in the roast tests, that would be spectacular. :)