diff options
Diffstat (limited to 'modules/fnmap')
-rw-r--r-- | modules/fnmap/pom.xml | 14 | ||||
-rw-r--r-- | modules/fnmap/src/main/clojure/clojure/contrib/fnmap.clj | 36 | ||||
-rw-r--r-- | modules/fnmap/src/main/clojure/clojure/contrib/fnmap/PersistentFnMap.clj | 70 |
3 files changed, 120 insertions, 0 deletions
diff --git a/modules/fnmap/pom.xml b/modules/fnmap/pom.xml new file mode 100644 index 00000000..7785e3e5 --- /dev/null +++ b/modules/fnmap/pom.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http//www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 + http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.clojure.contrib</groupId> + <artifactId>parent</artifactId> + <version>1.3.0-SNAPSHOT</version> + <relativePath>../parent</relativePath> + </parent> + <artifactId>fnmap</artifactId> +</project>
\ No newline at end of file diff --git a/modules/fnmap/src/main/clojure/clojure/contrib/fnmap.clj b/modules/fnmap/src/main/clojure/clojure/contrib/fnmap.clj new file mode 100644 index 00000000..cc9824c5 --- /dev/null +++ b/modules/fnmap/src/main/clojure/clojure/contrib/fnmap.clj @@ -0,0 +1,36 @@ +;;; fnmap.clj: maps that dispatch get/assoc to functions + +;; Copyright (c) Stuart Sierra, 2008. All rights reserved. The use +;; and distribution terms for this software are covered by the Eclipse +;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) +;; which can be found in the file epl-v10.html at the root of this +;; distribution. By using this software in any fashion, you are +;; agreeing to be bound by the terms of this license. You must not +;; remove this notice, or any other, from this software. + + +(ns ^{:author "Stuart Sierra" + :doc "Maps that dispatch get/assoc to user-defined functions. + + Note: requires AOT-compilation"} + clojure.contrib.fnmap + (:require clojure.contrib.fnmap.PersistentFnMap)) + +(defn fnmap + "Creates a fnmap, or functional map. A fnmap behaves like an + ordinary Clojure map, except that calls to get and assoc are + filtered through user-defined getter and setter functions, which + operate on an internal map. + + (getter m key) should return a value for key. + + (setter m key value) should assoc key with value and return a new + map for m. + + All other map operations are passed through to the internal map." + ([getter setter] (clojure.contrib.fnmap.PersistentFnMap/create getter setter)) + ([getter setter & keyvals] + (apply assoc + (clojure.contrib.fnmap.PersistentFnMap/create getter setter) + keyvals))) + diff --git a/modules/fnmap/src/main/clojure/clojure/contrib/fnmap/PersistentFnMap.clj b/modules/fnmap/src/main/clojure/clojure/contrib/fnmap/PersistentFnMap.clj new file mode 100644 index 00000000..dfa3af64 --- /dev/null +++ b/modules/fnmap/src/main/clojure/clojure/contrib/fnmap/PersistentFnMap.clj @@ -0,0 +1,70 @@ +;; PersistentFnMap.clj: implementation for clojure.contrib.fnmap + +;; Copyright (c) Stuart Sierra, 2009. All rights reserved. The use +;; and distribution terms for this software are covered by the Eclipse +;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) +;; which can be found in the file epl-v10.html at the root of this +;; distribution. By using this software in any fashion, you are +;; agreeing to be bound by the terms of this license. You must not +;; remove this notice, or any other, from this software. + + +;; Thanks to Meikel Brandmeyer for his work on lazymap, which made +;; this implementation easier. + + +(ns clojure.contrib.fnmap.PersistentFnMap + (:gen-class :extends clojure.lang.APersistentMap + :state state + :init init + :constructors {[clojure.lang.IPersistentMap] [], + [clojure.lang.IPersistentMap clojure.lang.IPersistentMap] [clojure.lang.IPersistentMap]})) + +(defn -init + ([theMap] [[] theMap]) + ([theMap metadata] [[metadata] theMap])) + +(defn create [getter setter] + (clojure.contrib.fnmap.PersistentFnMap. + {::getter getter ::setter setter})) + +;; IPersistentMap + +(defn -assoc [this key value] + (clojure.contrib.fnmap.PersistentFnMap. + ((::setter (. this state)) (. this state) key value))) + +;; Associative + +(defn- -containsKey [this key] + (not (nil? ((::getter (. this state)) this key)))) + +(defn- -entryAt [this key] + (clojure.lang.MapEntry. key ((::getter (. this state)) (. this state) key))) + +(defn -valAt + ([this key] + ((::getter (. this state)) (. this state) key)) + ([this key default] + (or ((::getter (. this state)) (. this state) key) + default))) + +;; Iterable + +(defn -iterator [this] + (.. this state iterator)) + +;; IPersistentCollection + +(defn -count [this] + (count (. this state))) + +(defn -seq [this] + (seq (. this state))) + +(defn -cons [this that] + (.. this state (cons this that))) + +(defn -empty [this] + (.. this state empty)) + |