Thunks and Streams Assignment

From CSE425S Wiki
Jump to navigation Jump to search

Motivation

It is all too easy to make a simple mistake on the Streams Lab and have it burn way to much of ones time. We will build some utility functions that will hopefully make our code more clear, as well as raise better errors sooner when we make a mistake.

Code To Use

Code To Implement

file: src/main/racket/hw4/hw4.rkt Racket-logo.svg
functions: thunk?
thunk-that
dethunk-that
value-next-stream-pair-from-stream
stream-cons-ensuring-stream-prime-is-thunk

Thunk Utilities

A thunk is a 0 argument function. We will write functions to check if an expression is a thunk, a MACRO to create a thunk from an expression, and a function to evaluate a thunk.

thunk?

define a function thunk? which returns whether the specified parameter is a thunk or not.

(define (thunk? th)
    (error 'not-yet-implemented))

thunk-that

define a MACRO thunk-that which takes a parameter e creates thunk. that is: wraps e in a zero argument function.

(define-syntax-rule (thunk-that e)
   (error 'not-yet-implemented))

Thunks are useful for delaying the evaluation of expressions. As such thunk-that must be declared as a macro and not a function. Unlike Haskell which has lazy evaluation, Racket (and most other languages) eagerly evaluates function arguments.

dethunk-that

define a function dethunk which takes a thunk parameter e and returns the result of invoking e.

(define (dethunk-that e)
   (error 'not-yet-implemented))

If thunking and expression wraps an expression in a single argument function, then de-thunking is simply calling that function.

NOTE: It may seem unnecessary to use dethunk-that when implementing Lab4, when you could simply (thunk)... that is "call the thunk". Still, you are encouraged to use dethunk-that as a bit of verbosity can sometimes help in debugging a sea already full of parentheses.

Stream Utilities

value-next-stream-pair-from-stream

define a function value-next-stream-pair-from-stream which takes a stream parameter and returns two values for the next value and the next stream.

(define (value-next-stream-pair-from-stream s)
   (error 'not-yet-implemented))

A critical value of this utility function is to provide early error detection. As such, exceptions should be raised if either the parameter s is not a thunk (upon entering) and if the next stream is not thunk (before leaving).

next-value-from-stream

provided function next-value-from-stream which takes a stream parameter and returns the next value of that stream.

(define (value-from-stream s)
 (let-values ([(value s-prime) (value-next-stream-pair-from-stream s)])
   value))

next-stream-from-stream

provided function next-stream-from-stream which takes a stream parameter and returns the next stream of that stream.

(define (next-stream-from-stream s)
 (let-values ([(value s-prime) (value-next-stream-pair-from-stream s)])
   s-prime))

stream-cons-ensuring-stream-prime-is-thunk

Define a function stream-cons-ensuring-stream-prime-is-thunk which takes two parameters value and s-prime.

(define (stream-cons-ensuring-stream-prime-is-thunk value s-prime)
  (error 'not-yet-implemented))

If the specified s-prime parameter is not a thunk then an error should be raised:

(raise (error "not a thunk" stream-prime))

If s-prime is a thunk it should simply cons value and s-prime. Do NOT create a thunk.