practicalli / practicalli/clojure

Using clojure.spec in development

Open
#78 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Makefile
Stars
117
Forks
36
PR merge metrics
No merged PRs in 30d

Description

use spec to explicitly check that data structure have the keys/values/structures a function expects

what is the best approach to do this

  • validate incoming parameters of functions by explicitly validating the parameters inside the function, e.g. with this utility function:
(defn validate! [spec value error-msg]
  (when-not (s/valid? spec value)
    (s/explain spec value)
    (throw (ex-info error-msg
                    (s/explain-data spec value)))))

Another option seems to be using s/fdef and then stest/instrument to apply upon function call.

What's the preferred approach for data validation during function calls?

seancorfield 20:11
instrument is intended to be dev/test only. For production it's appropriate to use s/valid?

So I should put explicit s/valid? calls inside most of my functions?
Functions at the boundary, not "most".

Also, perhaps, taking more time and care to design the "data API" so you aren't "changing a key name".

Use case
So considering I'm not exactly creating production code, just some code to train a ML model, and still changing functions all the time, it's an ok approach to use instrument? Once the code is stable and using it as an "api", I should get rid of those and validate at the boundaries?

seancorfield
Yeah, absolutely use instrument while you're developing -- that can be very helpful.
I recently had to work on some legacy Clojure code that I'd never worked with before and it was heavily data-centric but I didn't have a sense of the different shapes of data through the pipeline I found it very helpful to write a lot of specs, instrument a lot of functions, and explore it in the REPL. Took me about four or five days to build up a full model in Spec so I could safely begin changing the code 🙂

It can be particularly difficult for beginners with Clojure, given its focus on small, composable pieces -- and composable ideas -- so there is so much "assembly required" when putting together your dev env and your workflow.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the issue's examples of clojure.spec, s/valid?, s/fdef, and stest/instrument, then review the surrounding discussion about development, production boundaries, and REPL exploration. Done means providing a clear, project-appropriate recommendation for when to use each approach, including the boundary-validation guidance.

Written by the indexing model from the issue text.

Assessment

Tech stack
clojure
Domain
developer-experience
Issue type
Documentation
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.