Wednesday, 1 July 2020

(practical-python->racket 1.3 numbers)

The first challenge that I faced in translating the examples of Practical Python Programming - 1.3 Numbers was the differences in the number type systems between Python and Racket.

Python has a flat number type system with four types: booleans, integers, floating point and complex (imaginary numbers).

Racket has a heirarchical number type system. There are two main branches in the heirarchy, exact and inexact. This is a somewhat simplified view of the Racket number type hierarchy:
    exact
      integer      e.g. 10 - like a Python integer
      rational     e.g. 1/2
      complex    e.g. 1 + 2i
    inexact
      real          e.g. 2.0 - like a Python floating point
      complex    e.g. 2.1 + 3.3i

Racket also has two specialists number types, flonum (floating point) and fixnum (integer), that are used when there is a need for improved performance. These have their own maths operators. (I haven't looked into them any further at this stage.)

When "translating" the Python code, I have equated its integer with Racket's exact and its floating point with Racket's inexact.

The second came from Python's boolean type. It's a very raw C-language type with very few barriers to how a programmer can use it. For all I know, Racket's boolean type may similarly be implemented using integers. However, as far as the Racket programmer is concerned, it supports only two values: true and false.

I didn't want my script to just raise an error and stop when I tried to add a number to a boolean. After searching the docs and a little trial and error, I worked out how to trap an error:

   (racket '(define c 4))
   (racket "(+ c true)")
   (expect "Contract violation")
   (with-handlers ([exn:fail:contract?
                 (lambda (err) 
                  (displayln "Contract Violation"))])
                 (+ c true))

The third was tame in comparison, working out how to convert an inexact float to an exact integer. I came up with using: 

   (inexact->exact (floor my-float-value))

Take a look at the numbers.rkt script, then run it either in Dr Racket or the Racket repl. Do the result make sense?

No comments: