• Stars
    star
    132
  • Rank 274,205 (Top 6 %)
  • Language
    Clojure
  • License
    Eclipse Public Li...
  • Created over 8 years ago
  • Updated over 7 years ago

Reviews

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

Repository Details

A library for building declarative data flow graphs via a fluent api and core.async

naiad

A library for building declarative data flow graphs via a fluent api and core.async.

Rationale

Premise

Core.async is simple but not easy. That is to say, it is possible to write simple maintainable using core.async but it is not a easy task. Often users want to deal with core.async channels in a way that mirrors lazy seqs but are somewhat hindered by the congitive overhead of using abstractions just as async/mult and async/pub. Naiad attempts to abstract the construction of data flow graphs in a declarative way. You specify the operations you want to apply to a set of channels, and then let Naiad work out how to wire it all up.

Tenets

The goals of Naiad are as follows:

  • Represent dataflow graphs as data, that can be manipulated via post-processing optimizers
  • Provide a fluent API that works well with threading macros: (-> (range 3) (take 2) (map inc))
  • Provide a keyword argument API that works well when needing to connect graphs (-> (range 3) (take 2 :out o :in))
  • Provide a map based API that works well with programatic data transformers (->take {:in (range 3) :n 2 :out o})
  • Do not introduce a large number of new macros. Should prefer functions over DSLs
  • Performance hints (such as parallel pipelining) should not require restructuring of code, it should be as simple as wrapping a block of code in a macro or function call.

Example 1:

Let's say you (for some strange reason) wanted to take a sequence of integers, square them, split them into odds and evens, then decrement the odds and increment the evens, sending the first 100 results into a output channel. The code may look something like this in core.async

(let [in-c (chan (map (fn [x] (* x x))))
      m (mult c)
      odds (chan (comp (filter odd?)
                       (map dec)))
      evens (chan (comp (filter even?)
                        (map inc)))
      final-chan (chan (take 100))]
  (tap m odds)
  (tap m evens)
  (onto-chan in-c (range 1000))
  (pipe (merge odds evens) final-chan)
  (pipe final-chan output-chan))

While the core.async code here is not complex, it is rather hard to read and comprehend, the flow of data does not match the normal human way of reading lisp code. In addition, some constructs like merge are ill suited to situations were we have a pre-existing output channel.

This same code written in Naiad would look something like this:

