Skip to content
Browse files

Adding more info on reference invars to README

  • Loading branch information...
1 parent 64e1a1e commit 73bb3cdbb1549b901ddb7e6c68413933ea1c4679 @fogus committed
Showing with 50 additions and 94 deletions.
  1. +50 −9 README.md
  2. +0 −85 src/trammel/core.clj
View
59 README.md
@@ -41,26 +41,23 @@ Example
(use '[trammel.core :only (defconstrainedrecord)])
- (defconstrainedrecord Foo [a 1 b 2]
+ (defconstrainedrecord Foo [a b]
"Foo record fields are expected to hold only numbers."
[(every? number? [a b])]
Object
(toString [this] (str "record Foo has " a " and " b)))
;; default ctor with default values
- (->Foo)
+ (->Foo 1 2)
;=> #:user.Foo{:a 1, :b 2}
- ;; kwarg ctor
- (->Foo :a 42)
- ;=> #:user.Foo{:a 42, :b 2}
-
;; use like any other map/record
- (assoc (->Foo) :a 88 :c "foo")
+ (assoc (->Foo 1 2) :a 88 :c "foo")
;=> #:user.Foo{:a 88, :b 2, :c "foo"}
;; invariants on records checked at runtime
- (assoc (->Foo) :a "foo")
+ (assoc (->Foo 1 2) :a "foo")
+ ; Pre-condition failure: Foo record fields are expected to hold only numbers.
; Assert failed: (every? number? [a b])
```
@@ -99,10 +96,19 @@ Example
;=> 1
(swap! a str)
+ ; Pre-condition failure: only numbers allowed
+
(compare-and-set! a 0 "a")
+ ; Pre-condition failure: only numbers allowed
```
+The same will work on all reference types, including:
+
+* **Refs** - Invariants checked in a transaction
+* **Agents** - Invariants checked on `send` and `send-off`, assertion errors handled as normal agent errors
+* **Vars** - Invariants checked on `binding`
+
Getting
-------
@@ -142,7 +148,6 @@ Trammel is in its infancy but I think that I have a nice springboard for experim
- `defconstraint` -- with ability to relax requires and tighten ensures
- Study the heck out of Racket Scheme (in progress)
- Modify macros to also allow regular Clojure constraint maps
- - Reference contracts
- Make the `anything` constraint cheap (elimination)
- Allow other stand-alones: true/false, numbers, characters, regexes
- Make `provide-contracts` more amenable to REPL use
@@ -231,4 +236,40 @@ Type the following into a REPL session to see how Trammel might be used.
(Math/sqrt x))
(* (sqrt 30) (sqrt 30))
+
+ (def ag (constrained-agent 0
+ "only numbers allowed"
+ [number?]))
+
+ (send ag str)
+
+ @ag
+
+ (agent-error ag)
+
+ (def r (constrained-ref 0
+ "only numbers allowed"
+ [number?]))
+
+ (dosync (alter r inc))
+
+ (dosync (alter r str))
+
+ (def a (constrained-atom 0
+ "only numbers allowed"
+ [number?]))
+
+ @a
+
+ (swap! a inc)
+
+ (swap! a str)
+ (compare-and-set! a 0 "a")
+
+ (defconstrainedvar ^:dynamic foo 0
+ "only numbers allowed in Var foo"
+ [number?])
+
+ (binding [foo :a] [foo])
+
```
View
85 src/trammel/core.clj
@@ -366,88 +366,3 @@
(fn [x#] true)))
r#)))
-
-(comment
- (def ag (constrained-agent 0
- "only numbers allowed"
- [number?]))
-
- (send ag str)
-
- @ag
-
- (agent-error ag)
-
- (def r (constrained-ref 0
- "only numbers allowed"
- [number?]))
-
- (dosync (alter r inc))
-
- (dosync (alter r str))
-
- (def a (constrained-atom 0
- "only numbers allowed"
- [number?]))
-
- @a
-
- (swap! a str)
- (compare-and-set! a 0 "a")
-
- (defconstrainedvar ^:dynamic foo 0
- "only numbers allowed in Var foo"
- [number?])
-
- (macroexpand '(defconstrainedvar ^:dynamic foo 0
- "only numbers allowed"
- [number?]))
-
- (var-set (var foo) 42)
-
- (binding [foo :a] [foo])
-
- (use 'trammel.factors)
-
- (defconstrainedfn leap-year?
- [year],[number? pos? =>]
- (and (= (mod year 4) 0)
- (not (some #{(mod year 400)}
- [100 200 300]))))
-
- (leap-year? 111)
- (let [year 0]
- (in (mod year 400)
- 100 200 300))
-
- (defconstrainedfn sqr
- [n],[number? => pos? number?]
- (* n n))
-
- (sqr 0)
-
- (defn sqr [n] (* n n))
-
- (sqr 0)
-
- (require '[trammel.provide :as provide])
-
- (provide/contracts
- [sqr "given a number not equal to zero, sqr ensures that it returns a positive number"
- [x] [number? (not= 0 x) => number? pos?]])
-
- (sqr 10)
-
- (sqr 0)
- (sqr -1)
-
- (defconstrainedrecord Foo [a 1 b 2]
- "Foo record fields are expected to hold only numbers."
- [(every? number? [a b])]
- Object
- (toString [this] (str "record Foo has " a " and " b)))
-
- (assoc (->Foo) :a "foo")
-
-)
-

0 comments on commit 73bb3cd

Please sign in to comment.
Something went wrong with that request. Please try again.