If you look at your code for this exercise as well as the one about approximating the square root and the one about finding epsi, you'll notice a common pattern:
You have a function which performs a single step and a predicate which tells you when you're done. You then apply the stepping function until the predicate is met. When you encounter a common pattern like this, the best thing to do is usually to abstract it. So let's define an apply-until function which takes a stepping function, a predicate and an initial value and applies the function to the value until the predicate is met:
(define (apply-until step done? x) (if (done? x) x (apply-until (step x) step done?)))
You can now define your cuberoot function using apply-until instead of cuberoot-iter:
(define (cuberoot x) (apply-until (lambda (y) (improve-guess y x)) (lambda (guess) (goodenough? guess)) 1.0))
You can also move your helper functions as local functions into the cuberoot function. This way they don't need to take x as an argument (as they will close over it) and can thus be passed directly to apply-until without using lambda:
(define (cuberoot x) (define (improveguess y) ; y is a guess for cuberoot(x) (/ (+ (/ x (expt y 2)) (* 2 y)) 3)) (define (goodenough? guess) (< (/ (abs (- (cube guess) x)) guess) 0.0001)) (apply-until improveguess goodenough? 1.0))