Quite similar to lisp.
An advantage of s-expr:
(+ 1 2 3 4 5 6)
is clearer than1+2+3+4+5+6
General
Comment: semicolon
File extension: rkt
Can use any kind of these brackets with the same effect.
- [] or {} or ()
- Use wisely to improve readability
Function call:
(fn-name args)
Variable 'call':
var-name
(ie, no braces)'
#lang ...
is only a shorthand for(module name initial-import decl ...)
Multiple modules can be imported at once
- Eg:
(require (for-syntax racket/base))
- Eg:
racket/base
is the foundational languagedefine-syntax
: 'basic tool for introducing a macro' ᵇʳ- accepts a syntax object, returns another syntax object
syntax-parse
: 'most powerful macro-making tool'syntax-case
: a limited form ofsyntax-parse
??
with-syntax
,with-syntax*
A given lang is inside a directory with its name
- Must have a file
main.rkt
main.rkt
must have a submodule namedreader
reader
module mustprovide
aread-syntax
function
- Must have a file
case-lambda
: Defining function by cases
#lang racket/base
(define f
(case-lambda
[() 10] ; no arg
[(x) (+ x 1)] ; one arg
[(x y) (list y x)] ; two arg
[r r])) ; everything else
;; case-lambda.rkt> (f)
;; 10
;; case-lambda.rkt> (f 10)
;; 11
;; case-lambda.rkt> (f 2 3)
;; '(3 2)
;; case-lambda.rkt> (f "whatever" "here" "huh")
;; '("whatever" "here" "huh")
String formatting
Use racket/format
.
- https://stackoverflow.com/questions/32839407/how-to-format-output-using-racket
- https://docs.racket-lang.org/reference/strings.html
#lang racket/base
(require racket/format)
(~a 12
#:align 'right
#:width 5)
; " 12"
(~a 12
#:align 'right
#:pad-string "Hi"
#:width 5)
; "HiH12"
Data structure contracts
Variable name conventions
https://docs.racket-lang.org/reference/reader.html#(part._default-readtable-dispatch)
Many of the conventions are from Scheme.
- Question mark at end of a function means that it is a function returning a bool (predicate)
- Eg:
pair?
- https://docs.racket-lang.org/reference/notation.html
(boolean? #f) ; #t
- Eg:
- Exclamation mark at end of name: function that mutates.
- For destructive procedures. ie, those that modifies arg in-place.
- Eg:
set!
->
: procedures that perform a conversion- Eg:
string->number
- Eg:
*
for variants- Eg:
let
andlet*
- Eg:
Unknown:
#%name
: ??- Eg:
#%module-begin
- Eg:
Not sure if the following are followed in racket:
*name*
: global mutable variable+name+
: global constants:
: namespaces- Eg:
top:func
- Eg:
https://justinethier.github.io/cyclone/docs/Scheme-code-conventions.html
Pattern macros
(define-syntax-rule (swap x y)
(let ([tmp x])
(set! x y)
(set! y tmp)))
(let
([a 3]
[b 4])
(swap a b)
a)
; '(4 3) instead of '(3 4)
Defining new language
provide
: mention list of names to export from a filerename-out
: rename names while exportingdefine-syntax
:
Examples
; Factorial of whole numbers
(define (fact n)
(if (<= n 0)
1
(* n {fact [- n 1]})))
let
expressions
let
for 'subcomputation':
Syntax:
let <list of binding> <expr>
(define foobar
(let* ([foo 10]
[bar 20])
(* foo bar)))
(define (fact n) (if (<= n 0) 1 (let* [foo (fact (- n 1))])
let* use => no recursion???
eval
eval:
- the interpreter itself
- scheme can be its own metalanguage
we can e
; assuming fact is function doing factorial
(define foo '(fact 5))
(eval foo)
; 120
Bindings not assignments
We can't redefine an identifer.
(define pi 3.14)
(define pi (/ 22 7))
module: identifier already defined
∵ it's immutable.
They're bindings not value assignments.
Modulus operation
> (quotient/remainder 17 2)
8
1
> (quotient 17 2)
8
> (remainder 17 2)
1
Boolean values
- True:
#t
- False:
#f
; pair? checks if its argument is a pair
> (pair? '())
#f
> (pair? (cons 2 3))
#t
Lists
(list 1 2 3)
; is same as
'(1 2 3)
The single quote sort of asks the interpreter to stop evaluating from that point.
- Constructor:
list
- head:
car
- tail:
cdr
- Empty list:
null
or'()
> (list -1 2.3 "hi")
'(-1 2.3 "hi")
> (car '(1 2 3 4 5))
1
> (cdr '(1 2 3 4 5))
'(2 3 4 5)
car
and cdr
for elisp is similar:
Pairs
See https://docs.racket-lang.org/reference/pairs.html.
Tuples.
Immutable
Constructor:
cons
1st:
car
2nd element:
cdr
> (cons 1 2)
'(1 . 2)
> '(1 . 2)
'(1 . 2)
> '(1 . 2 . 3)
'(2 1 3)
> (car '(1 . 2))
1
> (cdr '(1 . 2))
2
Etymology of car
and cdr
(for pairs and lists) in the lisp world is historical.
- https://en.wikipedia.org/wiki/CAR_and_CDR
- https://www.math.utah.edu/docs/info/emacs-lisp-intro_8.html
Loops
See https://docs.racket-lang.org/guide/for.html
(for ([i 3])
(display i))
; Above is syntactic sugar for
(for ([i (in-range 0 3)])
(display i))
; because in-range's first argument defaults to 0
drracket
- run: C-r
emacs
- Emacs mode: racket-mode
- C-c C-c: Load buffer
- paredit mode could be useful.
- Or even better:
racket-xp-mode
Info
- Scheme is a dialect of lisp.
- Scheme is standardized as an IEEE standard.
- R5RS is a scheme standard.
- RnRS: Revisedⁿ Report on algorithmic standard Scheme
- Racket is descended from scheme