Permalink
Browse files

fixed curried functions

  • Loading branch information...
1 parent cf2051d commit 39806b3c60bfddacb846bb6fbe4f3390c4d6c357 @dnaumov committed Apr 12, 2012
Showing with 27 additions and 17 deletions.
  1. +2 −0 src/contracts/core.clj
  2. +12 −9 src/contracts/curried.clj
  3. +2 −2 test/contracts/test/core.clj
  4. +11 −6 test/contracts/test/tutorial.clj
View
2 src/contracts/core.clj
@@ -80,4 +80,6 @@
(for [clause clauses]
`(provide-contract ~@clause))))
+
(load "preds")
+(load "curried") ; this line should be commented out during development
View
21 src/contracts/curried.clj
@@ -1,13 +1,16 @@
+(in-ns 'contracts.core)
+
(defmacro ^:private defcurried
- ([name]
- (let [clj-var (ns-resolve 'clojure.core name)]
- `(-> (defn ~name
- ([a#] (partial ~clj-var a#))
- ([a# b#] (~clj-var a# b#)))
- (alter-meta! merge (meta ~clj-var)))))
- ([name & names]
- `(do (defcurried ~name)
- (defcurried ~@names))))
+ [& names]
+ (->> (for [name names
+ :let [clj-var (ns-resolve 'clojure.core name)
+ doc (str "Curried version of clojure.core/" name)
+ args (->> clj-var meta :arglists (take 2))]]
+ `(do (defn ~name
+ ([a#] (partial ~clj-var a#))
+ ([a# b#] (~clj-var a# b#)))
+ (alter-meta! (var ~name) assoc :doc ~doc :arglists '~args)))
+ (cons `do)))
(defcurried
= == not= < > <= >=
View
4 test/contracts/test/core.clj
@@ -1,5 +1,5 @@
(ns contracts.test.core
- (:use [contracts.core :as c :exclude [=>]] :reload)
+ (:require [contracts.core :as c] :reload)
(:use [midje.sweet]))
(fact "Simple contracts with explicit arguments"
@@ -101,7 +101,7 @@
(defn constrained-inc [x] (inc x))
(defn constrained-dec [x] (dec x))
-(provide-contracts
+(c/provide-contracts
(constrained-inc (c/=> number? number?))
(constrained-dec [number? => number?]))
View
17 test/contracts/test/tutorial.clj
@@ -187,7 +187,7 @@
(provide-contract sum
(c/=> ([(c/coll-of number?)]
- [fn? (c/coll-of number?)])
+ [fn? (c/coll-of number?)])
number?))
;; As you can see, we've wrapped preconditions for different arities
@@ -239,7 +239,7 @@
(provide-contract sum
(c/=> ([(c/coll-of number?)]
- [(c/=> number? number?) (c/coll-of number?)])
+ [(c/=> number? number?) (c/coll-of number?)])
number?))
;; We've replaced `fn?` predicate with another `c/=>` call. That's
@@ -358,7 +358,12 @@
(c/=> [x y]
{x (c/and number? (c/not neg?))
y (c/and number? (c/not neg?))}
- (partial <= (Math/sqrt (* x y)))))
+ (c/<= (Math/sqrt (* x y)))))
+
+;; Pay attention to the `c/<=` call; for your convenience,
+;; clojure-contracts includes curried versions of the most commonly
+;; used predicates from clojure.core, so it's possible to simply write
+;; `(c/<= ...)` instead of `(partial <= ...)`.
;; Of course, this contract will never be violated as long as valid
;; input is given to the function (which is ensured by preconditions)
@@ -422,11 +427,11 @@
(provide-contracts
(forward (c/=> [this]
- {this (partial satisfies? Movement)}
+ {this (c/satisfies? Movement)}
(fn [result]
(ahead? result this))))
(backward (c/=> [this]
- {this (partial satisfies? Movement)}
+ {this (c/satisfies? Movement)}
(fn [result]
(ahead? this result)))))
@@ -488,7 +493,7 @@
;; provide the appropriate contract. Let's add some implementations
;; and check how they work:
-(comment ;; ** TODO **
+(comment
(defmethod mean :arithmetic [x y]
(/ (+ x y) 2))

0 comments on commit 39806b3

Please sign in to comment.