Templates arise from data definitions. It's meaningless to talk about a template without a data definition. The idea of a template is to write a skeleton of a function that consumes a particular kind of data as input. The template captures everything we know about the structure of the program based on the structure of the data.
; A Circle is a (make-circle Posn Number) (define-struct circle (center radius))
would yield the template
(define (circ-func acirc)
(...(circle-center acirc)
(circle-radius acirc)))
For a structure, we simply pull out all of the pieces inside of the template.
; A Circle is a (make-circle Posn Number) (define-struct circle (center radius)) ; A Square is a (make-square Posn Number) (define-struct square (top-left width)) ; A Shape is either ; - a Circle, or ; - a Square
Here, the template for shape has two cases (one for each option in the definition). In each case, we call the template for the corresponding shape.
(define (circ-func acirc)
(... (circle-center acirc)
(circle-radius acirc)))
(define (square-func asqr)
(... (square-top-left asqr)
(square-width asqr)))
(define (shape-func ashape)
(cond [(circle? ashape) (circ-func ashape)]
[(square? ashape) (square-func ashape)]))
; A ListOfString is ; - empty, or ; - (cons String ListOfString)
Now, the template breaks down the list inside the cons? case and includes a recursive call to capture the "arrow" from ListOfString back to itself.
(define (list-of-str-func alos)
(cond [(empty? alos) ...]
[(cons? alos)
(... (first alos)
(list-of-str-func (rest alos)))]))