Julio Biason
4 years ago
1 changed files with 180 additions and 0 deletions
@ -0,0 +1,180 @@
|
||||
+++ |
||||
title = "Realm of Racket: Lean to Program, One Game at a Time!" |
||||
date = 2020-12-18 |
||||
|
||||
[taxonomies] |
||||
tags = ["books", "reviews", "it", "racket", "2020 challenge", "2 stars"] |
||||
+++ |
||||
|
||||
[GoodReads Summary](https://www.goodreads.com/book/show/17153511-realm-of-racket): |
||||
Racket is a descendant of Lisp, a programming |
||||
language renowned for its elegance, power, and challenging learning |
||||
curve. But while Racket retains the functional goodness of Lisp, it |
||||
was designed with beginning programmers in mind. Realm of Racket is |
||||
your introduction to the Racket language. |
||||
|
||||
<!-- more --> |
||||
|
||||
{{ stars(stars=2) }} |
||||
|
||||
This is a weird book. Not because its content, or the topic at hand, |
||||
but the path chosen to explain things. For example, even after reading |
||||
the whole book, I don't have any idea why I should pick Racket over |
||||
any other Lisp variant. |
||||
|
||||
So, laundry list of things that put me off: |
||||
|
||||
- No real explanation on why I should pick Racket over any other Lisp |
||||
(or any other language, for that matter); they don't say it's faster, |
||||
or more accurate, or it's syntax makes you write less bugs or the |
||||
compiler will prevent you from doing it so. |
||||
|
||||
- There is a strong favouritism for Racket. It isn't that unexpected, |
||||
but they authors start by bashing other languages, which gives a |
||||
feeling that they just want to make their favourite language look |
||||
better (this goes away only in the last chapter, when comparing Racket |
||||
to Java). |
||||
|
||||
- They use different words for common things. There isn't and IDE, it |
||||
is a PDE, "program development environment"; the integrated |
||||
development environment becomes "interactive development |
||||
environment"; functions don't "receive" parameters, they "consume" |
||||
the values, which make it sound more like a Rust thing, in which the |
||||
function gets the ownership of the value and, on its end, the memory |
||||
is freed, which doesn't happen in Racket. |
||||
|
||||
- There is a bunch of "trivial", "simple", and such. This is bad, |
||||
specially if you want newbies to read the book; if they don't grasp |
||||
the concept, saying it is "trivial" will make them feel bad about |
||||
themselves. |
||||
|
||||
- A lot of explanations are basically "(+ a 1)" -> "adds 1 to |
||||
a". Sure, one may not understand all the facets of the code, but |
||||
when you explain "why" you wrote code that way instead of "what" the |
||||
code is, it is a lot easier to understand. |
||||
|
||||
- Because the book is too focused on explaining one single library, |
||||
some things feel like "if everything you have is a hammer". For |
||||
example, there is one game of attacking monsters and which the |
||||
authors put the target in the state, and it doesn't feel like this |
||||
should be part of the state of the game. Sure, the selected target |
||||
affects the state, but it is not part of the state, at least for me, |
||||
and there isn't any good explanation on why it should be part of it. |
||||
|
||||
- Another example uses a complex number to represent points in a 2D |
||||
plane. Sure, 2D points and complex numbers are composed by two |
||||
elements, but that doesn't mean that 2D points **are** complex |
||||
numbers. Types matter, even in dynamic languages. |
||||
|
||||
So... yeah, I think I learn a bit of Racket, but I still don't know |
||||
why I should pick it over anything else. Is it just the game building |
||||
library? Should one pick a language exclusively because of some built |
||||
in library? Doesn't anything else affects this decision? (All |
||||
questions are rhetorical, it is obvious that you shouldn't pick a |
||||
language just because one library). |
||||
|
||||
--- |
||||
|
||||
Highlights: |
||||
|
||||
> `(foo)*g++.baz(!&qux::zip->ding());` |
||||
|
||||
"Let me write a very contrived example, just to make my favourite |
||||
language look better compared to this one." |
||||
|
||||
> `(sqrt (+ (sqr 3) (sqr 4)))` |
||||
|
||||
This is nowhere _near_ the example in C++. If you want to compare |
||||
languages, at least write the same thing. |
||||
|
||||
> If you’re on a *nix box, you are already a hero and don’t need instructions. |
||||
|
||||
What a load of bull. It sounds more like you don't have an idea on how |
||||
to do it in Linux. |
||||
|
||||
> (the compiler) DrRacket reads this expression, evaluates it, |
||||
> prints the result, and then displays its prompt again. |
||||
|
||||
You just described an interpreter, not a compiler. For all purposes |
||||
and intents, sure, it compiles the code to make sure it is not |
||||
invalid, but the concept of "compiler" is used mostly for things that |
||||
take a source and produce a stand-alone executable. Otherwise, even |
||||
Python have a compiler. |
||||
|
||||
> the function uses a set! expression to change the value of a |
||||
> variable. |
||||
|
||||
Why `set!`? Why not just `set`? What the `!` means? Nothing? Is it |
||||
just a convention? |
||||
|
||||
> Racket has three kinds of comments |
||||
|
||||
And absolutely no example of those kinds. |
||||
|
||||
> ``` |
||||
> (/ 4 6) |
||||
> 2/3``` |
||||
|
||||
This is one cool thing: Racket keeps the values in their fractional |
||||
format. |
||||
|
||||
> ```(struct student (name id# dorm)) |
||||
> (student-name freshman1) |
||||
> 'Joe |
||||
> (student-id# freshman1) |
||||
> 1234``` |
||||
|
||||
Creating structs and extracting values from them. |
||||
|
||||
> ```(define x 7) |
||||
> (cond [(= x 7) 5] |
||||
> [(odd? x) 'odd-number] |
||||
> [else 'even-number])``` |
||||
|
||||
Multiple tests. Also, there is this use of brackets ("[") and |
||||
parenthesis ("(") which is never properly explained, though. |
||||
|
||||
> ``` |
||||
> (when (and file-modified (ask-user-about-saving)) (save-file)) |
||||
> ``` |
||||
|
||||
Because `and` and `or` return the value if it's not the boolean false |
||||
(`#f`), you can use tests to simplify the code. |
||||
|
||||
> ``` |
||||
> (define filename "my-first-program.rkt") |
||||
> (unless (ask-user-whether-to-keep-file filename) (delete-file filename)) |
||||
> ``` |
||||
|
||||
`unless` is a form of `if` that performs an action only if the value |
||||
is `#f` (false). |
||||
|
||||
> ``` |
||||
> (struct orc monster (club)) |
||||
> (struct hydra monster ()) |
||||
> (struct slime monster (sliminess)) |
||||
> (struct brigand monster ()) |
||||
> ``` |
||||
|
||||
Examples of deriving structs from other structs. |
||||
|
||||
> In summary, mutators make programming complex |
||||
|
||||
Just a few paragraphs better, you used a mutator saying that this |
||||
would make the code better. |
||||
|
||||
> `raco exe -l hello-world.rkt` |
||||
|
||||
Generating a standalone executable from Racket source code. |
||||
|
||||
> ``` |
||||
> (define snake% |
||||
> (class object% |
||||
> (super-new) |
||||
> (init-field dir head tail) |
||||
> (define/public (slither) |
||||
> (set! tail (cons head (all-but-last tail))) |
||||
> (set! head (next-head))) |
||||
> ``` |
||||
|
||||
Classes in Racket. |
Loading…
Reference in new issue