On Fri May 29 13:28:16 2020, TOBYINK wrote:
Show quoted text> The Bool type constraint accepts the following values:
>
> undef
> ""
> 0
> 1
So the manual states. But it falls down in practice due to the default coercion.
Show quoted text>
> It is also able to coerce from any value (it just does !!$value).
I may not be the greatest Perl programmer but I understood your initial explanation-by-example. I was not aware of this coercion prior to opening the ticket. Mea culpa. The thing is that it explains the how, but not the why, of it. Why is this coercion applied by default for a type named Bool? What is the use case and who benefits? Is it truly necessary to be so very permissive and munge any random value into either 0 or 1 by default?
I just can't envisage any situation from hereon in which I am now not going to now write Bool->no_coercions every time. There is no world in which I would want to accidentally pass an empty arrayref, say, and have it not only be tolerated but munged into a truthy value. As Perl has no native boolean data type, what I actually want is to guarantee that the caller is passing a value that is _conventionally_ used to denote something truthy or falsey, this preventing errors of logic (I'm sure that you can readily conceive of many such scenarios in the blink of an eye). The explanation of the Bool type in the manual made me think that this was what I was getting by default. To eventually find otherwise was an unwelcome surprise.
Show quoted text>
> Why use it instead of just using Any?
No, I mean: why have have a type named Bool that features a default coercion that effectively makes it accept absolutely anything and evaluate as 1 for a very wide range of possible input values, then be exepected to favour _that_ over Any in principle? Surely you can see how this might be considered a pitfall, or confusing at the least? As I wrote this, I thought "I can't be the only one!" and, sure enough, only then did I realise that this issue has actually been raised before.
Show quoted text>
> Well, Bool makes your intention clearer to people reading your code.
Yes. I'm not disputing this.
Show quoted text> If you use Any, people are going to need to check further to see how
> the variable is used; if you use Bool, they know you'll be checking
> its truthiness.
Ditto. That's one of the reasons that I'm trying to use the Bool type in the first place, just not the main reason.
If I see Any in a signature then at least I know that any value is permitted to pass. Granted, it won't 'document' whether or not I intend to evaluate it for truthiness but, as far as type validation is concerned (what I'm using Type::Tiny for in the first place!) it does document what will _actually_ happen, which is to allow any value to pass. That's honest. I just don't expect a type named Bool to allow any value to pass, regardless of the underlying design decision that made it so. The !!$value transformation is not the exact sort of nannying I was looking for and I cannot fathom it as a design decision. Further, I suspect that this will be true of some others that discover Type::Tiny in the future, though I anticipate that you will not agree.
In any case, I would suggest that this pitfall be mentioned in the section of the manual where Bool is introduced and described, so as to reduce the likelihood of others making this same mistake. I have my solution in so far as the unwanted coercion can be disabled and I can live with that, given that Type::Tiny is a valuable module and one with no credible competition.
Finally, lest I appear ungrateful, thank you for your continued work on the module.