Skip to main content

Day 15 - Variables and loops

Skills: 3

Pre-reading: 9.1.8.5 (except 9.1.8.5.4)

Intro (15 mins)

  • To Design our own list processing functions, we need a way to do computations for each element in the list. There are multiple ways to do that, today we will show iteration with for each().
  • This requires being able to modify variables, which in Pyret means they must be declared with var, and must be updated with the special operator :=.
  • The pattern is:
    var my-var = initial-value
    for each(my-elt from my-list):
    code
    to
    handle
    my-elt
    and update
    my-var
    end
    my-var # final result
  • Example: while sum is built in, we could have Designd it ourselves as:
    fun my-sum(num-list :: List<Number>) -> Number block:
    var total = 0
    for each(n from num-list):
    total := total + n
    end
    total
    where:
    my-sum([list: 0, 1, 2, 3]) is 6
    end
  • Note that any function that has multiple expressions (aside from definitions), as my-sum does (the for each loop and the total variable at the end) must be declared as a block; otherwise Pyret signals an error, given that unless the first expression changes something, it will be ignored, and thus is possible an indication of a mistake. e.g., if I write:
    fun my-fun(x :: Number):
    1 + x
    2
    end
    Because I accidentally hit the Return key instead of the + (intending the body to be 1 + x + 2), if Pyret accepted this, the function would always return 2, ignoring the 1 + x entirely. If I truely wanted that behavior, I would need to add block, as:
    fun my-fun(x :: Number) block:
    1 + x
    2
    end
    Which conveys to Pyret that I expect their to be multiple expressions, with only the last one returned. In this case, it is pointless, but if the earlier expressions (as in my-sum) modify the variable that is to be returned, this makes sense.

Class Exercises (40 mins)

  • Design your own product function that takes a list of numbers and returns their product (multiply all of them together).
  • Design a function sum-even-numbers that takes a list of integers and adds up only the even numbers -- the rest should be ignored (num-modulo may be helpful)!
  • Design a function my-length that takes a list of any value and returns the number of elements in the list.
  • Design a function any-negative that takes a list of numbers and returns true if there is at least one negative number in the list, false otherwise.
  • Design a function all-short-words that takes a list of strings and returns true if every word has 4 or fewer characters, false otherwise.
  • Design a function reverse-list that takes a list and returns a new list with all the elements in reverse order. You'll need to build up the result by adding each element to the front of your accumulator list.
  • Design a function concat-all that takes a list of strings and concatenates them all together into one string (with no separator between them).

Wrap-up (5 mins)

  • Mutable variables can be declared with var and updated with :=.
  • for each can run code for each element of a list; combined with mutable variables, this allows writing custom list operations.