indianhottie
indianhottie

Reputation: 323

Racket - lang plai - define-type and type-case explanations

Can someone try and explain these two functions: "define-type" and "type-case" in the PLAI scheme in racket? I'm a noob programmer and I don't really understand the documentation on the racket website. If anyone could provide examples, it would greatly be appreciated. Thanks.

Upvotes: 3

Views: 2954

Answers (2)

Nebu Pookins
Nebu Pookins

Reputation: 83

I'm not super experienced with Lisp/Scheme/Racket, but it looks like this question is still unanswered after 5 years, so I'll give it a shot.

First of all, note that not everything is a function. For example, when you use define to define a function or some other value, define is not acting as a function. A function is something that takes some input, and then returns some output. define does not do this. Instead, it changes the environment that you're programming in such a way that a new name exists that can be used to refer to some value.

So for example, in...

(define cadr
  (lambda (x)
    (car (cdr x))))

... define modifies the programing environment so that the function cadr now exists. cadr is a function (if you invoke it with some input, it will yield some output), but define itself is not a function (you're not invoking define with some input in order to get some output).

With that distinction hopefully cleared up, define-type is not a function. It is similar to define in that it modifies the programming environment to make it so that you have new names to refer to certain values. It is used to define a new type, along with some functions the allow you to work with that type.

An example taken from the Racket documentation:

> (define-type Shape
    [circle (radius : number)]
    [rectangle (width : number)
               (height : number)])

> (define (area [s : Shape])
    (type-case Shape s
      [circle (r) (* (* r r) 3.14)]
      [rectangle (w h) (* w h)]))

> (area (circle 1))
- number
3.14

> (area (rectangle 2 3))
- number
6

Here it defines a new type Shape which it says has two variants: circle and rectangle. It further says that in the case of the circle variant, the interesting piece of data is its radius, which is a number; and in the rectangle variant, there's two pieces of data (or "fields"), which are its width and height (both numbers).

It then defines a new function area, which is expected to take a single input of type Shape (the type we just declared earlier). The type-case expression is used to specify how to compute the area of a Shape depending on which variant we're dealing with. If we're dealing with a circle then we can compute the area by squaring the radius and multiplying it by Pi. If we're dealing with a rectangle, then we can compute the area by multiplying its width by its height.

Earlier, I said define-type is not a function, but by virtue of using it, it defines a new type and a bunch of functions that allow us to work with that type. So what are these new functions it defines? See this example:

> (define c (circle 10))

> c
- Shape
(circle 10)

> (circle? c)
- boolean
#t

> (circle-radius c)
- number
10

> (define r (rectangle 2 3))

> (+ (rectangle-width r) (rectangle-height r))
- number
5

Here we then use define to modify the programming environment so that the name c refers to a circle we created with radius 10. circle? is a function that automatically got created when we did the define-type in the earlier example, and it returns whether or not the shape we're dealing with is a circle variant (as opposed to a rectangle variant). Similar, the circle-radius, rectangle-width and rectangle-height functions were automatically defined for us when we used define-type, which allow us to access the fields inside of the data type.

Upvotes: 2

soegaard
soegaard

Reputation: 31145

Here is a little example of how to use define-type and type-case:

#lang plai

; A ListOfNumbers are either
; is either an empty list of numbers
; or is constructed to two things a, and, d,
; where a is a number and d is a list of numbers.

(define-type ListOfNumbers
  (Empty)
  (Cons (a number?) (d ListOfNumbers?)))

; construct a list of numbers as an example
(define a-list (Cons 42 (Cons 43 (Empty))))    
a-list   ; prints: (Cons 42 (Cons 43 (Empty)))

(type-case ListOfNumbers a-list
  (Empty ()     "the list is empty")
  (Cons (a d)  (~a "the first number in the list is " a)))
; prints: "the first number in the list is 42"

Upvotes: 3

Related Questions