Git Product home page Git Product logo

Comments (6)

kurtschelfthout avatar kurtschelfthout commented on May 23, 2024 1

Don't have a a strong opinion. My theory that "explicit is better than implicit, until people find out that explicit means more typing" still going strong I see :)

The idea of v3 was that there'd be some integrated shrinking, so Gen wouldn't be so important, but obviously I never got there.

In principle putting a method on Gen would make most sense, not sure if that's easy to arrange, because the Arb code occurs in a module after the Gen code.

from fscheck.

kurtschelfthout avatar kurtschelfthout commented on May 23, 2024 1

Decided against this.

The explicit arbitrary map is an important piece of the new design for extending and dealing with what was "arbitrary registration" before. In particular, ArbMap.defaults is now immutable - whenever you want to change something in it, ArbMap.defaults |> ArbMap.generate will NOT pick up changes. 2.x had side-effects which was a source of much confusion.

Making it explicit that there is an immutable map from types T to Arbitrary<T> which you can extend or change by making a new one, is important. Making a Gen.default or whatever obscures this (esp. in light of the previous design).

If you prefer, there is a GeneratorFor extension method in FsCheck.Fluent. ArbMap.defaults.GeneratorFor<T>()

from fscheck.

ploeh avatar ploeh commented on May 23, 2024

The first time I picked up v3 I also struggled finding the correct API.

Since ArbMap.generate ArbMap.defaults returns a Gen<'a>, I would find it more intuitive that such a function were to be defined in the Gen module; Gen.default or (if you want to explicitly include the type) Gen.defaultFor<'a>?

from fscheck.

ploeh avatar ploeh commented on May 23, 2024

...or perhaps Gen.fromDefaults?

from fscheck.

bartelink avatar bartelink commented on May 23, 2024

While I like Gen.defaultFor the most from the above, the main negative is probably the fact that it doesn't convey that the root of it all is ArbMap.defaults and/or that it might be appropriate to consider whether you should be doing something at the Arb level.

I guess Kurt will have an opinion; I feel the important bits are:

  • provide something terse and usable, because it's a common (and IMO valid) need
  • help people upgrade from V2 (IIRC there was something on Gen, which does make the case for it being on Gen
  • still nudge people in the correct direction wrt the ArbMap/Arb/Gen layering

That last piece is something I have grokked to any major degree, and any nudge the common APIs that people will run into via the FsCheck.Xunit onramp (i.e. feeling your way into using FsCheck by having it feed stuff into a [<Property>], only customising the Generators "to shut FsCheck up" without actually using any Gen or gen { stuff, or properly considering whether your inputs are actually getting appropriate variation induced at all).

from fscheck.

bartelink avatar bartelink commented on May 23, 2024

Apologies for not responding earlier; had been letting it percolate in the hope of coming up with a counter proposal. Writing this in case it helps others, rather than as an actual counter-argument to your decision (which I feel is the correct call)

If you prefer, there is a GeneratorFor extension method in FsCheck.Fluent

I don't use anything else in the .Fluent namespace, so for me that's not particularly useful.

In general I agree with your call though; concealing pivotal abstractions in the name of discoverability that will only help people that are porting is definitely not ideal. (Would an Obsolete stub for Arb.generate have helped #644 ?)


I currently have this helper blob in most projects and don't see myself removing it:

open FsCheck.FSharp

module ArbMap =
    let defGen<'t> = ArbMap.defaults |> ArbMap.generate<'t>

Ultimately, I use FsCheck in a pretty declarative manner:

  1. all properties are via inheriting FsCheck.Xunit.Property
  2. most generation is by demanding Choice types, Active Patterns etc and/or a Fixture that does the generation based on constructor arguments
  3. in some cases, I need to disambiguate construction of id types that fail out of the box, which is generally a very boring one-liner
type FsCheckGenerators =
    static member SkuId = ArbMap.defGen |> Gen.map SkuId |> Arb.fromGen
    static member RequestId = ArbMap.defGen<Guid> |> Gen.map (fun x -> RequestId.parse %x) |> Arb.fromGen
type DomainPropertyAttribute() =
    inherit FsCheck.Xunit.PropertyAttribute(QuietOnSuccess = true, Arbitrary=[| typeof<FsCheckGenerators> |])

I suspect this is not a normal usage pattern, and probably reflects a very naive take on how to wield it...

from fscheck.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.