Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (defn ^{:private true}
- maybe-destructured
- [params body]
- (if (every? symbol? params)
- (cons params body)
- (loop [params params
- new-params []
- lets []]
- (if params
- (if (symbol? (first params))
- (recur (next params) (conj new-params (first params)) lets)
- (let [gparam (gensym "p__")]
- (recur (next params) (conj new-params gparam)
- (-> lets (conj (first params)) (conj gparam)))))
- `(~new-params
- (let ~lets
- ~@body))))))
- (defmacro fn
- "params => positional-params* , or positional-params* & next-param
- positional-param => binding-form
- next-param => binding-form
- name => symbol
- Defines a function"
- {:added "1.0", :special-form true,
- :forms '[(fn name? [params* ] exprs*) (fn name? ([params* ] exprs*)+)]}
- [& sigs]
- (let [name (if (symbol? (first sigs)) (first sigs) nil)
- sigs (if name (next sigs) sigs)
- sigs (if (vector? (first sigs)) (list sigs) sigs)
- psig (fn* [sig]
- (let [[params & body] sig
- conds (when (and (next body) (map? (first body)))
- (first body))
- body (if conds (next body) body)
- conds (or conds (meta params))
- pre (:pre conds)
- post (:post conds)
- body (if post
- `((let [~'% ~(if (< 1 (count body))
- `(do ~@body)
- (first body))]
- ~@(map (fn* [c] `(assert ~c)) post)
- ~'%))
- body)
- body (if pre
- (concat (map (fn* [c]
- `(if (vector? ~c) (assert ~@c) (assert ~c)))
- pre)
- body)
- body)]
- (maybe-destructured params body)))
- new-sigs (map psig sigs)]
- (with-meta
- (if name
- (list* 'fn* name new-sigs)
- (cons 'fn* new-sigs))
- (meta &form))))
Advertisement
Add Comment
Please, Sign In to add comment