7.0.0.6

8 Lab My First Real Language

Goals

building a simple hash-lang language

Exercise 16. Make #lang algebra work, instead of #lang s-exp "algebra.rkt". image

Exercise 17. The program
#lang algebra
(+ 0.1 (+ 0.1 (+ 0.1 (+ 0.1 (+ 0.1 (+ 0.1 (+ 0.1 (+ 0.1 (+ 0.1 0.1)))))))))
shouldn’t produce a number less than 1.0, but that’s what happens if you use inexact numbers that are implemented as floating-point numbers. Change #lang algebra to treat all numbers as exact numbers, even when the number has a decimal point.

This change happens to be easy, because read-syntax supports a read-decimal-as-inexact parameter that can be set using parameterize.

Examples:
> (exact? 1.0)

#f

> (exact? 1)

#t

> (define (one-as-input) (open-input-string "1.0"))
> (read-syntax 'one (one-as-input))

#<syntax:one::1 1.0>

> (parameterize ([read-decimal-as-inexact #f])
    (read-syntax 'one (one-as-input)))

#<syntax:one::1 1>

> (define (read-it)
    (read-syntax 'one (one-as-input)))
> (read-it)

#<syntax:one::1 1.0>

> (parameterize ([read-decimal-as-inexact #f])
    (read-it))

#<syntax:one::1 1>

The other piece that you need is that syntax/module-reader supports a #:wrapper1 option to control a call to read-syntax. image

Exercise 18. Let’s go the other way, and suppose that you want all numbers in #lang algebra to be floating-point numbers, because you don’t want to accidentally perform expensive exact calculations.

There’s no parameter that makes read-syntax treat all numbers as inexact. Fortunately, there’s no loss of information when read-syntax produces an exact number and you want an inexact number; you can convert using exact->inexact. image

Exercise 19. Let’s allow the user of #lang algebra pick when to use exact numbers and when to use inexact numbers:
  Expression = ...
  | (exactly Expression)
  | (inexactly Expression)
  | (/ Expression Expression)
In (exactly Expression), any number that appears literally in Expression should e an exact number, unless it’s in a nested (inexactly Expression), and vice versa.

We’re also adding a division operator. That way, an expression can fail at run time. Make sure that

(inexactly (+ 1.0 (exactly (/ 1.0 0.0))))

fails with a divide-by-zero error (as happens with exact numbers), as opposed to producing +inf.0 (as happens with inexact numbers). Also make sure that DrRacket highlights specifically the (/ 1.0 0.0) in pink as the source location of the error. image

Please fill out today’s post-day survey.