Fork me on GitHub
#clojure-spec
<
2021-02-26
>
jumar11:02:17

I know that you have to call stest/instrument again when you change the function definition because instrument wraps the original function and replaces the var root - when you redefine the fn, it's no longer instrumented. But I thought that just changing the fdef definition would be fine (no need to call instrument again) because the spec is hold in global registry. But any change inside fdef still requires calling instrument again - is this because the spec fn wrapper captures the fdef spec value as it was at the instrument was called?

jumar11:02:44

After looking at spec code, I think the "problem" is that it doesn't call get-spec at the time the function is invoked but rather at the time when instrument is called and thus it only captures the spec as it was at that time - no later redefinitions are taken into account.

Alex Miller (Clojure team)13:02:40

yep, exactly - this is a performance optimization

Alex Miller (Clojure team)13:02:54

typical tradeoff of perf vs dynamicity :)

👍 3
seancorfield18:02:26

@jumar What I tend to do in situations like that is put the stest/instrument call in my test namespace as a top-level form (after ns but before any tests) so that the tests run with up-to-date instrumentation. If you want to do it in a source file, you could always have something like

(comment
  (do
    (stest/instrument `my-fn)
    (my-fn 123)) ; eval this form with both the instrument call and the my-fn call
  ,)

jumar06:02:30

For us the most common case is working on an app in the REPL and changing functions or specs. Then you forget to call instrument and you either realize pretty late or not at all that your spec is broken or some data aren’t really passed in. We do have a decent test suite but not everything is covered so sometimes it’s only another developer who catches the issue

seancorfield06:02:25

When I'm writing Specs, I always have an RCF with s/exercise calls to test the specs. I also tend to write a stub -test ns when I write code and then I can run the tests in it with a hot key while I'm in the source file. The key is keeping a short feedback cycle and making sure you can run "tests" or at least "sanity check expressions" easily via hot keys while you are writing code. "forget" isn't an option: write the code so you can't forget (like the do form I suggested).

uwo16:02:06

@U04V70XH6 Would love to see a youtube video about the spec dimension of your development workflow, if you ever feel like it. I remember enjoying the demonstration of your REBL workflow

seancorfield17:02:21

@U09QBCNBY Noted. I'm not sure when I'll get back to making videos -- I really hate the process (and the medium): I much prefer prose and code to videos.

👍 3
borkdude18:02:00

I also have a couple of helper macros here for in/unstrumentation: https://github.com/borkdude/respeced#with-instrumentation https://github.com/borkdude/respeced#with-unstrumentation They ensure the desired state in the body, but will restore the state like it was afterwards

metal 3