When implementing data structures we need a way to represent a structure. A list or array is one approach to implementing structures but this provides little semantic meaning. With structures we have a way of implementing data structures and providing a semantic meaning to the values used for fields.
Suppose we have a structure called person with fields name and age. If we implemented structures with a list the implementation would be (define person (list "chili5" 18)). Then if we wanted the name of the person we would have to do (first (person)) but what does this mean? It simply returns the first element in the list but that could be anything. To clean this up we could write a function name that takes a list and returns the first element like this:
(define (name person) (first person))
This is in fact a powerful way to implement structures and is how they are implemented in Scheme dialects where structures do not exist. You may prefer this because it lets you use list functions on your structure. When we look at recursive list functions it will be obvious that you can implement recursive structures such as trees and graphs fairly easily.
The benefit of using structures is you get predefined selector functions and predicate functions. The selector functions are easy to write with lists but the predicate function is not that easy to write.
Defining a Structure
We use the keyword define-struct as follows:
(define-struct person (name age height))
The name of the structure is person and in the inner parenthesis are the fields of this structure. In this case person has 3 fields: name, age and height. So when this runs the following functions are created:
(person-name person) which returns the name of the person passed as a parameter
(person-age person) which returns the age of the person passed as a parameter
(person-height person) which returns the height of the person passed as a parameter
(person? obj) which returns true if obj is of type person and false otherwise.
(make-person name age height) which produces a person structure.
(define p (make-person "chili5" 19 2.5)) (person-name p) ;; produces chili5 (person-age p) ;; produces 19 (person-height p) ;; produces 2.5 (person? p) ;; produces true (person? 5) ;; produces 5
At this point, it is important to mention that mutators DO NOT exist. These are added later. In the mean time, the only option you have to mutate structures is to make a new one.
In this example, I want to increase age by 2 and increase height by 3 and leave the name the same. My only option is to use selector functions and a new constructor. Because mutation does not exist, I will be left with a new person object and the new person object.
(define p (make-person "chili5" 19 2.5)) (define new-person (make-person (person-name p) (+ (person-age p) 2) (+ 3 (person-height p))))You can test out the change in values by using selectors on new-person. Try the following code:
(person-name new-person) ;; produces chili5 (person-age new-person) ;; produces 21 (person-height new-person) ;; produces 3.5
Post any questions below!
Edited by chili5, 21 August 2011 - 06:11 AM.