A way to write shit with you elegant Scheme language

Take it easy if you're uncomfortable with the word 'elegant'. This article is not driven by any academic purpose. I'm trying to show an interesting way to write chaos Scheme code. ;-)

IMO, learning a language in a chaos way is fascinating.

Before your advanture, please make sure your Scheme interpreter support R7Rs.

For example, the latest Racket(5.3+) or GNU Guile(2.0.10+).

If you picked GNU Guile, please enable R7Rs symbols feature:

;; run this line in your Guile REPL:
(read-enable  'r7rs-symbols)


Now here is the code:

;; Try this code:
(apply + `(,((lambda (|2+3|) #(1)2+3) #e2e3) 
           ,(* 120 .((*(/(+(/(* #e144#) 84)))))) 
           ,(*(/(+ #e5/7)) 5)))

See, if you copy this code or type it correctly, what it should be showed?

Surprise hum?

Now let me explain the code if you can't figure it out clearly.

We can split this chaos code to several parts. The first part is:

((lambda (|2+3|) #(1)2+3) ; *exp1*
 #e2e3)                   ; *exp2*

As you may know the symbol in the parens after lambda depicts the parameter(as formal parameter) name. So |2+3| means a parameter named "2+3". Note that "2+3" here won't be evaluated to 5, but stored as a symbol for parameter name. This is a new syntax in R7Rs, an identifier can be represented by a sequence of zero or more characters enclosed within vertical lines (|), analogous to string literals.

#(1) means a vector contained one element: integer 1. It's reasonable to consider it as C array, because of the randomly accessing:

int arr[1] = {1};

The right side paren ')' is delimiter in Scheme, so *exp1* can be rewritten as:

(lambda (x) ; imagine x is replaced by a variable named "2+3"
 x) ; return x 

Now it's easy to understand that it's a anonymous function which always return the parameter passed in. The vector #(1) would be ignored in the context.

Let's consider *exp2*. The first question is "In what order should this code be read?"

Is it e2e3 after a hashtag? No.

Actually, it's #e followed by 2e3

2e3 means $2.0\times 10^3 = 2000.0$.

#e means "produce an exact number". So the code *exp2* can be replaced as:

(* 2 (expt 10 3))
;; NOTE:
;; #e means "produce an exact number" NOT "convert it to exact number"
;; The difference is that the cast can't promise the exactness
((lambda (|2+3|) #(1)2+3) #e2e3)

Let's move to the second part:

(* 120 .((*(/(+(/(* #e144#) 84))))))

Well, now you've already known the meaning of #e here, right?

And 144# seems an ambiguous mystery syntax. Actually, it's guaranteed in string->number of R5Rs[0]. You may consider it as $ddd\# = produce\_exact\_num(ddd \times 10)$ [1].

(string->number "144#")
;; ==> 1440.0
;; ==> 1440.0
;; ==> 1440
;; #e means "produce an exact number"

The REPL calls read procedure to read&parse "144#", then it will call string->number to convert it to an inexact number 1440.0.

With all hints so far, the rest code is easy to analyze, it's your turn if you're still here. ;-)

Happy hacking!



[0] Actually there's an explicit removing of this feature in R6Rs and R7Rs: # can no longer be used in place of digits in number representations.

[1] Racket/Chicken/Guile has this feature. Some Scheme implementation don't guarantee it. Scheme48 doesn't replace # as 0, but 5. Its code intend doing so, but I've no idea why.