KRC
KRC

Reputation: 328

scheme/racket: extensible functions

I wish to build a data struct for different kind of objects that have different ways of accessing the same type of parameters. For example,

A circle object would have a group code preceding its x-coord as 10, while a line object would have a header preceding its x-coord as 30. Also, objects do not always have the same parameters

So a generic function to extract all the necessary parameters from any object would look like:

(define (build-struct lst)
  (if (empty? lst)
      empty
      (begin (make-entity (find-params (string=? (car (car lst)))))
             (build-struct (cdr lst)))))
    ;function to build structs from a list of lists (that contain an object)

(define-struct entity (name x-coord y-coord layer-name [num-vertices #:auto] [radius #:auto] [start-angle #:auto] [end-angle #:auto])
  #:auto-value empty)
;data struct to store object param values

(define (find-circle-param lst parameter)
  (let ((kw (string-upcase parameter)))
    (if (empty? lst)
        '() ;put error message here
        (cond ((and (string=? kw "X-COORD") (= (car lst) "10"))
               (cadr lst))
              ((and (string=? kw "Y-COORD") (= (car lst) "20"))
               (cadr lst))
              ((and (string=? kw "LAYER-NAME") (= (car lst) "8"))
               (cadr lst))
              ((and (string=? kw "RADIUS") (= (car lst) "40"))
               (cadr lst))
              (else #f)))))
(define (find-line-param lst parameter)
  (let ((kw (string-upcase parameter)))
    (if (empty? lst)
        '() ;put error message here
        (cond ((and (string=? kw "X-COORD-START") (= (car lst) "10"))
               (cadr lst))
              ((and (string=? kw "Y-COORD-START") (= (car lst) "20"))
               (cadr lst))
              ((and (string=? kw "X-COORD-END") (= (car lst) "11"))
               (cadr lst))
              ((and (string=? kw "Y-COORD-END") (= (car lst) "21"))
               (cadr lst))
              ((and (string=? kw "LAYER-NAME") (= (car lst) "8"))
               (cadr lst))
              (else #f)))))
;functions to find parameter value depending on object type

I just want to create one function for finding parameters.

Upvotes: 0

Views: 112

Answers (1)

soegaard
soegaard

Reputation: 31147

Structures can have a super type. If you have several structures with common properties consider giving them a common super type. Here is an example:

#lang racket
(struct shape        (x y)         #:transparent) ; all shapes has x and y coordinates
(struct circle shape (radius)      #:transparent) ; a circle has besides the center also a radius
(struct line   shape (x-end y-end) #:transparent) ; a line has besides its start point also end coords    
(define c (circle 1 2 3))
(define l (line   4 5 6 7))

(define (position a-shape)
  (match a-shape
    [(shape x y)  (list "Position:" x y)]
    [_            (error 'position "expected a shape, got ~a" a-shape)]))

(position c)
(position l)

Note that the definition of position can find the position of both a circle and a line, without explicit mentioning of circles and lines in the definition of position.

Upvotes: 1

Related Questions