diff options
Diffstat (limited to 'racket.html.markdown')
-rw-r--r-- | racket.html.markdown | 96 |
1 files changed, 85 insertions, 11 deletions
diff --git a/racket.html.markdown b/racket.html.markdown index adacd91d..0fe3f030 100644 --- a/racket.html.markdown +++ b/racket.html.markdown @@ -6,6 +6,8 @@ contributors: - ["th3rac25", "https://github.com/voila"] - ["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. @@ -195,7 +197,7 @@ my-pet ; => #<dog> (hash-ref m 'd 0) ; => 0 ;; Use `hash-set' to extend an immutable hash table -;; (Returns the extended hash instdead of mutating it) +;; (Returns the extended hash instead of mutating it) (define m2 (hash-set m 'd 4)) m2 ; => '#hash((b . 2) (a . 1) (d . 4) (c . 3)) @@ -223,7 +225,7 @@ m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- no `d' (define hello-world (lambda () "Hello World")) (hello-world) ; => "Hello World" -;; You can shorten this using the function definition syntatcic sugae: +;; You can shorten this using the function definition syntactic sugar: (define (hello-world2) "Hello World") ;; The () in the above is the list of arguments for the function @@ -281,16 +283,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 -;; for collections use `equal?' -(equal? (list 'a 'b) (list 'a 'b)) ; => #t -(equal? (list 'a 'b) (list 'b 'a)) ; => #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 + +;; `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 @@ -495,7 +530,7 @@ vec ; => #(1 2 3 4) ;; 8. Classes and Objects ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Create a class fish% (-% is idomatic for class bindings) +;; Create a class fish% (-% is idiomatic for class bindings) (define fish% (class object% (init size) ; initialization argument @@ -551,7 +586,7 @@ vec ; => #(1 2 3 4) (set! i (add1 i)))) ;; Macros are hygienic, you cannot clobber existing variables! -(define-syntax-rule (swap! x y) ; -! is idomatic for mutation +(define-syntax-rule (swap! x y) ; -! is idiomatic for mutation (let ([tmp x]) (set! x y) (set! y tmp))) @@ -600,6 +635,45 @@ vec ; => #(1 2 3 4) ;; expected: positive? ;; given: -5 ;; more details.... + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; 11. Input & output +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; Racket has this concept of "port", which is very similar to file +;; descriptors in other languages + +;; Open "/tmp/tmp.txt" and write "Hello World" +;; This would trigger an error if the file's already existed +(define out-port (open-output-file "/tmp/tmp.txt")) +(displayln "Hello World" out-port) +(close-output-port out-port) + +;; Append to "/tmp/tmp.txt" +(define out-port (open-output-file "/tmp/tmp.txt" + #:exists 'append)) +(displayln "Hola mundo" out-port) +(close-output-port out-port) + +;; Read from the file again +(define in-port (open-input-file "/tmp/tmp.txt")) +(displayln (read-line in-port)) +; => "Hello World" +(displayln (read-line in-port)) +; => "Hola mundo" +(close-input-port in-port) + +;; Alternatively, with call-with-output-file you don't need to explicitly +;; close the file +(call-with-output-file "/tmp/tmp.txt" + #:exists 'update ; Rewrite the content + (λ (out-port) + (displayln "World Hello!" out-port))) + +;; And call-with-input-file does the same thing for input +(call-with-input-file "/tmp/tmp.txt" + (λ (in-port) + (displayln (read-line in-port)))) ``` ## Further Reading |