Skip to content

Pre- and Post-Conditions for Pyret Functions #1882

Description

@michel-steuwer

Hi Pyret Team,

I am teaching a first-year Bachelor's CS class at TU Berlin this fall.

One of the concepts that I'd like to teach is the importance of interfaces and that a well-designed interface of every function should allow us to use the function without knowing or understanding its implementation. This way of abstraction is one of the key concepts in CS that I want to get across.

Also, with the increasing use of AI in software engineering, I think we should put more emphasis on teaching students how to write specifications (as implementations will be increasingly generated by an automatic agent).

Therefore, I'd like to propose adding explicit support for pre- and post-conditions to Pyret functions.

I have the following in mind:

fun g(n :: Number):
  doc: "Input must be odd, returns an even number"
  requires: num-modulo(n, 2) == 1
  ensures: lam(res): num-modulo(res, 2) == 0 end

  n - 1
end

I am aware that using refinements, one can currently already write:

fun is-odd(n :: Number): num-modulo(n, 2) == 1 end
fun is-even(n :: Number): num-modulo(n, 2) == 0 end
fun f(n :: Number%(is-odd)) -> Number%(is-even):
  doc: "Input must be odd, returns an even number"
  n - 1
end

However, I would like to establish the notion of pre- and post-conditions explicitly, as they will carry over nicely to many other languages (such as Python, Java, etc.) and are generally a widely understood concept. Type refinements are fancy and cool but less widely used in other languages.

I would implement this as a dynamic check. I suspect that this could be done purely by desugaring the new syntax into code that checks the precondition on entry and raises it if it is violated. Similarly, the postcondition is checked after the function exists (however it did so, without raising an exception) with the return value passed to the argument of the lam in the ensures clause.

I suspect that the feature would be orthogonal to the existing languages. Users who don't want it can ignore it.

I briefly discussed this on a call with @jpolitz today, who seemed generally positive about the idea but already pointed out that in this design the pre- and post-conditions are not part of the signature (and therefore the interface) of the function.

I would be curious to see how others from the Pyret team see this. If this is a feature that seems interesting to the Pyret language, I could give it a go at implementing a pull request.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions