Giter Club home page Giter Club logo

contextual's Introduction

contextual

A small library for Clojure and ClojureScript providing associative data structures that store metadata about their context in some larger data structure.

Rationale

A common idiom in functional programming is to walk a tree-like data structure of nested maps or vectors, processing each "node" of the tree with a function..

Sometimes, it is necessary to know "where" a given node is located within the data structure as a whole. For example, this is often the case when building a user interface, so user interaction events can be applied back to the same logical location in the tree.

Normally, this requires passing around additional book-keeping arguments to each function. Each function must be passed not just the node itself, but its "path" or context within the data structure as a whole.

This library provides contextual data structures for maps and vectors that track their own context, from some arbitrary root. They implement the full set of persistent map and vector interfaces and are full substitutes for Clojure(Script)'s map and vector datatypes.

At any point, an application may query a contextual object for its path relative to the root. Retrieving a "child" map or vector from a contextual data structure will yield another contextual object, with a path reflecting its key or index within its "parent". This is entirely seamless and requires no special functions or arguments. Intermediate functions can be agnostic to the fact that they are operating on contextual objects vs normal data structures.

Creating a contextual object or retrieving its path are constant-time operations.

For the purposes of equality semantics, contextual objects are always equivalent to their non-contextual counterparts. The path of a contextual object is not included in equality comparisons - it is effectively metadata (although it is not implemented using Clojure's metadata mechanism).

Usage

To create a contextual object, use contextual.core/contextualize, passing an associative data structure to wrap and (optionally) a path. If no path is given, an empty path with be used, implying that the given object is the root.

(def root (c/contextualize {:a [{:b {:c 1}} {:x 3}]}))

To retrieve the path of a contextual object, use contextual.core/context, which returns the path relative to the root.

(c/context root) ;; => []

Use any of Clojure's built in methods for retrieving nested values:

(def node (:b (first (root :a))))

(= node {:c 1}) ;; => true

(c/context node) ;; => [:a 0 :b]

Getting items via the sequence APIs returns contextual objects, too.

(map c/context (:a root)) ;;=> ([:a 0] [:a 1])
(map c/context (vals root)) ;;=> ([:a])

To unwrap the contextual object and get a normal data structure back, use contextual.core/decontextualize.

(c/decontextualize node) ;; => {:c 1}

Implementation

The library is implemented in terms of two protocols:

Contextual indicates a contextual object and supports the context and decontextualize protocol methods.

Two implementations are provided, DelegateMap and DelegateVec. These wrap maps and vectors (respectively), maintaining the object's path and delegating operations to the wrapped map or vector implementation.

The Contextualizable protocol provides the contextualize method, which converts the implemented type into an instance of Contextual. By default it is extended to all of Clojure(Script)'s default persistent map and vector types, clients may extend it to additional types if necessary.

License

Copyright © 2015 Cognitect, Inc

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

contextual's People

Contributors

levand avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.