• Stars
    star
    592
  • Rank 75,038 (Top 2 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created about 12 years ago
  • Updated about 10 years ago

Reviews

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

Repository Details

Serious functional programming library for JavaScript.

% bilby.js

Build status

Main Build Status

Dependency Dependencies

Description

bilby.js is a serious functional programming library. Serious, meaning it applies category theory to enable highly abstract and generalised code. Functional, meaning that it enables referentially transparent programs.

Some features include:

  • Immutable multimethods for ad-hoc polymorphism
  • Functional data structures
  • Automated specification testing (ScalaCheck, QuickCheck)
  • Fantasy Land compatible

Usage

node.js:

var bilby = require('bilby');

Browser:

<script src="bilby-min.js"></script>

Development

Download the code with git:

git clone https://github.com/puffnfresh/bilby.js.git

Install the development dependencies with npm:

npm install

Run the tests with grunt:

npm test

Build the concatenated scripts with grunt:

$(npm bin)/grunt

Generate the documentation with emu:

$(npm bin)/emu < bilby.js

Environment

Environments are very important in bilby. The library itself is implemented as a single environment.

An environment holds methods and properties.

Methods are implemented as multimethods, which allow a form of ad-hoc polymorphism. Duck typing is another example of ad-hoc polymorphism but only allows a single implementation at a time, via prototype mutation.

A method instance is a product of a name, a predicate and an implementation:

var env = bilby.environment()
    .method(
        // Name
        'negate',
        // Predicate
        function(n) {
            return typeof n == 'number';
        },
        // Implementation
        function(n) {
            return -n;
        }
    );

env.negate(100) == -100;

We can now override the environment with some more implementations:

var env2 = env
    .method(
        'negate',
        function(b) {
            return typeof b == 'boolean';
        },
        function(b) {
            return !b;
        }
    );

env2.negate(100) == -100;
env2.negate(true) == false;

The environments are immutable; references to env won't see an implementation for boolean. The env2 environment could have overwritten the implementation for number and code relying on env would still work.

Properties can be accessed without dispatching on arguments. They can almost be thought of as methods with predicates that always return true:

var env = bilby.environment()
    .property('name', 'Brian');

env.name == 'Brian';

This means that bilby's methods can be extended:

function MyData(data) {
    this.data = data;
}

var _ = bilby.method(
    'equal',
    bilby.isInstanceOf(MyData),
    function(a, b) {
        return this.equal(a.data, b.data);
    }
);

_.equal(
    new MyData(1),
    new MyData(1)
) == true;

_.equal(
    new MyData(1),
    new MyData(2)
) == false;

environment(methods = {}, properties = {})

  • method(name, predicate, f) - adds an multimethod implementation
  • property(name, value) - sets a property to value
  • envConcat(extraMethods, extraProperties) - adds methods + properties
  • envAppend(e) - combines two environemts, biased to e

Helpers

The helpers module is a collection of functions used often inside of bilby.js or are generally useful for programs.

functionName(f)

Returns the name of function f.

functionLength(f)

Returns the arity of function f.

bind(f)(o)

Makes this inside of f equal to o:

bilby.bind(function() { return this; })(a)() == a

Also partially applies arguments:

bilby.bind(bilby.add)(null, 10)(32) == 42

curry(f)

Takes a normal function f and allows partial application of its named arguments:

var add = bilby.curry(function(a, b) {
        return a + b;
    }),
    add15 = add(15);

add15(27) == 42;

Retains ability of complete application by calling the function when enough arguments are filled:

add(15, 27) == 42;

flip(f)

Flips the order of arguments to f:

var concat = bilby.curry(function(a, b) {
        return a + b;
    }),
    prepend = flip(concat);

identity(o)

Identity function. Returns o:

forall a. identity(a) == a

constant(c)

Constant function. Creates a function that always returns c, no matter the argument:

forall a b. constant(a)(b) == a

compose(f, g)

Creates a new function that applies f to the result of g of the input argument:

forall f g x. compose(f, g)(x) == f(g(x))

create(proto)

Partial polyfill for Object.create - creates a new instance of the given prototype.

getInstance(self, constructor)

Always returns an instance of constructor.

Returns self if it is an instanceof constructor, otherwise constructs an object with the correct prototype.

tagged(name, fields)

Creates a simple constructor for a tagged object.

var Tuple = tagged('Tuple', ['a', 'b']);
var x = Tuple(1, 2);
var y = new Tuple(3, 4);
x instanceof Tuple && y instanceof Tuple;

taggedSum(constructors)

Creates a disjoint union of constructors, with a catamorphism.

var List = taggedSum({
    Cons: ['car', 'cdr'],
    Nil: []
});
function listLength(l) {
    return l.cata({
        Cons: function(car, cdr) {
            return 1 + listLength(cdr);
        },
        Nil: function() {
            return 0;
        }
    });
}
listLength(List.Cons(1, new List.Cons(2, List.Nil()))) == 2;

error(s)

Turns the throw new Error(s) statement into an expression.

zip(a, b)

Takes two lists and pairs their values together into a "tuple" (2 length list):

zip([1, 2, 3], [4, 5, 6]) == [[1, 4], [2, 5], [3, 6]]

singleton(k, v)

Creates a new single object using k as the key and v as the value. Useful for creating arbitrary keyed objects without mutation:

singleton(['Hello', 'world'].join(' '), 42) == {'Hello world': 42}

extend(a, b)

Right-biased key-value concat of objects a and b:

bilby.extend({a: 1, b: 2}, {b: true, c: false}) == {a: 1, b: true, c: false}

isTypeOf(s)(o)

Returns true iff o has typeof s.

isFunction(a)

Returns true iff a is a Function.

isBoolean(a)

Returns true iff a is a Boolean.

isNumber(a)

Returns true iff a is a Number.

isString(a)

Returns true iff a is a String.

isArray(a)

Returns true iff a is an Array.

isEven(a)

Returns true iff a is even.

isOdd(a)

Returns true iff a is odd.

isInstanceOf(c)(o)

Returns true iff o is an instance of c.

AnyVal

Sentinal value for when any type of primitive value is needed.

Char

Sentinal value for when a single character string is needed.

arrayOf(type)

Sentinel value for when an array of a particular type is needed:

arrayOf(Number)

isArrayOf(a)

Returns true iff a is an instance of arrayOf.

objectLike(props)

Sentinal value for when an object with specified properties is needed:

objectLike({
    age: Number,
    name: String
})

isObjectLike(a)

Returns true iff a is an instance of objectLike.

or(a)(b)

Curried function for ||.

and(a)(b)

Curried function for &&.

add(a)(b)

Curried function for +.

strictEquals(a)(b)

Curried function for ===.

not(a)

Returns true iff a is falsy.

fill(s)(t)

Curried function for filling array.

range(a, b)

Create an array with a given range (length).

liftA2(f, a, b)

Lifts a curried, binary function f into the applicative passes a and b as parameters.

sequence(m, a)

Sequences an array, a, of values belonging to the m monad:

 bilby.sequence(Array, [
     [1, 2],
     [3],
     [4, 5]
 ]) == [
     [1, 3, 4],
     [1, 3, 5],
     [2, 3, 4],
     [2, 3, 5]
 ]

Do (operator overloading)

Adds operator overloading for functional syntax:

  • >= - monad flatMap/bind:

    bilby.Do()(
        bilby.some(1) >= function(x) {
            return x < 0 ? bilby.none : bilby.some(x + 2);
        }
    ).getOrElse(0) == 3;
    
  • >> - kleisli:

    bilby.Do()(
        function(x) {
            return x < 0 ? bilby.none : bilby.some(x + 1);
        } >> function(x) {
            return x % 2 != 0 ? bilby.none : bilby.some(x + 1);
        }
    )(1).getOrElse(0) == 3;
    
  • < - functor map:

    bilby.Do()(
        bilby.some(1) < add(2)
    ).getOrElse(0) == 3;
    
  • * - applicative ap(ply):

    bilby.Do()(
        bilby.some(add) * bilby.some(1) * bilby.some(2)
    ).getOrElse(0) == 3;
    
  • + - semigroup concat:

    bilby.Do()(
        bilby.some(1) + bilby.some(2)
    ).getOrElse(0) == 3;
    

Do()(a)

Creates a new syntax scope. The a expression is allowed multiple usages of a single operator per Do call:

  • >= - flatMap
  • >> - kleisli
  • < - map
  • * - ap
  • + - concat

The associated name will be called on the bilby environment with the operands. For example:

bilby.Do()(bilby.some(1) + bilby.some(2))

Desugars into:

bilby.concat(bilby.some(1), bilby.some(2))

Do.setValueOf(proto)

Used to mutate the valueOf property on proto. Necessary to do the Do block's operator overloading. Uses the object's existing valueOf if not in a Do block.

Warning: this mutates proto. May not be safe, even though it tries to default back to the normal behaviour when not in a Do block.

Trampoline

Reifies continutations onto the heap, rather than the stack. Allows efficient tail calls.

Example usage:

function loop(n) {
    function inner(i) {
        if(i == n) return bilby.done(n);
        return bilby.cont(function() {
            return inner(i + 1);
        });
    }

    return bilby.trampoline(inner(0));
}

Where loop is the identity function for positive numbers. Without trampolining, this function would take n stack frames.

done(result)

Result constructor for a continuation.

cont(thunk)

Continuation constructor. thunk is a nullary closure, resulting in a done or a cont.

trampoline(bounce)

The beginning of the continuation to call. Will repeatedly evaluate cont thunks until it gets to a done value.

Id

  • concat(b) - semigroup concat
  • map(f) - functor map
  • ap(b) - applicative ap(ply)
  • chain(f) - chain value
  • arb() - arbitrary value

isId(a)

Returns true if a is Id.

idOf(type)

Sentinel value for when an Id of a particular type is needed:

idOf(Number)

isIdOf(a)

Returns true iff a is an instance of idOf.

Option

Option a = Some a + None

The option type encodes the presence and absence of a value. The some constructor represents a value and none represents the absence.

  • fold(a, b) - applies a to value if some or defaults to b
  • getOrElse(a) - default value for none
  • isSome - true iff this is some
  • isNone - true iff this is none
  • toLeft(r) - left(x) if some(x), right(r) if none
  • toRight(l) - right(x) if some(x), left(l) if none
  • flatMap(f) - monadic flatMap/bind
  • map(f) - functor map
  • ap(s) - applicative ap(ply)
  • concat(s, plus) - semigroup concat

of(x)

Constructor of Monad creating Option with value of x.

some(x)

Constructor to represent the existence of a value, x.

none

Represents the absence of a value.

isOption(a)

Returns true if a is a some or none.

Either

Either a b = Left a + Right b

Represents a tagged disjunction between two sets of values; a or b. Methods are right-biased.

  • fold(a, b) - a applied to value if left, b if right
  • swap() - turns left into right and vice-versa
  • isLeft - true iff this is left
  • isRight - true iff this is right
  • toOption() - none if left, some value of right
  • toArray() - [] if left, singleton value if right
  • flatMap(f) - monadic flatMap/bind
  • map(f) - functor map
  • ap(s) - applicative ap(ply)
  • concat(s, plus) - semigroup concat

left(x)

Constructor to represent the left case.

right(x)

Constructor to represent the (biased) right case.

isEither(a)

Returns true iff a is a left or a right.

Validation

Validation e v = Failure e + Success v

The Validation data type represents a "success" value or a semigroup of "failure" values. Validation has an applicative functor which collects failures' errors or creates a new success value.

Here's an example function which validates a String:

function nonEmpty(field, string) {
    return string
        ? λ.success(string)
        : λ.failure([field + " must be non-empty"]);
}

We might want to give back a full-name from a first-name and last-name if both given were non-empty:

function getWholeName(firstName) {
    return function(lastName) {
        return firstName + " " + lastName;
    }
}
λ.ap(
    λ.map(nonEmpty("First-name", firstName), getWholeName),
    nonEmpty("Last-name", lastName)
);

When given a non-empty firstName ("Brian") and lastName ("McKenna"):

λ.success("Brian McKenna");

If given only an invalid firstname:

λ.failure(['First-name must be non-empty']);

If both values are invalid:

λ.failure([
    'First-name must be non-empty',
    'Last-name must be non-empty'
]);
  • map(f) - functor map
  • ap(b, concat) - applicative ap(ply)

success(value)

Represents a successful value.

failure(errors)

Represents a failure.

errors must be a semigroup (i.e. have an concat implementation in the environment).

success(x)

Constructor to represent the existance of a value, x.

failure(x)

Constructor to represent the existance of a value, x.

isValidation(a)

Returns true iff a is a success or a failure.

Lenses

Lenses allow immutable updating of nested data structures.

store(setter, getter)

A store is a combined getter and setter that can be composed with other stores.

isStore(a)

Returns true iff a is a store.

lens(f)

A total lens takes a function, f, which itself takes a value and returns a store.

  • run(x) - gets the lens' store from x
  • compose(l) - lens composition

isLens(a)

Returns true iff a is a lens.

objectLens(k)

Creates a total lens over an object for the k key.

Input/output

Purely functional IO wrapper.

io(f)

Pure wrapper around a side-effecting f function.

  • perform() - action to be called a single time per program
  • flatMap(f) - monadic flatMap/bind

isIO(a)

Returns true iff a is an io.

Tuples

Tuples are another way of storing multiple values in a single value. They have a fixed number of elements (immutable), and so you can't cons to a tuple. Elements of a tuple do not need to be all of the same type

Example usage:

 bilby.Tuple2(1, 2);
 bilby.Tuple3(1, 2, 3);
 bilby.Tuple4(1, 2, 3, 4);
 bilby.Tuple5(1, 2, 3, 4, 5);
  • arb() - arbitrary value

Tuple2

  • flip() - flip values
  • concat() - Semigroup (value must also be a Semigroup)
  • map() - functor map

Tuple3

  • concat() - Semigroup (value must also be a Semigroup)
  • map() - functor map

Tuple4

  • concat() - Semigroup (value must also be a Semigroup)
  • map() - functor map

Tuple5

  • concat() - Semigroup (value must also be a Semigroup)
  • map() - functor map

isTuple2(a)

Returns true if a is Tuple2.

isTuple4(a)

Returns true if a is Tuple3.

isTuple4(a)

Returns true if a is Tuple4.

isTuple5(a)

Returns true if a is Tuple5.

Promise(fork)

Promise is a constructor which takes a fork function. The fork function takes one argument:

fork(resolve)

Where resolve is a side-effecting callback.

fork(resolve)

The resolve callback gets called when a value is resolved.

of(x)

Creates a Promise that contains a successful value.

chain(f)

Returns a new promise that evaluates f when the current promise is successfully fulfilled. f must return a new promise.

map(f)

Returns a new promise that evaluates f on a value and passes it through to the resolve function.

isPromise(a)

Returns true if a is Promise.

State(run)

  • chain() - TODO
  • evalState() - evaluate state
  • execState() - execute on state
  • map() - functor map
  • ap() - applicative ap(ply)

isState(a)

Returns true if a is State.

List

List a = Cons a + Nil

The list type data type constructs objects which points to values. The cons constructor represents a value, the left is the head (car, the first element) and the right represents the tail (cdr, the second element). The nil constructor is defined as an empty list.

The following example creates a list of values 1 and 2, where the nil terminates the list:

cons(1, cons(2, nil));

The following can also represent tree like structures (Binary Trees):

cons(cons(1, cons(2, nil)), cons(3, cons(4, nil)));

     *
    / \
   *   *
  / \ / \
 1  2 3  4
  • concat(a) - semigroup concat
  • fold(a, b) - applies a to value if cons or defaults to b
  • map(f) - functor map
  • fold(f) - applies f to values
  • flatMap(f) - monadic flatMap
  • append(a) - append
  • appendAll(a) - append values
  • prepend(a) - prepend value
  • prependAll(a) - prepend values
  • reverse() - reverse
  • exists() - test by predicate
  • filter() - filter by predicate
  • partition() - partition by predicate
  • size() - size of the list

cons(a, b)

Constructor to represent the existence of a value in a list, a and a reference to another b.

nil

Represents an empty list (absence of a list).

isList(a)

Returns true if a is a cons or nil.

QuickCheck

QuickCheck is a form of automated specification testing. Instead of manually writing tests cases like so:

assert(0 + 1 == 1);
assert(1 + 1 == 2);
assert(3 + 3 == 6);

We can just write the assertion algebraicly and tell QuickCheck to automaticaly generate lots of inputs:

bilby.forAll(
    function(n) {
        return n + n == 2 * n;
    },
    [Number]
).fold(
    function(fail) {
        return "Failed after " + fail.tries + " tries: " + fail.inputs.toString();
    },
    "All tests passed!"
)

failureReporter

  • inputs - the arguments to the property that failed
  • tries - number of times inputs were tested before failure

forAll(property, args)

Generates values for each type in args using bilby.arb and then passes them to property, a function returning a Boolean. Tries goal number of times or until failure.

Returns an Option of a failureReporter:

var reporter = bilby.forAll(
    function(s) {
        return isPalindrome(s + s.split('').reverse().join(''));
    },
    [String]
);

goal

The number of successful inputs necessary to declare the whole property a success:

var _ = bilby.property('goal', 1000);

Default is 100.

More Repositories

1

roy

Small functional language that compiles to JavaScript.
JavaScript
834
star
2

toggle-osx-shadows

Tiny tool to toggle window shadows on OS X
C
413
star
3

Honer.app

OS X application to draw a border around the focused window
Objective-C
285
star
4

iridium

xmonad with the X11 abstracted and configured with Idris
Idris
201
star
5

nix-files

My NixOS configuration and custom Nix derivations.
Nix
147
star
6

brushtail

JS AST rewriter for tail call elimination
JavaScript
133
star
7

node-webgl

WebGL addon for node.js
C++
106
star
8

wat-collection

Collection of "wat" moments in various languages
PHP
76
star
9

sonic2

Sonic the Hedgehog 2 in Haskell
Haskell
67
star
10

node-cgi

A CGI adaptor for node.js
JavaScript
55
star
11

free-graphs

Generate GraphViz graphs by interpretting free monads.
Haskell
53
star
12

game-of-comonads.js

Pure and comonadic Game of Life in Fantasy Land compatible JavaScript
JavaScript
42
star
13

rephrase

Rewrite rules for JavaScript.
JavaScript
39
star
14

haskell-buildpack-demo

Demo of the Heroku Haskell Buildpack
Haskell
39
star
15

bam-idris-blog

Static blog generator in Idris.
Idris
39
star
16

tryidris

Try Idris
JavaScript
36
star
17

crosscheck

Using QuickCheck to test functions in other languages/environments.
Haskell
32
star
18

licentious

License your GitHub repository in seconds
Haskell
29
star
19

atsboot

A tiny 32 bit kernel written in ATS
Assembly
26
star
20

eta-android

Quick example of Eta on Android
Java
24
star
21

language-scala

Pretty printer of Scala
Haskell
20
star
22

leftpad.hs

Verified left pad
Haskell
19
star
23

c4-model

Haskell implementation of C4 model, for specifying software architecture
Nix
18
star
24

haskell-jwt

JSON Web Token (JWT) decoding and encoding
Haskell
18
star
25

th-pprint

Simplify and render Template Haskell
Haskell
18
star
26

fo

Overloaded operators for Fantasy Land compatible JavaScript.
JavaScript
17
star
27

purescript-streams

Compositional, streaming I/O library (unfinished)
PureScript
13
star
28

stl-idris

Code from my StrangeLoop 2014 Idris presentation.
Idris
13
star
29

ray

Roy plugin for Play 2.0
JavaScript
12
star
30

nix-command-store-plugin

Arbitrary commands as remote Nix stores
C++
11
star
31

game-of-comonads

Game of Life written using a Comonadic grid/board and Ncurses.
Haskell
11
star
32

linuxkit-builder

See newer work at https://github.com/nix-community/linuxkit-builder
Nix
11
star
33

type-search

Hoogle's core type search algorithm, as a library
Haskell
11
star
34

scrappy

Better Scala for-comprehensions using paradise's annotation macros
Scala
11
star
35

kosinski

Compression used in Sonic the Hedgehog
Haskell
10
star
36

crab-emacs

Emacs minor mode to use Emacs as a Crab remote browsing server.
Emacs Lisp
9
star
37

purescript-webrtc

PureScript WebRTC bindings
PureScript
9
star
38

confining-strut

Sets an engine independent toString on Functions
JavaScript
8
star
39

blimp

Small Haskell to JVM compiler
Haskell
8
star
40

nix-chromeos

Scripts for working with Nix via a chroot on ChromeOS.
Shell
8
star
41

idris-partiality

The partiality monad in Idris.
Idris
7
star
42

editpipe

Edit stdin using an editor before sending to stdout.
Haskell
7
star
43

osxplaypause

Simple OS X application to trigger the play/pause key
Objective-C
7
star
44

lam

Experiment in generating a functional Java library from Haskell
Haskell
6
star
45

totality

A total functional language embedded in Scala using macros.
Scala
6
star
46

crab-chrome

Chrome Extension to allow Chrome as a Crab remote browsing client.
JavaScript
6
star
47

megadrive-palette

Palettes for Sega Mega Drive (and Genesis)
Haskell
6
star
48

type-algebra

Haskell library for operations on type algebra, e.g. inhabitant counting
Haskell
6
star
49

amqp-pathwatcher

Dump close_write inotify events onto an AMQP queue.
Haskell
6
star
50

scalaz-concurrent-io

Functions for working with concurrency within the scalaz IO type.
Scala
5
star
51

macgiffer

OS X screencast as a GIF, using just a paperclip and a sock.
Objective-C
5
star
52

emu.js

Simple JavaScript documentation generator.
JavaScript
5
star
53

vagrant-haskell-heroku

Vagrant project for deploying Haskell to Heroku
Ruby
5
star
54

idris-workshop

Small collection of Idris exercises
Idris
5
star
55

awsom

Implemenation of a Self-Organising Map using Python
Python
4
star
56

bounded-array

Arrays with a value for every index
Haskell
4
star
57

novation-launchpad

Haskell for the Novation Launchpad
Haskell
4
star
58

buzzbee

jQuery plugin and web service to embed Google Buzz in your website
JavaScript
4
star
59

puffyterm

GTK-based terminal emulator configured using Haskell
Haskell
4
star
60

reaktor-hands-on

Reaktor Hands On: Pure Functional Programming in Plain JavaScript
JavaScript
4
star
61

wasm-encoder

Haskell low-level WebAssembly encoder
Haskell
4
star
62

halves

Splitting/combining data structures to/from halves, quarters, eighths
Haskell
4
star
63

cufp-2015-tutorial-purescript

Code developed during the PureScript Tutorial at CUFP 2015
PureScript
3
star
64

lastresort

Turing Tarpit based on pattern matching. Entry into PLT Games #1 ("Into the Turing Tarpit").
Haskell
3
star
65

purescript-functor-semigroups

Semigroups for instances of the functor hierarchy.
PureScript
3
star
66

epever

Communicating to a Epever/Epsolar Tracer A series charge controller via Modbus
Haskell
3
star
67

eshindleymilner

Hindley-Milner using the Mozilla Parser API.
3
star
68

roku-api

Bindings to Roku's External Control API
Haskell
3
star
69

cloud9-userscript

Extend the Cloud9 editor with a client-side script.
JavaScript
3
star
70

stack-nix

Haskell
3
star
71

scalispa

A small S-expression to JVM bytecode compiler.
Scala
3
star
72

haskell-hangouts

Projects from the Haskell Hangouts
Haskell
3
star
73

cufp-2016-purescript

PureScript
2
star
74

hnchumby

A Hacker News client for Chumby.
ActionScript
2
star
75

scander

Single file PHP remote administration
PHP
2
star
76

yesod-buildpack-demo

Demo of a Yesod application deployed to Heroku using the Haskell Buildpack
Haskell
2
star
77

stunning-octo-happiness

JavaScript
2
star
78

bigtext-slideshow

HTML5 slideshow demo with BigText.
2
star
79

folds4s

Beautiful Folding
Scala
2
star
80

ProfunctorBot

LambdaBot on Twitch
Nix
2
star
81

puffnfresh-ghc-plugin-lens

Haskell
2
star
82

crypto-keys-ssh

Parse SSH keys
Haskell
2
star
83

strip18

A programming language REPL as a game. Entry into PLT Games March 2013 ("Game on")
JavaScript
2
star
84

rsahub

Easily send encrypted messages to GitHub users.
Haskell
1
star
85

papa-prelude-core

Useful functions from Prelude, or reimplemented from base
Haskell
1
star
86

git-log-impact

Shows a chart of lines added to a repository (as recorded by git log)
Haskell
1
star
87

sicp-exercises

Structure and Interpretation of Computer Programs Exercises (in Scheme)
Scheme
1
star
88

word4

Provides Word4, half a Word8
Haskell
1
star
89

kiks-scilab

Port of KiKS to SciLab
1
star
90

prelim-monoid

Monoid
Haskell
1
star
91

eta-midi-player

Haskell
1
star
92

fiery-biscuits

An entry for PyWeek
1
star