Giter VIP home page Giter VIP logo

current_incr's Introduction

docs OCaml-CI Build Status

Current_incr - Self-adjusting computations

This is a small, self-contained library for self-adjusting (incremental) computations. It was written for OCurrent, but can be used separately too.

It is based on the paper Adaptive Functional Programming.

It is similar to Jane Street's incremental library, but much smaller and has no external dependencies.

It is also similar to the react library, but the results do not depend on the behaviour of the garbage collector. In particular, functions stop being called as soon as they are no longer needed.

Installation

Use opam install current_incr to install the library.

Example

# #require "current_incr";;

# let total = Current_incr.var 10;;
val total : int Current_incr.var = <abstr>
# let complete = Current_incr.var 5;;
val complete : int Current_incr.var = <abstr>

# let status =
    Current_incr.of_cc begin
      Current_incr.read (Current_incr.of_var total) @@ function
      | 0 -> Current_incr.write "No jobs"
      | total ->
        Current_incr.read (Current_incr.of_var complete) @@ fun complete ->
        let frac = float_of_int complete /. float_of_int total in
        Printf.sprintf "%d/%d jobs complete (%.1f%%)"
                       complete total (100. *. frac)
        |> Current_incr.write
    end;;
val status : string Current_incr.t = <abstr>

This defines two input variables (total and complete) and a "changeable computation" (status) whose output depends on them. At the top-level, we can observe the initial state using observe:

# print_endline @@ Current_incr.observe status;;
5/10 jobs complete (50.0%)
- : unit = ()

Unlike a plain ref cell, a Current_incr.var keeps track of which computations depend on it. After changing them, you must call propagate to update the results:

# Current_incr.change total 12;;
- : unit = ()
# Current_incr.change complete 4;;
- : unit = ()
# print_endline @@ Current_incr.observe status;;      (* Not yet updated *);;
5/10 jobs complete (50.0%)
- : unit = ()

# Current_incr.propagate ();;;
- : unit = ()
# print_endline @@ Current_incr.observe status;;
4/12 jobs complete (33.3%)
- : unit = ()

Computations can have side-effects, and you can use on_release to run some compensating action if the computation needs to be undone later. Here's a function that publishes a result, and also registers a compensation for it:

let publish msg =
  Printf.printf "PUBLISH: %s\n%!" msg;
  Current_incr.on_release @@ fun () ->
  Printf.printf "RETRACT: %s\n%!" msg

It can be used like this:

# let display = Current_incr.map publish status;;
PUBLISH: 4/12 jobs complete (33.3%)
val display : unit Current_incr.t = <abstr>

# Current_incr.change total 0;;;
- : unit = ()
# Current_incr.propagate ();;
RETRACT: 4/12 jobs complete (33.3%)
PUBLISH: No jobs
- : unit = ()

A major difference between this and the react library is that current_incr does not depend on the garbage collector to decide when to stop a computation. In react, you'd have to be careful to make sure that display didn't get GC'd (even though you don't need to refer to it again) because if it did then the output would stop getting updated. Also, setting total to 0 in react might cause the program to crash with a division-by-zero exception, because the frac computation will continue running until it gets GC'd, even though it isn't needed for anything now.

Current_incr's API is pretty small. You might want to wrap it to provide extra features, e.g.

  • Use of a result type to propagate errors.
  • Integration with Lwt to allow asynchronous computations.
  • Static analysis to render your computation with graphviz.
  • Persistence of state to disk.

If you need that, consider using the OCurrent library, which extends current_incr with these features.

Contributing

You will need to run dune runtest to validate your changes. A more extensive verification is provided with crowbar to generate arbitrary computations and check their behavior and results. This step requires afl-fuzz and an ocaml compiler with the +afl option enabled, for example:

$ opam switch create 4.12.1-afl --packages=ocaml-variants.4.12.1+options,ocaml-option-afl --repos=default,beta

Before running the tests, afl-fuzz requires an input/ folder with some initial random data:

$ mkdir input
$ head -c 512 /dev/urandom > input/rnd

We recommend leaving afl-fuzz running for hours before concluding that your patch is fine:

$ dune build test/exhaust.exe
$ afl-fuzz -m 500 -i input -o output _build/default/test/exhaust.exe @@

Any issue will be reported in the output/crashes/ folder. The crashing test cases can then be reproduced with:

$ ./_build/default/test/exhaust.exe -i ./output/crashes/id:000000,...

$ find output/crashes/ -name 'id:*' -exec ./_build/default/test/exhaust.exe -i '{}' ';'

Note that the fuzzer may report crashes due to memory consumption or a bad input file ("testcase was invalid: premature end of file"), which aren't indicative of an issue with your changes.

current_incr's People

Contributors

art-w avatar craigfe avatar maiste avatar misterda avatar samoht avatar talex5 avatar tmcgilchrist avatar

Watchers

 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.