Class summary:   Introduction to Functions
1 Repeated Computations:   Flags Example
2 Defining Your Own Functions

Class summary: Introduction to Functions

Copyright (c) 2017 Kathi Fisler

This material goes with From Repeated Expressions to Functions from the textbook

1 Repeated Computations: Flags Example

Consider programs to draw the flags of Armenia and Austria. These two countries have the same flag, just with different colors:

  armenia =

    frame(

      above(rectangle(120, 30, "solid", "red"),

        above(rectangle(120, 30, "solid", "blue"),

          rectangle(120, 30, "solid", "orange"))))

  

  austria =

    frame(

      above(rectangle(120, 30, "solid", "red"),

        above(rectangle(120, 30, "solid", "white"),

          rectangle(120, 30, "solid", "red"))))

Rather than write this code twice, it would be nice to write the common code only once, then just change the colors to generate each flag. With what we’ve learned so far, we might do this as follows:

  top = "red"

  middle = "blue"

  bot = "orange"

  

  flag=

    frame(

      above(rectangle(120, 30, "solid", top),

        above(rectangle(120, 30, "solid", middle),

          rectangle(120, 30, "solid", bot))))

This is unsatisfying, however – what if we were trying to create an image that included both flags at the same time? We can only put one defintion of each color in the Pyret dictionary, so there is no way to change the colors to generate another flag within the same run of the program.

Wouldn’t it be nice to be able to do something similar for the flags? It would be nice to just write the following:

  armenia = three-stripe-flag("red", "blue", "orange")

  austria = three-stripe-flag("red", "white", "red")

This is precisely what you are about to learn how to do. You are going to learn how to add your own operators to Pyret.

2 Defining Your Own Functions

(See the textbook for details on what a function is – what follows is just summarizing the code from class)

Here is

  fun three-stripe-flag(top, middle, bot):

    doc: "produce image of flag with three equal-sized horizontal stripes"

    frame(

      above(rectangle(120, 30, "solid", top),

        above(rectangle(120, 30, "solid", middle),

          rectangle(120, 30, "solid", bot))))

  end

With this, the two desired flag expressions work fine.

What if we make a mistake, and try to use the function as follows:

  three-stripe-flag(50, "blue", "red")

What do you think should happen? 50 is not a string (much less a string naming a color). Pyret will give an error on one of the rectangle commands (we’ll see which one in particular in a little while). The point is that the error comes up inside the computation that creates the flag.

It would be much more helpful if we got the error when we tried to use three-stripe-flag. We can annotate the inputs with types telling Pyret what kind of data the function expects to receive:

  fun three-stripe-flag(top-color :: String, mid-color :: String, bot-color :: String):

    doc: "produce image of flag with three equal-sized horizontal stripes"

    frame(

      above(rectangle(120, 30, "solid", top-color),

        above(rectangle(120, 30, "solid", mid-color),

          rectangle(120, 30, "solid", bot-color))))

  end

If you try the erroneous call again, you’ll see that the location where the error is reported has changed.