This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-12-28
Channels
- # ai (1)
- # beginners (190)
- # boot (24)
- # cider (43)
- # cljsjs (3)
- # cljsrn (29)
- # clojars (6)
- # clojure (310)
- # clojure-dev (6)
- # clojure-nl (6)
- # clojure-russia (11)
- # clojure-spec (66)
- # clojure-uk (95)
- # clojurescript (103)
- # clojurewerkz (2)
- # core-async (9)
- # cursive (4)
- # datomic (5)
- # hoplon (163)
- # lein-figwheel (52)
- # luminus (1)
- # off-topic (6)
- # om (6)
- # onyx (42)
- # perun (8)
- # re-frame (16)
- # reagent (10)
- # ring (7)
- # ring-swagger (1)
- # rum (1)
- # slack-help (2)
- # uncomplicate (1)
- # untangled (80)
I’m a little confused on fmap
vs bind
— according to the docs for clojure.test.check.generators/bind
: Create a new generator that passes the result of gen into function k. k should return a new generator.
fmap
also takes a generator, and applies some function to it. The only difference I can see is that in bind
, the function is responsible for returning a generator, and in fmap
, the function just returns data.
Is there some other difference I’m not seeing?
so the idea is this is somewhat like Haskell with generators analogous to monads? that comparison doesn't make the most sense to me tho
I expect that's literally true in quickcheck, which test.check is largely based on
i suppose in the sense that they're bound to a certain type? but i don't see how the monad laws could even possibly apply to generators
The first three make sense to me. I'll translate them to generators when I get to a keyboard
i don't think that SO post is the best source. i've always only known three laws: left identity, right identity, and associativity. https://wiki.haskell.org/Monad_Laws
here's an example that uses it as the base case in a recursive generator: https://github.com/gfredericks/chess-clj/blob/89b2e5543534f82915a1aab67e026a326a0ed0a5/test/com/gfredericks/chess/generators.clj#L194
it's just double-binding in two different ways; looks suspiciously trivial actually
so if you can associate that then you've met the third monad law...really the important one in that it lets you compose monads that encapsulate different typeclasses
it doesn't have a corollary in dynamic typing. that's why i always thought algo.monad was quite odd...
but it makes more sense with generators because they do in a sense have type signatures
it's really just a library of macros that needlessly replicate the functionality of a number of common haskell monads
but this makes sense. you need bind in order to compose generators with different types
wow, now i'm really interested in uses of spec beyond things like quickcheck. i haven't seen other examples actually using generators to write code, although i think rich touched on it in his talk i saw
well, i only glossed over your chess example, but it seems you're using them to actually generate moves rather than to just test functions you've written?
it is generating moves, but only in service of generating legal positions, which is for testing
I don't think test.check generators are necessarily the best fit for non-testing purposes
yeah, i've only noticed that now that i've started getting them working for whole projects...are they purposefully non-random or that's just a consequence of their implementation?
i mean, for example, if i call (gen/sample (s/gen int?) n)
the size of the ints increase with n. initially they're quite small...which, as you said, makes sense for testing
but even if you fix size
, which you can do with gen/generate
, there are still elements of the "smaller things are worth trying more often" heuristic
more about sizing: https://github.com/clojure/test.check/blob/master/doc/growth-and-shrinking.md
ah, these are the docs i should have been looking at this whole time! i've been using this: http://clojure.github.io/clojure/branch-master/clojure.spec-api.html which just says everything is a wrapper of test.check macros
I'm trying to do a big documentation overhaul, so I'll try to look for ways to make discovery better too
yeah, your test.check docs are most useful for what i personally needed than most of what's in alex's guide. like i could have used gen/nat
earlier to avoid divide by zero errors and instead rolled my own
anyway, i think it'd be interesting to have something about the generator combinators and category theory. it's an interesting consequence of how they're typed that we're not used to in a dynamic language