Scheme: Changing the definition of complex numbers

2019-01-29 06:39发布

问题:

Basically what I am trying to do is change the definition of complex numbers so I can represent vectors in Scheme. I want to be able to write something like "i+j+k" without the quotes and not have the program go entirely crazy. I know complex numbers can be represented by something like "1+2i" so I was hoping a simple overwrite could accomplish this.

I thought overwriting the complex? definition might work, but it seems to have no effect. I am unsure of where the code I need to affect even is. Any help would be amazing. Thanks.

回答1:

Are you aware that the Racket reader already supports complex literal numbers?

Examples from the Reference:

1+2i reads equal to (make-complex 1 2)

1/2+3/4i reads equal to (make-complex (/ 1 2) (/ 3 4))

1.0+3.0e7i reads equal to (exact->inexact (make-complex 1 30000000))



回答2:

In short: You can not with a "simple overwrite" accomplish what you want. The syntax for numbers include a + used to read/write complex numbers, but the reader converts 2+3i into a number directly with no option of any overriding.

If you want to use infix notation in your program you'll need to replace the reader. This is possible in Racket but it is more complicated than a simple overwrite.

Maybe you can use an existing library for infix notation in Racket?

You may want to try out:

https://github.com/soegaard/this-and-that/blob/master/readtable/test2.rkt

which parses anything in {} as infix expressions.



回答3:

Modifying the Scheme reader is certainly not provided for in the Scheme standards and would thus require you to change the 'reader' for your chosen Scheme implementation - a non-trivial task.

You'd be better off embedding your own language in Scheme proper using Scheme's macro and abstraction facilities.

Assume you have a coordinate basis for i, j, and k and you want to express vectors as, for example, 2i+7j-k. You could start with:

(define (make-coord i j k) (vector i j k))
(define (coord-i b) (vector-ref b 0))
…

Then if you want to make things a bit easier to express:

(define-syntax coord
  (syntax-rules ()
    ((coord i j k) (make-coord i j k))))

which you would use as:

(define a-coord (coord 2 7 -1))

Edit: Here is an example. I replaced make-coord with list:

> (define-syntax coord
    (syntax-rules ()
      ((coord i j k) (list i j k))))
> (coord 1 1 1)
(1 1 1)

Note that one of the advantages to using syntax/functions, instead of the reader, is that you can use expressions:

> (coord (/ 124 4) 0 0)
(31 0 0)