#lang racket (require htdp/testing) ; Symbols, Strings, Characters, Lists ; Robert Keller ; confused about the above? Maybe this will help. ; This file can be executed for further clarification. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; The following is a symbol: 'hello ; Unmatched single quote looks weird at first, but you get used to it. ; Symbols can't start with digits free-standing, e.g. '123abc ; Here's how to be sure we have a symbol: (check-expect (symbol? 'hello) #t) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Symbols are stored in a unique location in memory. ; Strings are stored as arrays of characters ; The same array of characters can be stored multiple times in different locations. "This is a string" (check-expect (string? "This is a string") #t) ; Symbols have a string that identifies them externally. ; A symbol's string can be obtained by (symbol->string). (check-expect (symbol->string 'hello) "hello") ; We tend not to embed blanks in symbols, because the appearance gets messy. (string->symbol "The result will be a symbol, not a string.") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Predicate string=? determines whether two strings have the same content. ; Below we are checking that the content of "hello" is the same as ; the result of converting a symbol. (check-expect (string=? "hello" (symbol->string 'hello)) #t) ; Predicate equal? is more general (applies to strings and other things) ; thus can be used for strings too. (check-expect (equal? "hello" (symbol->string 'hello)) #t) ; Predicate eq? tells whether two things are in the same memory location. ; Two identical strings may or may not be, as the following shows. (check-expect (eq? "hello" (symbol->string 'hello)) #f) (check-expect (eq? "hello" "hello") #t) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Function string->list creates a list of characters from a string (check-expect (string->list "hello") '(#\h #\e #\l #\l #\o)) ; Function list->string creates a string from a list of characters. (check-expect (list->string '(#\g #\o #\o #\d #\b #\y #\e)) "goodbye") ; The list must consist only of characters, not other stuff (check-error (list->string '(a b c 1 2 3))) ; The following works (check-expect (list->string '(#\a #\b #\c #\1 #\2 #\3)) "abc123") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; There is no built-in for going from a symbol directly to a list or ; vice-versa, but we can make one. (define (symbol->list S) (string->list (symbol->string S))) (check-expect (symbol->list 'hello) '(#\h #\e #\l #\l #\o)) (define (list->symbol L) (string->symbol (list->string L))) (check-expect (list->symbol '(#\a #\b #\c #\1 #\2 #\3)) 'abc123) ; Two of the same symbol (not string) will always be eq? to each other: (check-expect (eq? 'abc123 (list->symbol '(#\a #\b #\c #\1 #\2 #\3))) #t) ; The same rule for list->string still applies. ; Here the list is not a list of characters. (check-error (list->symbol '(a b c 1 2 3))) ; There are other handy functions for manipulating strings, such as string-split: (check-expect (string-split "This is a joy!") '("This" "is" "a" "joy!")) (check-expect (string-append "Not" "such" "a" "joy!") "Notsuchajoy!") (check-expect (string-join '("This" "is" "a" "joy!")) "This is a joy!") (generate-report)