Application for Clojurists Together open source project funding. See more details and an example application at https://www.clojuriststogether.org/open-source/.
We will automatically reuse your application for the next 4 funding rounds, unless you let us know otherwise. We will email you before each funding round closes to confirm you're still available.
Ambrose Bonnaire-Sergeant
typed.clj/spec: type-like specs
Ambrose Bonnaire-Sergeant, the creator and maintainer of Typed Clojure.
The first iteration of typed.clj/spec centered
on generatively testing polymorphic functions, with much success -- for example, we can now generatively testing transducers,
and variable-arity higher-order functions (like comp
, map
). eg., here's the spec for identity.
(s/def ::identity
(all :binder (binder :x (bind-tv))
:body
(s/fspec :args (s/cat :x (tv :x))
:ret (tv :x))))
To generatively test that clojure.core/identity
satisfies this, simply call (s/valid? ::identity identity)
.
Using this robust foundation, I want to explore the design space around typed.clj/spec. I will simultaneously investigate several promising areas, some of which are listed below.
I want to express (and test!) properties of macros like:
(if e1 e2 e3)
returns e2 if its e1 is true(let [x e1] e2)
returns e2 after evaluating it with x mapped to e1
To sketch how this might be possible, here are the main differences between testing functions and macros.
Testing functions via fspec involves:
- Generating values for :args
- Applying :args to function
- Ensure return value satisfies :ret (and :fn)
I want to move this idea to the level of macros. Roughly, to check a macro, you:
- Generating programs for :args
- Splice :args into a macro form
- Ensure result of evaluating form satisfies :ret
I want to generatively test properties of functions like:
forall f,g,h. (comp (comp f g) h) == (comp f (comp g h))
- "comp is associative"
forall f. (comp identity f) == (comp f identity)
- "clojure.core/identity is the identity of comp"
The interesting parts are how to generate f, g, h. We can start with existing polymorphic infrastructure from typed.clj/spec.
- generate polymorphic functions (eg., generate
(fn [x] x)
for the spec of identity) - how to s/instrument polymorphic functions
- polymorphic specs for Associative values (eg., how to write a spec for all arities of assoc?)
- specs for Atoms & Channels
typed.clj/spec is a fresh perspective on how to use clojure.spec. It gives programmers a level of specificity that rivals type systems, without the burden of static type checking.
Yes. These sources provide revenue for general Typed Clojure maintenance.
- US$29 / month via Patreon
- US$100 / month via OpenCollective
No.
Are you part of a group that is affected by systemic bias, particularly in technology? If so, can you elaborate?
No.
No.