test-check 2019-11-03

@leonoel has joined the channel

does the empty generator exist ?

meaning, fails to generate anything?

What would you expect it to do if you tried to cause it to generate a value? Throw an exception?

Can make it with such-that, if so

Can you describe a situation where it would be useful to have a generator that doesn't generate anything? I'm lacking imagination there.

I'm working on regular languages, and I'm willing to construct a generator for words of a given language

so, does it makes sense to have a generator for words of the empty language ?

Would it just throw an exception when you tried to generate such a word?

no, because it's not error

If it returns a value, that would be interpreted as a generated valid value, wouldn't it?

What would it generate then?

it would generate nothing

What would a call to samples return? (edit: I meant a call to gen/sample)

an empty list

There's no such thing as generating nothing

Similar to there's no such thing as a function that returns nothing

e.g. a generator that returns nil is thereby indicating: nil is a value that satisfies the desired predicate. Not that there is no valid value satisfying the predicate.

I guess a downside of using a throwing generator for the empty language is that test.check wouldn't let you do things like create a disjunction using gen/one-of like you'd want to

That would just give you a generator that threw half the time, which is obviously wrong

I don't fully understand why it doesn't make sense, and why e.g (g/one-of []) is forbidden.

this is really a noob question, I'm not really familiar with this topic

This might be a feature that could be added, but it would have to pervade a lot of the combinators

Like one-of would have to filter out empty generators from its input, for example

fmap and bind would have to short circuit

Well, if you used such-that with an arbitrary function predicate that always returned false, test.check would have no general way to identify all possible generate-nothing generators. It could only recognize ones that you made obvious were generating-nothing generators.

Which is why the pervasive support is important

So one-of would have to try invoking empty generators, and have a way of getting back "I didn't generate anything", wouldn't it? i.e. in order to enable arbitrary empty gens.

I guess you could do it that way

And this would still be a generator that throws when you try to generate, so if that can't be useful to you, then even this idea wouldn't help

Not sure how that would affect the usability of such-that

Not recommending that approach, necessarily, but it seems like one approach, the other being to say something like "empty gens using such-that with arbitrary Clojure functions as predicates may throw exceptions, or some other behavior you might not like, if you try to use them"

That's a pretty deep breaking change, though, so I doubt it would be added as a feature

is (g/such-that (constantly false) generator) a terrible idea ?

No, but it throws, and you said you didn't want that

Also it doesn't compose like I suspect you'd want for regular languages

But if you use it without composing, it'd work fine

that matches my intuition

I ended up working with nilable generators, and it's not that clumsy so I'll keep it that way

Meaning a generator that generates nil, or a context where you either have a generator or you have nil?

OK thank you for clarification

👍 1