This code doesn’t do much, just four ‘ants’ doing random walks, but could anyone suggest ways this code could be better and more Racket in style.
#lang racket
(require 2htdp/universe 2htdp/image)
(struct ant (x y) #:transparent)
(define (random-walk value)
(+ value (sub1 (random 3))))
(define (move-ant in-ant)
(ant (random-walk (ant-x in-ant)) (random-walk (ant-y in-ant))))
(define (move-ants list-ants)
(map move-ant list-ants))
(define one-ant-list (list (ant 100 100) (ant 200 200) (ant 100 200) (ant 200 100)))
(define (render-world list-of-ants)
(let ((image (rectangle 400 400 "solid" "white")))
(map (λ (ant) (set! image (add-line image (ant-x ant) (ant-y ant) (add1 (ant-x ant)) (add1 (ant-y ant)) "black"))) list-of-ants)
image))
(big-bang one-ant-list
(on-tick move-ants)
(to-draw render-world))
@mark.warren to me, random-walk
could take both x and y coordinates. And the drawing with (set! image ...)
part could be render-ant
@jerome.martin.dev Good points, thanks.
apart from that, looks good :slightly_smiling_face:
maybe one style hint: inside a let
form, racketeers often use square brackets like so: (let ([x 4] [y 12] [z 28]) ...)
I find it easier to read let
, for
and other such constructs with square brackets
I don’t remember where but I stumbled upon someone saying it was great to differentiate between executed and not-executed forms.
@jerome.martin.dev Yes I forgot about the square bracket convention
oh also
the (set! image ...)
can be avoided completely
Cool
I didn’t like that
(define (render-world list-of-ants)
(for/fold ([image (rectangle 400 400 "solid" "white")])
([ant list-of-ants])
(add-line image
(ant-x ant)
(ant-y ant)
(add1 (ant-x ant))
(add1 (ant-y ant))
"black")))
Woo, like it.
for/fold
is a great construct in Racket :smile:
Yeah, still not got those for
constructs really sussed. I’m a Java programmer by day and to me for
means a whole other thing.
yep, it was the same for me first :stuck_out_tongue:
in fact, in standard scheme you would do something a bit similar using (let loop ([image (rectangle)]) (loop (add-line)))
but then when your familiar with the named let (it creates a function you can call to recurse), then for/fold
abstracts this for you
I love scheme
Personally, It took me multiple steps: 1) I don’t know Scheme 2) I don’t get it 3) Oh my god it’s awful 4) I love it
I’ve not changed the random walk function yet but this is looking better #lang racket
(require 2htdp/universe 2htdp/image)
(struct ant (x y) #:transparent)
(define (random-walk value)
(+ value (sub1 (random 3))))
(define (move-ant in-ant)
(ant (random-walk (ant-x in-ant)) (random-walk (ant-y in-ant))))
(define (move-ants list-ants)
(map move-ant list-ants))
(define one-ant-list (list (ant 100 100) (ant 200 200) (ant 100 200) (ant 200 100)))
(define (render-ant image ant)
(add-line image (ant-x ant) (ant-y ant) (add1 (ant-x ant)) (add1 (ant-y ant)) "black"))
(define (render-world list-of-ants)
(for/fold ([image (rectangle 400 400 "solid" "white")])
([ant list-of-ants])
(render-ant image ant)))
(big-bang one-ant-list
(on-tick move-ants)
(to-draw render-world))
definitely :smile:
Yep, I found once the parentheses thing went away in my head, it just feels such a natural way to do stuff.
Now I love them cause I just have to pass my cursor above them to see what the code structure is. I hated them and now I miss them in other languages x)
Hehe, know what you mean.
@jerome.martin.dev Many thanks, that feels slicker
you’re welcome :slightly_smiling_face:
Now to get the ants to take over the world.
:ant:
:grinning:
the for/x
variants in Racket are so much better than using map
, fold
, named lets or even plain recursive functions
I agree. Also, in some cases if you ever do need (or prefer) to use recursive functions? Using racket/match
to destructure lists can be much nicer than the traditional eye-glazing null?
car
cadr
cdr
soup.
@greg to me it’s still one of the biggest gains in using a ML like OCaml: destructuring pattern matching + Algebraic data types. though sometimes having all variants defined upfront gets in the way (there are polymorphic variants though)