Racket for the Masses
Table of Contents
- 1. Introduction
- 2. Racket in 20 minutes or less
- 2.1. How to use functions
- 2.2. Things that are not functions look like functions
- 2.3. Function are just variables
- 2.4. Polymorphism was introduced later
- 2.5. Peculiarities
- 2.5.1. There is a small set of symbols that are reserved:
() [] {} # |, everything else can be overwritten. - 2.5.2. The language uses dashes for separate words in identifiers, like
string-appendorvector-ref. - 2.5.3. There is no operator for “not equal” like
!=. Conditionals have an inverse counterpart (likewhenandunless), we use(not x),(negate f), or just the structure the code to avoid the negation.
- 2.5.1. There is a small set of symbols that are reserved:
- 3. Programming Language Oriented
1. Introduction
2. Racket in 20 minutes or less
2.1. How to use functions
While functions in any other language look like this string_append("a", "b", "c"), in Racket they are written (string-append "a" "b" "c"). The open parenthesis is put before the function name and there is no comma separating arguments.
Play close attention to that because everything else is based on that format. In general, to call a function the format is:
(function-name arg1 arg2 arg3 ...)
2.2. Things that are not functions look like functions
2.2.1. Math looks like functions
Math has no special representation nor it changes the way the code is normally evaluated.
So, this in most languages:
1 + 2 + 3 * 4 * 5
Is written in Racket like this:
(+ 1 2 (* 3 4 5))
2.2.2. Control structures look like functions
Other languages have “commands”, reserved words, and special syntaxes for control structures. There is no such things in Racket. For example, if is usually reserved in other languages and have a special structure:
In Ruby, it is:
if a == b 1 else 2 end
Or in Javascript:
a === b ? 1 : 2;
The equivalent in Racket is:
(if (= a b) 1 2)
Note that it looks exactly like a function call.
2.2.3. Variable assigment looks like functions
A variable assignment (called binding in Racket) usually has a special structure in other languages. In Racket they look like functions, as everything else.
Variable assignment in Ruby:
a = 1
In Racket:
(define a 1)
2.2.4. Function definitions also look like function calls
Any other language have well defined syntaxes and reserved keywords for defining functions, methods, classes and so on.
For example, a function in Python is defined like this:
def add1(a): return a + 1 add1(10)
In Racket, defining a function looks like we are just calling the function define:
(define (add1 a) (+ a 1)) (add1 10)
2.2.5. Anonymous functions look like functions
Anonymous functions or code block in other languages also have special syntaxes. For example, a code block in Ruby looks like this:
add1 = -> a { a + 1 }
add1[10]
11
In Racket they still look like functions:
(define add1 (lambda (a) (+ a 1))) (add1 10)
Or using the character “λ” instead of the word “lambda”.
(define add1 (λ (a) (+ a 1))) (add1 10)
11
However, for simple functions like that, it is common to just use currying.
(define add1 (curry + 1)) (add1 10)
11
2.2.6. We call them “forms”
Given that the syntax for functions and everything else looks exactly the same, we need a name for them. In Racket they are called forms.
2.3. Function are just variables
2.3.2. They are passed as arguments or attributed to variables
2.4. Polymorphism was introduced later
Racket is a Scheme-like language which is quite old. So old that is predates polymorphism or method/function overloading. That means we still have a lot of functions that are prefixed by the type of data they act upon.
For example, to get the second value of:
- A list: we can write
(list-ref my-list 1) - A vector, we should write
(vector-ref my-vector 1). - A hash, it would be
(dict-ref my-dict 1).
However, now Racket supports polymorphism and modern code can use functions like:
(sequence-ref anything 1)if we use the standard library.(ref anything 1)if we use the excellent Generic Collections library.