racketrackunit

Racket strange (require ...) semantics


I have a Racket code:

#lang racket
(provide (all-defined-out))

(struct weather (name perspective temperature humidity wind class) 
#:transparent)

;;Exercise 8
;;Todo implement
#;(define (read-examples file-name)
  (file->lines file-name))

;;todo uncomment
#;(define examples (read-examples "examples.txt"))

;;Exercise 9
(define (add-example examples example)
  (cons example examples))

;;Exercise 10
(define (attribute which examples)
  (define command (eval (string->symbol(string-append "weather-" 
(symbol->string which)))))
  (if (null? examples) null
      (cons (command (car examples)) (attribute which (cdr examples)))))

Also test file:

#lang racket
(require rackunit "xalt2.rkt")

(define examples (list (weather "Day1" 'cloudy -5 60 'yes '-)
                   (weather "Day2" 'cloudy 0 30 'no '+)
                   (weather "Day3" 'cloudy 10 45 'no '+)
                   (weather "Day4" 'cloudy 20 60 'yes '-)
                   (weather "Day5" 'cloudy 30 80 'no '+)))

;;tests for Exercise 9
(define argument-for-add-example (weather "Day77" 'cloudy 39 87 'no '+))
(define expected-result (cons argument-for-add-example examples))
(check-equal? (add-example examples argument-for-add-example) expected-result "addind to list is not working?")

;;tests for Exercise 10
(check-equal? (attribute 'wind examples) null "")

it gives me strange error about struct functions not being defined, but i have required the file with the struct defined and used in the test file... I do use Racket 6.8


Solution

  • The error occurs because you are using eval in the wrong namespace.

    Recommendation #1: Don't use eval.

    Consider writing a helper function that converts attribute symbols into accessors:

    ;; get-attribute-function : Symbol -> (Weather -> Any)
    (define (get-attribute-function attr)
      (case attr
        [(name) weather-name]
        ....))
    

    Or you could make a hash table that mapped symbols to functions instead.

    Recommendation #2: If you must, must use eval, you need to make sure you're giving it the right namespace. Read the docs on reflection and dynamic evaluation, especially the parts about namespaces.