Scheme notes
Notes
tinyscheme
has some functions missing unlessinit.scm
is added to the current directory. (*) means that implementation needsinit.scm
.
First item of a list
Scheme
(car list)
Clojure
(first list)
All items except the first
Scheme
(cdr list)
Clojure
(rest list)
Prepend item to list
Scheme
(cons '(1 2 3 4))
Clojure
(first [1 2 3 4])
Print to terminal
Scheme
(display "Hello, world!\n")
Clojure
(println "Hello, world!\n")
Open REPL
Scheme
chezscheme [FILE]
Clojure
lein repl
Run file
Scheme
chezscheme --script [FILE]
Clojure
lein run
Compile a
Scheme
csc [FILE]
Clojure
lein uberjar
Apply a function to all elements of list
Scheme
(map add1 '(1 2 3 4))
; => (2 3 4 5)
Clojure
(map inc [1 2 3 4])
; => [2 3 4 5]
Apply a function for all the items in pairs
Scheme
(define reduce
(lambda (fn list)
((null? list) '())))
(reduce + '(1 2 3 4 5))
;; => 15
Clojure
(reduce + [1 2 3 4 5])
;; => 15
Check for empty list
Scheme
(null? list)
Clojure
(empty? list)
Combine strings
Scheme
(string-append "hello" "world")
; => "helloworld"
Clojure
(str "hello" "world")
; => "helloworld"
If statement
Scheme
(cond
((> 1 2) #t)
(else #f))
or (*)
(if (> 1 2)
#t
#f)
Clojure
(if (> 1 2)
true
false)
Do one operation after the other
Scheme
(begin
(+ 1 2)
(+ 2 3))
Clojure
(do
(+ 1 2)
(+ 2 3))
If statement with multiple operations
Scheme
(when #t
(+ 1 2)
(+ 3 4))
Clojure
(when true
(+ 1 2)
(+ 3 4))
Check for equality
(equal? 1 "Hello")
;; => #f
Clojure
(= 1 "Hello")
;; => false
Assign variable
(define name "Michael")
name
; => Michael
(def name "Michael")
name
; => Michael
Define function
(define add1
(lambda (x)
(+ 1 x)))
(add1 7)
; => 8
(defn add1
[x]
(+ 1 x))
(add1 7)
; => 8
Hash tables/maps
Scheme
R5RS doesn't really include hash tables (it was included in R6RS). Some Scheme implentations have them by adding SRFI 69 but the most basic Schemes don't have it. A (less efficient) alternative are (improper) association lists:
(define person
'((first-name . "John")
(last-name . "Smith")))
person
; => (("first-name" . "John") ("last-name" . "Smith"))
Clojure
(def person
{:first-name "John"
:last-name "Smith"})
person
; => {:first-name "John", :last-name "Smith"}
Create hash-map
Scheme
Equivalent with association lists:
(define alist
(lambda args
(cond
((null? args) '())
(else
(cons (cons (car args) (cadr args))
(apply alist (cddr args)))))))
(alist 'a '1 'b '2)
Clojure
(hash-map :a 1 :b 2)
Pass list as arguments
Scheme
(apply + '(1 2 3))
Clojure
(apply + [1 2 3])
Nested hash maps
Scheme
'(name ((first . "John") (middle . "Jacob") (last . "Smith"))
Clojure
"{:name {:first "John" :middle "Jacob" :last "Smith"}}"
Create hash map accepting nested hash maps
Scheme
(define alist
(lambda args
(cond
((null? args) '())
((list? (cadr args))
(cons (cons (car args) (list (cadr args)))
(apply alist (cddr args))))
(else
(cons (cons (car args) (cadr args))
(apply alist (cddr args)))))))
(alist 'name '((first . "John") (middle . "Jacob") (last . "Smith")))
Clojure
(hash-map :name {:first "John" :middle "Jacob" :last "Smith"})
Equivalences
Scheme*
If comparing… | then use… |
---|---|
numbers | = |
non numeric | eqv? |
strings | string=? (*) |
lists | equal? |
don't use | eq? |
Look up values
Scheme
(define get
(lambda (alist key)
(cdr (assoc key alist))))
(get '((a . 0) (b . ((c . "ho hum")))) 'b)
; => ((c . ho hum))
technically, Scheme also accepts:
(get '((:a . 0) (:b . ((:c . "ho hum")))) 'b)
but
'a
in Scheme is a symbol- Clojure has symbols and keywords
:a
in Clojure is a keyword, not a symbol
Clojure
(get {:a 0 :b {:c "ho hum"}} :b)
; => {:c "ho hum"}
Write to file
Scheme(*)
(call-with-output-file "out.txt"
(lambda (p)
(begin
(write "Hello, world!" p)
(newline p))))
Check if file exists
Scheme
Not the most elegant but I think should work.
(define file-exists?
(lambda (file)
(let ((port (open-input-file file)))
(if (port? port)
(close-input-port port)
#f))))
(file-exists? "/bin/bash")
; => #t
(file-exists? "/bin/bosh")
; => #f