views:

158

answers:

2

I'm revising for an upcoming Haskell exam and I don't understand one of the questions on a past paper. Google turns up nothing useful

fst(x, y) = x
square i = i * i

i) Source reduce, using Haskells lazy evaluation, the expression:

fst(square(3+4), square 8)

ii) Source reduce, using strict evaluation, the same expression

iii) State one advantage of lazy evaluation and one advantage of strict evaluation

What I don't understand is what is source reduction?

+7  A: 

From the structure of the question, it probably just mean "evaluate the expression by hand", e.g.

head (map primeTest (enumFromTo 1000 2000))

in lazy (evaluate only when needed) evaluation,

  head (map primeTest (enumFromTo 1000 2000))
= head (map primeTest (1000 : enumFromTo 1001 2000))
= head (primeTest 1000 : map primeTest (enumFromTo 1001 2000))
= primeTest 1000
= False

in strict (evaluate everything first) evaluation

  head (map primeTest (enumFromTo 1000 2000))
= head (map primeTest (1000 : enumFromTo 1001 2000))
= ...
= head (map primeTest [1000, 1001, ..., 2000])
= head (primeTest 1000 : map primeTest [1001, 1002, ..., 2000])
= head (False : map primeTest [1001, 1002, ..., 2000])
= ...
= head [False, False, ..., False]
= False

The only relevant place I could find is http://www.cs.bham.ac.uk/internal/modules/2009/11582.html where "source reducation" is listed as a "Programming technique". (O_O)

KennyTM
I wish he'd just say that in the paper, "evaluate this" would have made a lot more sense!
Martin
@The notes you found: I study CS at Birmingham, those are the notes for the module I took. I do love lecturers who just make things up.
Martin
+8  A: 

Reduction is a term from the lambda calculus which involves a semantics-preserving transformation that replaces one term with an equivalent term. For the examples you've given, the most important kind of reductions are

  • Replacement of a name by its definition (an instance of substituting equals for equals).
  • Beta-reduction of a function application.

Beta-reduction is the fundamental rule in the lambda calculus, and in a pure, lazy language like Haskell, it always preserves semantics. The beta rule is the one that says:

(\x. e) m

can be replaced by e with m substituted for x. (The substitution must avoid "capturing" free instances of x in m.)

It's quite possible that your instructor wants you to combine reductions as follows:

  1. Find a function application where the function being applied is a name.
  2. Replace the name with its definition, which will be a lambda abstraction.
  3. Beta-reduce the application.
  4. Do this all in one step.

Notice you often have a choice about which application to reduce; for example, in the term you give, there are two applications of square and one of fst that could be reduced in this fashion. (The application of + can also be reduced, but reduction involving constants requires different rules.)

From the questions I see that your instructor wants you to reduce each term repeatedly until it reaches a normal form and that your instructor wants you to demonstrate your understanding of different reduction strategies. The word "source" in "source reduce" is superfluous; reduction means manipulation of source terms in some language. I would have phrased the questions as follows:

  • Using the reduction strategy that corresponds to Haskell's lazy evaluation, reduce the following expression to weak head normal form. Show each step in the sequence of reductions.

  • Using the reduction strategy that corresponds to evaluation in a strict functional language, reduce the following expression to head normal form.

I probably would have chosen to be less coy and just name the reduction strategies: a call-by-need reduction strategy and a call-by-value reduction strategy.

Norman Ramsey