# Writing a general purpose "split" function (for SICP's imaginary language)

From SICP 2.2.4:

The textbook has already defined a function (right-split ...) as follows:

(define (right-split painter n)
(if (= n 0)
painter
(let ((smaller (right-split painter (- n 1))))
(beside painter (below smaller smaller)))))


and they have indicated that there exists a procedure (up-split ...) which has much the same structure.

Exercise 2.45. Right-split and up-split can be expressed as instances of a general splitting operation. Define a procedure split with the property that evaluating

(define right-split (split beside below))
(define up-split (split below beside))


produces procedures right-split and up-split with the same behaviors as the ones already defined.

I wrote the following function, but I'm not sure the best way to test it. What do you think?

(define (split step1 step2)
(define (split-f painter n)
(if (= n 0)
painter
(let ((smaller (split-f painter (- n 1))))
(step2 (step1 smaller smaller)))))
split-f)

(define right-split (split beside below))
(define up-split (split below beside))


In order to test it, you need to have definitions for things like beside and below. There's something strange in the text book code because the painter "smaller" is not actually scaled in the code, or is it indicated that "below" and "beside" scale their arguments? Anyway, you can just define

  (define (below a b) (below ,a, b))
(define (beside a b) (beside ,a ,b))


so e.g. (right-split 'apple 1) should produce as result

  '(beside apple (below apple apple))


You can verify from the structure of the terms that your code works correctly.

Your (split ...) function has a bug, as "painter" is missing from the line where you call "step2". The code should read

  (step2 painter (step1 smaller smaller))


Otherwise it looks fine to me.