Open jiacai2050 opened 8 years ago
From a high-level perspective, namespaces can be likened to a two-level mapping, where the first level is a symbol to a namespace containing mappings of symbols to Vars.
ns
宏可以包含以下几种指令:
(:require ...)
(:import ...)
(:use ...)
(:refer-clojure ...)
(:gen-class ...)
(ns megacorp.profitd.scheduling
(:require [clojure.set :as cs]
[clojure.walk :as walk]))
(ns megacorp.profitd.scheduling
(:require [clojure.set :refer [difference intersection]]))
;; Now it is possible to do:
;; (difference #{1 2 3} #{3 4 5})
(ns megacorp.profitd.scheduling
(:import java.util.concurrent.Executors
java.util.concurrent.TimeUnit
java.util.Date))
(ns megacorp.profitd.scheduling
(:import [java.util.concurrent Executors TimeUnit]
java.util.Date))
(ns megacorp.profitd.scheduling
(:refer-clojure :exclude [find]))
(ns megacorp.profitd.scheduling-test
(:use clojure.test :only [deftest testing is]))
这相当于 Clojure 1.4 之前的
(ns megacorp.profitd.scheduling-test
(:require clojure.test :refer [deftest testing is]))
现在比较推荐refer
的方式
Keywords always refer to themselves. What this means is that the keyword :magma always has the value :magma, whereas the symbol ruins may refer to any legal Clojure value or reference.
In a nutshell, symbols are primarily used to provide a name for a given value. But in Clojure, symbols can also be referred to directly, by using the symbol
or quote
function or the '
special operator. Symbols tend to be discrete entities from one lexical contour to another, and often even within a single contour. Unlike keywords, symbols aren’t unique based solely on name alone, as you can see in the following:
(identical? 'goat 'goat)
;=> false
Symbols differ from strings in that you can test equality by comparing a pointer.
(def a-to-j (vec (map char (range 65 75))))
a-to-j
;=> [\A \B \C \D \E \F \G \H \I \J]
(nth a-to-j 4)
(get a-to-j 4)
(a-to-j 4)
All three of these do the same work and each returns \E:
(assoc a-to-j 4 "no longer E")
;=> [\A \B \C \D "no longer E" \F \G \H \I \J]
(replace {2 :a, 4 :b} [1 2 3 2 3 4])
;=> [1 :a 3 :a 3 :b]
(def matrix
[[1 2 3]
[4 5 6]
[7 8 9]])
(get-in matrix [1 2])
;=> 6
(assoc-in matrix [1 2] 'x)
;=> [[1 2 3] [4 5 x] [7 8 9]]
(def my-stack [1 2 3])
(peek my-stack)
;=> 3
(pop my-stack)
;=> [1 2]
(conj my-stack 4)
;=> [1 2 3 4]
(+ (peek my-stack) (peek (pop my-stack)))
;=> 5
(defn strict-map1 [f coll]
(loop [coll coll, acc nil]
(if (empty? coll)
(reverse acc)
(recur (next coll) (cons (f (first coll)) acc)))))
(strict-map1 - (range 5))
;=> (0 -1 -2 -3 -4)
(defn strict-map2 [f coll]
(loop [coll coll, acc []]
(if (empty? coll)
acc
(recur (next coll) (conj acc (f (first coll)))))))
(strict-map2 - (range 5))
;=> [0 -1 -2 -3 -4]
(cons 1 '(2 3))
;=> (1 2 3)
(conj '(2 3) 1)
;=> (1 2 3)
(defmethod print-method clojure.lang.PersistentQueue
[q, w]
(print-method '<- w) (print-method (seq q) w) (print-method '-< w))
(def schedule
(conj clojure.lang.PersistentQueue/EMPTY
:wake-up :shower :brush-teeth))
<-(:wake-up :shower :brush-teeth)-<
(defn slope
[& {:keys [p1 p2] :or {p1 [0 0] p2 [1 1]}}]
(float (/ (- (p2 1) (p1 1))
(- (p2 0) (p1 0)))))
(slope :p1 [4 15] :p2 [3 21])
;=> -6.0
(slope :p2 [2 1])
;=> 0.5
(slope)
;=> 1.0
Clojure is a design language where the conceptual model is also Clojure.
(ns learn-by-doing.contract)
(declare collect-bodies)
(defmacro contract
[name & forms]
;; `(fn ~name (collect-bodies ~forms))
(list* `fn name (collect-bodies forms))
)
(declare build-contract)
(defn collect-bodies [forms]
(for [p (partition 3 forms)]
(build-contract p)))
(defn build-contract [form]
(let [args (first form)]
(list
(into ['f] args)
(apply merge
(for [con (rest form)]
(cond
(= (first con) :require) (assoc {} :pre (vec (rest con)))
(= (first con) :ensure) (assoc {} :post (vec (rest con)))
:else (throw (Exception. (str "Unknown tag" (first con)))))))
(list* 'f args)
;; (lazy-seq (into ['f] args))
)))
(def double-contract
(contract doubler
[x]
(:require (pos? x))
(:ensure (= (* x 2) %))))
;; (fn doubler
;; ([f x]
;; {:post [(= (* 2 x) %)],
;; :pre [(pos? x)]}
;; (f x)))
(def times2 (partial double-contract #(* 2 %)))
(times2 2)
;; (def times3 (partial double-contract #(* 3 %)))
;; (times3 10)
(def doubler-contract
(contract doubler
[x]
(:require (pos? x))
(:ensure (= (* x 2) %))
[x y]
(:require (pos? x) (pos? y))
(:ensure (= (* 2 (+ x y)) %))))
(doubler-contract #(* % 2) 4)
(doubler-contract #(* 2 (+ %1 %2)) 4 3)
main.java