(require '[naiad :as n])

(n/flow
  (let [in-c (->> (n/range 1000)
                  (n/map (fn [x] (* x x))))

        odds (->> in-c
                  (n/filter odd?)
                  (n/map dec))

        evens (->> in-c
                   (n/filter even?)
                   (n/map inc))]
    (->> (n/merge odds evens)
         (n/->take :n 100 :out output-chan :in))))

The flow macro is not a complex deep-walking macro, but is simply a easy way of setting up some bindings and post-processing the resulting graph created by the other functions in the body of this snippet. The rest of the code is macro-free (except for let of course), this means that normal clojure constructs like apply and map will continue to work as expected, there is no black magic here.

License

Copyright ยฉ 2016 Timothy Baldridge

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

More Repositories

1

mjolnir

Clojure
266
star
2

odin

An embedded extensible logic DSL for Clojure.
Clojure
183
star
3

clojure-conj-2013-core.async-examples

The examples used in my Clojure Conj 2013
JavaScript
166
star
4

com.tbaldridge.hermod

A mailbox based distributed computing library
Clojure
81
star
5

build-your-own-logic-engine

Code from the 2018 Denver Clojure Meetup
Clojure
38
star
6

heliotrope

A lisp with support for fexprs and interpreter collapsing
Clojure
36
star
7

async-mu-kanren

A POC implementation of muKanren using CSP (core.async)
Clojure
31
star
8

reactive

Something that will someday be core.reactive for clojure
Clojure
31
star
9

clojure-py-redux

A re-write of clojure-py using ClojureScript + Python ASTs
Clojure
26
star
10

fafnir

A library to ease insertion of complex structures into Datomic
Clojure
25
star
11

deep-freeze

A pure Clojure serializer/deserializer
Clojure
21
star
12

clojure-tutorial-source

Clojure
20
star
13

jit-playground

A translation of the PyPy prolog jit tutorials from Prolog to Clojure
Clojure
18
star
14

qt_with_cljs

Simple example of how to use QT with CLJS
Clojure
16
star
15

clj-pypy

A implementation of Clojure on PyPy
Python
13
star
16

data-all-the-asts

Code from the Clojure/West talk "Data all the ASTs"
Clojure
11
star
17

lisp-in-x

Several implementations of a simple lisp in many different languages and paradigms
Python
9
star
18

saavik

A Prolog interpreter for Clojure
Clojure
8
star
19

datascript-gc

A simple garbage collector for Datascript
Clojure
8
star
20

universal-clojure

A clojure compiler-compiler toolkit designed to be ultra portable. Think of this as platform agnostic Clojure-in-Clojure.
Clojure
8
star
21

deep-walking-macros

Code for the deep walking macros video
Clojure
7
star
22

clj-llvm

Working place for Clojure LLVM bindings library
Clojure
6
star
23

com.tbaldridge.slide

a data driven async JavaFX toolkit
Clojure
5
star
24

com.tbaldridge.omega

A parser library for Clojure that borrows heavily from OMeta
Clojure
5
star
25

conduit

A reactive framework for clojure, with sub-modules for network and gui programming
Clojure
4
star
26

clojure-dataflow

Functional Dataflow for Clojure
4
star
27

jarl

The best of Dataflow, Actors, and Agents. Here be dragons!
4
star
28

flow

(mostly) immutable dataflows for Clojure.
Clojure
4
star
29

telesto

A bytecode based data format for C# that is allocation free and extremely fast
C#
4
star
30

microactors

an ultra-lightweight implementation of actors in clojure (JVM)
Clojure
4
star
31

reactive-clojure

Reactive Programming for Clojure
Clojure
3
star
32

cljvm

Python
3
star
33

via-maris

Experiments in various techs (Datomic, Pedestal, Loom, etc). Using EVE Online for a source of data. Most likely I am using some of the tech wrong, this is a place for experiments, nothing much more.
Clojure
3
star
34

gambolpuddy

C#
2
star
35

lisp-in-fsharp

F#
2
star
36

HalgarisRPGLoot

PoE/D3 style loot generator for Skyrim modlists
C#
2
star
37

clj-lobapp

A demo Line of Business app for Clojure
Clojure
2
star
38

blasteroids

A Asteroid like game in Clojure
Clojure
2
star
39

soul-gem-disenchantment

Fill soul gems by melting down enchanted items
C#
2
star
40

Spriggan

C#
2
star
41

relational-zippers

Zipper like structures that integrate tightly with core.logic.
Clojure
2
star
42

treadle

Abstract Expression Graphs for Python
Python
2
star
43

PluginTextTools

Tools for using ESP/ESM/ESL with text manipulation tools like git
C#
1
star
44

Wabbajack.Paths

C#
1
star
45

ModTester

1
star
46

SynthusMaximus

A port of the PerkusMaximus patcher to SkyrimSE and Synthesis/Mutagen
C#
1
star
47

SynthNPCsWithFaces

A simple Synth patcher for TPF's uses
C#
1
star
48

halgaris-helper-modlist

A placeholder for testing WJ modlist decentralization
1
star
49

gormet

A game file cooker for Skyrim Special Edition
C#
1
star
50

async-bench

Clojure
1
star
51

texture-tools

A set of GPU accelerated DDS compression and processing tools for .NET
C#
1
star
52

effect-lisp

playing around with abstract interpreters and effect systems
Clojure
1
star
53

mandelbrot-server

An example project for showing use cases of core.async
Clojure
1
star
54

jack-frost

High performance binary serializer for getting data to/from Clojure and ClojureScript
Clojure
1
star