Skip to content

Instantly share code, notes, and snippets.

@scsibug
Created February 16, 2012 00:53
Show Gist options
  • Save scsibug/1840394 to your computer and use it in GitHub Desktop.
Save scsibug/1840394 to your computer and use it in GitHub Desktop.
Clojure 7-lang
(ns seven-lang-clojure.test.core
(:require [seven-lang-clojure.core])
(:use [seven-lang-clojure.core])
(:use [clojure.test])
(:import [seven_lang_clojure.core SimpleBOM Account]))
(deftest big-test
(is (not (big "blah" 4)))
(is (big "blah" 3))
(is (not (big "" 0)))
(is (not (big "foo" 3)))
(is (not (big "" 0)))
(is (big "a" 0)))
(deftest collection-type-test
(is (= (collection-type '(1 2 3)) :list))
(is (= (collection-type (list)) :list))
(is (= (collection-type [1 2 3]) :vector))
(is (= (collection-type []) :vector))
(is (= (collection-type (hash-map)) :map))
(is (= (collection-type (hash-map 1 2)) :map)))
(deftest unless-test
(is (= (unless true 1 2) 2))
(is (= (unless false 1 2) 1))
(is (= (unless (= 1 1) 1 2) 2)))
(deftest bom-test
(let [b (SimpleBOM. "root" '(123 456))]
(is (= (description b) "root"))
(is (= (children b) '(123 456)))))
(deftest account-test
(let [acct (make-account-ref 100)]
(is (= (balance @acct) 100))))
(deftest account-vector-test
(let [accts [(make-account-ref 70)
(make-account-ref 0)
(make-account-ref 30)]]
(defn accounts-sum-to [total]
(is (= (+ (balance @(get accts 0))
(balance @(get accts 1))
(balance @(get accts 2))) total)))
;; move $10 from account 0 to account 1
(account-transfer (get accts 0) (get accts 1) 10)
(is (= (balance @(get accts 0)) 60))
(is (= (balance @(get accts 1)) 10))
(accounts-sum-to 100)
;; Move $10 from account 0 to account 3
;; Move $5 from account 3 to account 1
(account-transfer (get accts 0) (get accts 2) 10)
(account-transfer (get accts 2) (get accts 1) 5)
(is (= (balance @(get accts 0)) 50))
(is (= (balance @(get accts 1)) 15))
(is (= (balance @(get accts 2)) 35))
(accounts-sum-to 100)))
(ns seven-lang-clojure.core)
;;; Implement a function called (big st n) that returns true if a string st
;;; is longer than n characters.
(defn big [st n] (> (.length st) n))
;;; Write a function called (collection-type col) that returns :list,
;;; :map, or :vector based on the type of collection col.
(defn collection-type [col]
(cond (map? col) :map
(list? col) :list
(vector? col) :vector
:else :unknown))
;;; Implement an unless with an else condition using macros
(defmacro unless [test body else]
(list 'if (list 'not test) body else))
;;; Write a type using defrecord that implements a protocol
(defprotocol BillOfMaterial
(description [b])
(children [b]))
(defrecord SimpleBOM [d c]
BillOfMaterial
(description [_] d)
(children [_] c))
;;; Use refs to create a vector of accounts in memory. Create debit
;;; and credit functions to change the balance of an account.
(defprotocol IAccount
(credit [acc amount])
(debit [acc amount])
(balance [acc]))
(defrecord Account [balance]
IAccount
(credit [acc amount] (Account. (+ balance amount)))
(debit [acc amount] (Account. (- balance amount)))
(balance [acc] (:balance acc)))
;; Move funds between two account references, using a transaction
(defn account-transfer [acc-ref dest-ref amount]
(dosync (ref-set acc-ref (debit @acc-ref amount))
(ref-set dest-ref (credit @dest-ref amount))))
;; Create a new account reference with a starting balance
(defn make-account-ref [starting-balance]
(ref (Account. starting-balance)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment