bryanalves
2021-6-7 12:11:23

Hi, I’m currently going through racket koans trying to learn some of the basics, and I’m a bit stuck on how to write a 0-arity function that returns successive squares: https://github.com/zyrolasting/racket-koans/blob/master/koans/procedures.rkt#L32 I’m not sure how to make the function remember how many times it has been called. My current try looks something like:

;; Create a procedure that returns a new square of an integer ;; i each time it is called, starting from i = 0. (define (next-square) (let ([i -1]) (define (inner) (set! i (add1 i)) (* i i) ) (inner) ) ) Which obviously doesn’t work because the let is re-evaluated each time. I’m not sure how to structure this function to capture the number of times it’s been called. And given the level of these koans, using something more advanced like a generator with yield doesn’t seem to be the right solution. any hints?


bryanalves
2021-6-7 12:27:29

I changed to this, but this doesn’t seem to be in the spirit of the koan: ;; Create a procedure that returns a new square of an integer ;; i each time it is called, starting from i = 0. (define i -1) (define (next-square) (set! i (add1 i)) (* i i))


sorawee
2021-6-7 12:57:03

If your worry is about how (define i -1) is separated from next-square, the solution is to use “let over lambda” idiom.

(define next-square (let ([i -1]) (lambda () (set! i (add1 i)) (* i i))))


bryanalves
2021-6-7 13:00:32

yah, I guess i was just confused on if changing the define like that makes sense given that the original define was (define (next-square) ...) instead of (define next-square ...)


soegaard2
2021-6-7 13:03:34

An alternative (also using “let over lambda”) based on your first attempt: #lang racket (define (make-next-square) (let ([i -1]) (define (inner) (set! i (add1 i)) (* i i)) inner)) (define next (make-next-square)) (next) (next) (next)


bryanalves
2021-6-7 13:08:24

yep, this makes sense I think I just got too caught up in thinking "only change "?" and nothing around it.


sorawee
2021-6-7 13:08:25

Ah, I think @soegaard2 is probably the intended solution. The “procedure” in “Create a procedure that returns a new square of an integer ” probably refers to the output of make-next-square, not make-next-square itself.


soegaard2
2021-6-7 13:10:05

@bryanalves FWIW This section in SICP describes the details. https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book-Z-H-20.html#%_sec_3.1


sorawee
2021-6-7 13:11:00

And you can use define:

#lang racket (define (make-next-square) (define i -1) (lambda () (set! i (add1 i)) (* i i))) (define next (make-next-square)) (next) (next) (next)


gmauer
2021-6-7 14:11:49

@gmauer has joined the channel


petertbrady
2021-6-7 20:37:11

@petertbrady has joined the channel