/speculative

Primary LanguageClojureEclipse Public License 1.0EPL-1.0

speculative

CircleCI Clojars Project

speculative is a collection of specs for the functions in clojure.core. While its ultimate goal is to be rendered obsolete by these or similar specs being added to clojure.core proper, speculative hopefully provides some value while we're waiting for that to happen.

Origins

The project started based on two tweets. First @mfikes tweeted

I still hold the view that Clojure’s core fns should have specs.

Ex: While
(merge-with + [0 3] {0 7 1 2} {0 3 2 32})
produces a reasonable result, it is not even a map. A spec would reject 2nd arg.

What if I conclude dot products are possible via
(merge-with + [0 3] [1 2])
?

— Mike Fikes (@mfikes) October 19, 2018

Then @borkdude tweeted a couple of days later:

Or maybe have a development version with guards and a production version without guards (I think Stu said something like this)

— (λ. borkdude) (@borkdude) October 19, 2018

Rationale

With the new error-messages that are coming with Clojure 1.10, adding specs to the clojure.core functions give much better error messages.

Withoug specs on clojure.core/map the error looks like:

Clojure 1.10.0-RC1
user=> (map 'lol 'lol)
Error printing return value (IllegalArgumentException) at clojure.lang.RT.seqFrom (RT.java:551).
Don't know how to create ISeq from: clojure.lang.Symbol
(user=>

user With speculative, we get

user=> (map 1 'lol)
Evaluation error - invalid arguments to clojure.core/map at (NO_SOURCE_FILE:4).
1 - failed: ifn? at: [:f]
user=>

Installation

Add the relevant coordinates to your favourite build tool:

deps.edn

speculative {:mvn/version "RELEASE"}

lein

[speculative "0.0.1"]

Usage

user=> (require 'speculative.core)
nil
user=> (require '[clojure.spec.test.alpha :as stest])
nil
user=> (stest/instrument `clojure.core/map)
[clojure.core/map]
user=> (map 1 'lol)
Evaluation error - invalid arguments to clojure.core/map at (NO_SOURCE_FILE:4).
1 - failed: ifn? at: [:f]
user=>

Tests

Clojure

 clj -A:test:runner

ClojureScript

clj -A:test:cljstests

Self-Hosted ClojureScript

plk -A:test:plktests

Contributing

In the hope that the code in this project would be useful for clojure.core, any contributer to this repo needs to have a Contributor Agreement for Clojure so that any code in speculative can be used in either Clojure or Clojurescript.

License

Copyright © 2018 Erik Assum

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