• Stars
    star
    204
  • Rank 192,063 (Top 4 %)
  • Language
    Clojure
  • License
    MIT License
  • Created almost 8 years ago
  • Updated about 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Clojure's update with superpowers.

supdate

Clojure's update with superpowers.

Clojars Project

This library provides a supdate macro which lets you transform Clojure data structures declaratively, using a data-driven specification which structure matches the schema of the input.

The benefit is that such specifications eliminate a lot of the boilerplate code involved when transforming nested data structures.

In addition, supdate is a macro that leverages static information on a best-effort basis in order to make the performance comparable to hand-written code. Dynamic pre-compilation (via compile) is also available to achieve better performance while remaining fully dynamic.

Usage

(require '[vvvvalvalval.supdate.api :as supd :refer [supdate]])

;; canonical example
(def my-input
  {:a 1
   :b [1 2 3]
   :c {"d" [{:e 1 :f 1} {:e 2 :f 2}]}
   :g 0
   :h 0
   :i 0})

(supdate
  my-input
  {:a inc
   :b [inc]
   :c {"d" [{:e inc}]}
   :g [inc inc inc]
   :my-missing-key inc
   :i false
   })
=> {:a 2,
    :b [2 3 4],
    :c {"d" [{:e 2, :f 1} {:e 3, :f 2}]}
    :g 3,
    :h 0}

See also the tests for more examples.

Emulating standard library operations

supdate generalizes several functions of Clojure's standard library:

;;;; Emulating clojure.core/update
(update {:a 1 :b 1} :a inc)
=> {:a 2 :b 1}
(supdate {:a 1 :b 1} {:a inc})
=> {:a 2 :b 1}

;;;; Emulating clojure.core/update-in
(update-in {:a {"b" [{:c 1}]}}
  [:a "b" 0 :c] inc)
=> {:a {"b" [{:c 2}]}}
(supdate {:a {"b" [{:c 1}]}}
  {:a {"b" {0 {:c inc}}}})
=> {:a {"b" [{:c 2}]}}
;; NOTE: unlike update-in, if a key is missing in the input, 
;; the transformation will be skipped instead of creating new maps.

;;;; Emulating clojure.core/map 
(map dec (range 10))
=> (-1 0 1 2 3 4 5 6 7 8)
(supdate (range 10) [dec])
=> (-1 0 1 2 3 4 5 6 7 8)
;; Note: unlike map, if the input is a vector, the output will also be a vector.

;;;; Emulating dissoc
(dissoc {:a 1 :b 2 :c 3}
  :a :b :d)
=> {:c 3}
(supdate {:a 1 :b 2 :c 3}
  {:a false :b false})
=> {:c 3}

Pre-compiling transforms

A compile function is available to make execution faster:

(def transform
  (supd/compile {:a inc
                 :b [inc]
                 :c {"d" [{:e inc}]}
                 :g [inc inc inc]
                 :missing-key inc
                 :i false
                 }))

(transform {:a 1
            :b [1 2 3]
            :c {"d" [{:e 1 :f 1} {:e 2 :f 2}]}
            :g 0
            :h 0
            :i 0})
=> {:a 2,
    :b [2 3 4],
    :c {"d" [{:e 2, :f 1} {:e 3, :f 2}]}
    :g 3,
    :h 0}

Comparison to Specter

This library is in the same space as Specter, but we don't see it as a replacement to Specter. We believe this library is useful in situations where using Specter is overkill.

More specifically:

  • Specter's transform is useful for making one sophisticated transformation, whereas supdate is good at making many basic transformations at once.
  • Specter provides a select operation, supdate is only about transformation.
  • Arguably, supdate is easier to learn.
  • Specter is extensible, supdate is not.

License

Copyright Β© 2016 Valentin Waeselynck and contributors

Distributed under the MIT License.

More Repositories

1

scope-capture

Project your Clojure(Script) REPL into the same context as your code when it ran
Clojure
574
star
2

datomock

Mocking and forking Datomic Peer connections in-memory.
Clojure
130
star
3

datofu

there's a :db/fn for that
Clojure
129
star
4

reagent-phonecat-tutorial

The official AngularJS 'Phonecat' tutorial ported to ClojureScript + React (Reagent).
Clojure
60
star
5

datalog-rules

Utilities for managing Datalog rulesets from Clojure
Clojure
48
star
6

reagent-phonecat

(MOVED) - The official AngularJS 'Phonecat' tutorial ported to a ClojureScript + Reagent stack.
Clojure
33
star
7

scope-capture-nrepl

nREPL middleware for scope-capture
Clojure
30
star
8

promise-dag

Chain promises declaratively using high-level graphs. Tiny, portable, dependency-free.
JavaScript
25
star
9

datascript-declarative-model-example

Clojure
22
star
10

mapdag

Map computations expressed as dependency graphs of named steps. Includes high-performance execution strategies for the JVM.
Clojure
8
star
11

reagent-pluggable-components-poc

Clojure
4
star
12

xml-pull

Pulling nested Clojure data structures from XML documents, declaratively and efficiently.
Clojure
4
star
13

m12

Environment for experimenting a 12-digits notation for music
Clojure
4
star
14

d2q-examples

Examples of using d2q in combination with various data storages / backends.
Clojure
3
star
15

Graph-Theory-Bondy-Murty-2008-study-notes

Study notes and some exercise hints / solutions for the classic "Graph Theory" textbook by Bondy and Murty.
3
star
16

val-on-programming

Source for the 'Val on Programming' blog
HTML
2
star
17

clj-inline-caching

Clojure
1
star
18

onodrim

enhanced Datomic entities
Clojure
1
star
19

ecolog10

On the use of logarithmic representations for planning GHG emissions reductions
Clojure
1
star
20

advent-of-code-2017

Clojure
1
star
21

vvvvalvalval.github.io

My blog on programming
HTML
1
star
22

software-notions-checklist

A checklist for programmers who don't know what they don't know.
JavaScript
1
star
23

reddit_bots

Clojure
1
star
24

breakform

DEPRECATED use scope-capture instead - Easier REPL-based debugging by saving and restoring snapshots of the local environment
Clojure
1
star
25

clojure-kata-compute-graph

A Clojure kata: implementing a library for expressing computations as a dependency graph.
Clojure
1
star