Skip to content
Q&A system with reflection and automation, similar to Patchwork, Affable, Mosaic
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.

See also:

Table of contents:


A question-answering system modelled after Patchwork. Differences:

  • Supports reflection.
  • Equal pointers in a sub-question become separate pointers in the respective sub-workspace. This is taken from Affable.
  • Uses Datomic as its database.

Applications of reflection

If you search the second file and this for ‘ISSUE’, you will find comments about problems with the Jursey model. This proposal addresses some of them.


Removing the following limitations would only be worthwhile if Jursey was going to be used by regular users. So far it looks like this won't be the case.

  • Jursey is not user-friendly. If your input doesn't follow the rules, the output won't make sense to you. The error messages won't be helpful.

  • There is no way to escape special symbols in hypertext. You cannot use any of []$ in normal text. This is not a fundamental limitation and could be fixed within eight hours.

Getting started

(This might not work on Windows. If you run into trouble, let me know and we'll figure something out.)

(You can also skip this section and run Jursey in a Docker container.)

  1. Install Leiningen, a build tool for Clojure. If you use Homebrew, you can just do brew install leiningen.

  2. Get the code and Datomic. Note that with downloading Datomic you agree to the terms of the Datomic Free Edition License, which also comes with the zip archive.

    $ git clone
    $ cd jursey
    $ wget -O
    $ unzip
    $ mv datomic
  3. Install the Datomic JAR to your local Maven repo. Yes, you need Maven.

    $ cd datomic
    $ ./bin/maven-install
  4. Start the Datomic transactor:

    # Still in directory `datomic`.
    $ ./bin/transactor config/samples/ &

    I've only gotten the connection between Jursey and the transactor to work when the transactor runs on Java 8. If on your machine java -version prints something about version 11, you have to (temporarily) change your JAVA_HOME. On my Mac it looks like this:

    JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk/Contents/Home/ bin/transactor config/samples/ &
  5. Start a Clojure REPL:

    $ cd .. # Back to project root.
    $ lein repl
    jursey.repl-ui=> (set-up)
    jursey.repl-ui=> (ask-root "What is your name?")

    You might get a warning about an illegal access operation. You can ignore it or make sure that your lein command also runs on Java 8.

Using a Docker container

Note that with running the following commands, you implicitly download Datomic Free and thereby agree to the terms of the Datomic Free Edition License.

$ git clone
$ cd jursey
$ docker build -t jursey . && docker run -ti --rm jursey

This trades leanness and speed for running Jursey with the fewest number of commands. I don't know why, but it can take up to a minute for the REPL prompt to appear. Also, I didn't make the Dockerfile according to best practices, so you end up with a > 900 MB image.


If you want to have a reliable branch (ie. no force-pushes), use master. If you want to see the newest changes, look at the dev-X branch with the highest X. If you want to study history in detail, look at all the dev branches.

My development process:

  1. Start task X.
  2. git checkout -b dev-X master (Until task 9.2 I developed everything on branch dev.)
  3. Make snapshot commits, push often, force-push sometimes.
  4. Review changes: git difftool master
  5. git co master
  6. git merge dev-X
  7. Squash and reword as needed.
  8. git push


  • The commits on dev-X are too small and the commits on master are too big. None of them are ‘logically separate changesets’. This is the nature of prototyping.

  • Sometimes I push to master directly.


Why do I not do them? YAGNI. I only do what will be useful later. If I expected end users to use Jursey, I would validate inputs. If I expected to add features to the core of Jursey, I would clean up the code more. But I don't expect, so I don't do.

Why are there so many? They are insights that I have while programming and might not have when I revisit the code weeks later. If one of my YAGNI expectations turns out wrong, I will open the file to change something and the TODO will remind me to change something else first. This is also the reason why I leave them littering the code instead of putting them in an issue tracker.

What about those Notes? When I read other people's code, my first thought is often: ‘This is stupid.’ Almost as often I realize a few minutes (or days) later that it was I, who was stupid. When I write a piece of code that I fear to cause a this-is-stupid thought, I add a note to induce the I-was-stupid response quickly. Of course, code that seems stupid is at least slightly stupid. The challenge is to find the level of stupidity that gives optimal long-term productivity.


  • Copying hypertext makes equality test for nested structures more complex. With persistent data structures one could just test identity.


Thanks to Andreas Stuhlmüller and Derek Elkins for their advice. And thanks to Paul Christiano for funding this work.



See LICENSE.txt.

You can’t perform that action at this time.