summaryrefslogtreecommitdiffhomepage
path: root/racket.html.markdown
diff options
context:
space:
mode:
Diffstat (limited to 'racket.html.markdown')
-rw-r--r--racket.html.markdown91
1 files changed, 83 insertions, 8 deletions
diff --git a/racket.html.markdown b/racket.html.markdown
index 6abc8759..c6b1deba 100644
--- a/racket.html.markdown
+++ b/racket.html.markdown
@@ -7,6 +7,7 @@ contributors:
- ["Eli Barzilay", "https://github.com/elibarzilay"]
- ["Gustavo Schmidt", "https://github.com/gustavoschmidt"]
- ["Duong H. Nguyen", "https://github.com/cmpitg"]
+ - ["Keyan Zhang", "https://github.com/keyanzhang"]
---
Racket is a general purpose, multi-paradigm programming language in the Lisp/Scheme family.
@@ -113,18 +114,42 @@ some-var ; => 5
"Alice"
me) ; => "Bob"
+;; let* is like let, but allows you to use previous bindings in creating later bindings
+(let* ([x 1]
+ [y (+ x 1)])
+ (* x y))
+
+;; finally, letrec allows you to define recursive and mutually recursive functions
+(letrec ([is-even? (lambda (n)
+ (or (zero? n)
+ (is-odd? (sub1 n))))]
+ [is-odd? (lambda (n)
+ (and (not (zero? n))
+ (is-even? (sub1 n))))])
+ (is-odd? 11))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 3. Structs and Collections
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Structs
+; By default, structs are immutable
(struct dog (name breed age))
(define my-pet
(dog "lassie" "collie" 5))
my-pet ; => #<dog>
+; returns whether the variable was constructed with the dog constructor
(dog? my-pet) ; => #t
+; accesses the name field of the variable constructed with the dog constructor
(dog-name my-pet) ; => "lassie"
+; You can explicitly declare a struct to be mutable with the #:mutable option
+(struct rgba-color (red green blue alpha) #:mutable)
+(define burgundy
+ (rgba-color 144 0 32 1.0))
+(set-rgba-color-green! burgundy 10)
+(rgba-color-green burgundy) ; => 10
+
;;; Pairs (immutable)
;; `cons' constructs pairs, `car' and `cdr' extract the first
;; and second elements
@@ -139,8 +164,25 @@ my-pet ; => #<dog>
(cons 1 (cons 2 (cons 3 null))) ; => '(1 2 3)
;; `list' is a convenience variadic constructor for lists
(list 1 2 3) ; => '(1 2 3)
-;; and a quote can also be used for a literal list value
+;; a quote can also be used for a literal list value
'(1 2 3) ; => '(1 2 3)
+;; a quasiquote (represented by the backtick character) with commas
+;; can be used to evaluate functions
+`(1 ,(+ 1 1) 3) ; => '(1 2 3)
+
+;; With lists, car/cdr work slightly differently
+(car '(1 2 3)) ; => 1
+(cdr '(1 2 3)) ; => '(2 3)
+
+;; Racket also has predefined functions on top of car and cdr, to extract parts of a list
+(cadr (list 1 2 3)) ; => 2
+(car (cdr (list 1 2 3))) ; => 2
+
+(cddr (list 1 2 3)) ; => '(3)
+(cdr (cdr (list 1 2 3))) ; => '(3)
+
+(caddr (list 1 2 3)) ; => 3
+(car (cdr (cdr (list 1 2 3)))) ; => 3
;; Can still use `cons' to add an item to the beginning of a list
(cons 4 '(1 2 3)) ; => '(4 1 2 3)
@@ -282,16 +324,49 @@ m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- no `d'
;; for numbers use `='
(= 3 3.0) ; => #t
-(= 2 1) ; => #f
+(= 2 1) ; => #f
+
+;; `eq?' returns #t if 2 arguments refer to the same object (in memory),
+;; #f otherwise.
+;; In other words, it's a simple pointer comparison.
+(eq? '() '()) ; => #t, since there exists only one empty list in memory
+(let ([x '()] [y '()])
+ (eq? x y)) ; => #t, same as above
-;; for object identity use `eq?'
-(eq? 3 3) ; => #t
-(eq? 3 3.0) ; => #f
(eq? (list 3) (list 3)) ; => #f
+(let ([x (list 3)] [y (list 3)])
+ (eq? x y)) ; => #f — not the same list in memory!
+
+(let* ([x (list 3)] [y x])
+ (eq? x y)) ; => #t, since x and y now point to the same stuff
+
+(eq? 'yes 'yes) ; => #t
+(eq? 'yes 'no) ; => #f
+
+(eq? 3 3) ; => #t — be careful here
+ ; It’s better to use `=' for number comparisons.
+(eq? 3 3.0) ; => #f
+
+(eq? (expt 2 100) (expt 2 100)) ; => #f
+(eq? (integer->char 955) (integer->char 955)) ; => #f
+
+(eq? (string-append "foo" "bar") (string-append "foo" "bar")) ; => #f
+
+;; `eqv?' supports the comparison of number and character datatypes.
+;; for other datatypes, `eqv?' and `eq?' return the same result.
+(eqv? 3 3.0) ; => #f
+(eqv? (expt 2 100) (expt 2 100)) ; => #t
+(eqv? (integer->char 955) (integer->char 955)) ; => #t
+
+(eqv? (string-append "foo" "bar") (string-append "foo" "bar")) ; => #f
-;; for collections use `equal?'
-(equal? (list 'a 'b) (list 'a 'b)) ; => #t
-(equal? (list 'a 'b) (list 'b 'a)) ; => #f
+;; `equal?' supports the comparison of the following datatypes:
+;; strings, byte strings, pairs, mutable pairs, vectors, boxes,
+;; hash tables, and inspectable structures.
+;; for other datatypes, `equal?' and `eqv?' return the same result.
+(equal? 3 3.0) ; => #f
+(equal? (string-append "foo" "bar") (string-append "foo" "bar")) ; => #t
+(equal? (list 3) (list 3)) ; => #t
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 5. Control Flow