Last active
November 12, 2019 04:16
-
-
Save JoshuaSkootsky/53402d8c528e36e8ea463d5fc106c652 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; This is a file I had lying around where I went through the beginning of SCIP (A scheme book) and translated it | |
; into Clojure as I went. Perfect for a gist? | |
; Joshua Skootsky, 2016 | |
; See xkcd #312 | |
Clojure : Scheme | |
def : define var | |
defn : define function | |
Clojure: | |
(defn square "Docstring - squares a number" [variable_1_to_be_squared] | |
(* variable_1_to_be_squared variable_1_to_be_squared )) | |
Scheme: | |
(define (square x) (* x x)) | |
Clojure: | |
(defn square [x] (* x x)) | |
lojure-noob.core=> (defn square [x] (* x x)) | |
#'clojure-noob.core/square | |
clojure-noob.core=> (square 6) | |
36 | |
clojure-noob.core=> (defn sum-of-squares [x y] "Sum of two squares" | |
#_=> (+ (square x) (square y))) | |
#'clojure-noob.core/sum-of-squares | |
clojure-noob.core=> (sum-of-squares 3 4) | |
25 | |
clojure-noob.core=> (defn f [a] "Does something with sum of squares" | |
#_=> (sum-of-squares (+ a 1) (* a 2))) | |
#'clojure-noob.core/f | |
clojure-noob.core=> (f 5) | |
136 | |
Scheme: | |
(define (abs x) | |
(cond ((> x 0) x) | |
((= x 0) 0) | |
((< x 0) (- x)))) | |
Clojure: | |
(defn abs [x] "Takes the absolute value of x" | |
(cond (> x 0) x | |
(= x 0) 0 | |
(< x 0) (- x))) | |
Scheme: | |
(define (abs x) | |
(cond ((< x 0) (- x)) | |
(else x))) | |
Clojure: | |
(defn abs [x] "Gives absolute value of x" | |
(cond | |
(< x 0) (- x) | |
:else x)) | |
Scheme: | |
(define (abs x) | |
(if (< x 0) | |
(- x) x)) | |
Clojure: | |
(defn abs [x] "Gives absolute value of x" | |
(if (< x 0) | |
(- x) x)) | |
Scheme: | |
(define (a-plus-abs-b a b) | |
((if (> b 0) + -) a b)) | |
Clojure: | |
(defn a-plus-abs-b [a b] | |
((if (> b 0) + -) a b)) | |
Newton's method | |
Scheme: | |
(define (sqrt-iter guess x) | |
(if (good-enough? guess x) | |
guess | |
(sqrt-iter (improve guess x) | |
x))) | |
(define (improve guess x) | |
(average guess (/ x guess))) | |
(define (average x y) | |
(/ (+ x y) 2)) | |
(define (good-enough? guess x) | |
(< (abs (- (square guess) x)) 0.001)) | |
Clojure: | |
(defn sqrt-iter [guess x] "Iteratively calculate square root x based on a guess and Newton's method" | |
(if (good-enough? guess x) guess | |
(sqrt-iter (improve guess x) x) | |
) | |
) | |
(defn improve [guess x] "Improves a guess of x" | |
(average guess (/ x guess))) | |
(defn average [x y] "Takes the average of x and y" | |
(/ (+ x y) 2)) | |
(defn good-enough? [guess x] "Checks to see if a guess is good enough" | |
(< (abs (- (square guess) x)) 0.001)) | |
Copy into REPL: | |
;;;; Square root approximation method | |
(defn abs [x] "Gives absolute value of x" | |
(if (< x 0) | |
(- x) x)) | |
(defn square [x] (* x x)) | |
(defn good-enough? [guess x] "Square guess to see if it could be the square root of x" | |
(< (abs (- (square guess) x)) 0.001)) | |
(defn average [x y] "Calculate mean of two terms, x and y" | |
(/ (+ x y) 2)) | |
(defn improve [guess x] "Improves a guess (square root of x?) by averaging with x/guess" | |
(average guess (/ x guess))) | |
(defn sqrt-iter [guess x] "Iteratively calculate square root x based on a guess and Newton's method" | |
(if (good-enough? guess x) guess | |
(sqrt-iter (improve guess x) x))) | |
(defn sqrt [x] "Calculates Square root of x" | |
(sqrt-iter 1.0 x)) | |
Fibonacci | |
(defn fib [x] "Returns fib x" | |
(cond (= x 2) x | |
(= x 1) x | |
:else | |
(+ | |
(fib (- x 1)) | |
(fib (- x 2))))) | |
Memoize Fibonacci: | |
(def memo-fib (memoize fib)) | |
; memoizes for future use - first call is still slow | |
Recursive fib? | |
(defn fib [x] "Returns fib x" | |
(cond (= x 2) x | |
(= x 1) x | |
:else | |
(+ | |
(fib (- x 1)) | |
(fib (- x 2))))) | |
You want memoized fib to call the memoized fib | |
(def fib (memoize | |
(fn [n] | |
(if (>= 1 n) n | |
(+ | |
; fib is the memoized function | |
(fib (- n 1)) | |
(fib (- n 2))))))) | |
http://danmidwood.com/content/2013/02/24/exploring-clojure-memoization.html | |
This is an important pattern. | |
1.6 | |
Alyssa P. Hacker | |
if and cond | |
Can if be defined in terms of cond? | |
Scheme: | |
(define (new-if predicate then-clause else-clause) | |
(cond (predicate then-clause) | |
(else else-clause))) | |
Clojure version: | |
(defn new-if [predicate then-clause else-clause] "Is this an if?" | |
(cond predicate then-clause | |
:else | |
else-clause)) | |
;; seemingly this works | |
Alyssa writes a new part of the square root program: | |
Scheme: | |
(define (sqrt-iter guess x) | |
(new-if (good-enough? guess x) | |
guess | |
(sqrt-iter (improve guess x) | |
x))) | |
Clojure: | |
(defn sqrt-iter [guess x] "Uses a conditional if by Alyssa P. Hacker" | |
(new-if (good-enough? guess x) | |
guess | |
(sqrt-iter (improve guess x) | |
x))) | |
problems using Alyssa's new-if: | |
clojure-noob.core=> (sqrt 9) | |
StackOverflowError clojure.lang.Numbers$DoubleOps.multiply (Numbers.java:595) | |
;;;; Interesting! | |
; In Alyssa's new-if procedure, an infinite recursive loop occurs because the | |
; sqrt-iter procedure is evaluated, which evaluates its recursed sqrt-iter | |
; procedure, which evaluates its recursed sqrt-iter, and so on. | |
; | |
; The top-level sqrt-iter procedure in Alyssa's new-if procedure has no way | |
; to expand to its primitive reductions. | |
; | |
; The new-if's recursion problem didn't happen during Eva's two demonstration | |
; runs because the evaluated arguments were at their primitive reductions. | |
; | |
; The infinite recursive loop problem doesn't occur with if expressions | |
; because the consequent and alternative expressions behave as single | |
; expressions. The (sqrt-iter (improve guess x) x) alternative expression | |
; is evaluated only one time and not multiple times recursively as is | |
; done for conditional expressions. | |
https://github.com/raywritescode/sicp/blob/master/ch01/exercises/exercise-1.6.scm | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment