On Tue, Jan 28, 2020 at 01:07 Kevin Pye <kevin....@gmail.com> wrote: > There's no need to ask essentially the same question three times. >
And I answered before noticing there was more activity in another thread. > https://docs.raku.org/routine/range <https://docs.raku.org.routine/range> > is quite clearly the wrong page. That's about a method on the class > X::OutOfRange, and not a method on Int. You want > https://docs.raku.org/routine/Range, which will unfortunately not be much > more useful. > > Your original error message "Invocant of method 'Range' must be a type > object of > type 'Int', not an object instance of type 'Int'" is much more useful. > > Your variable $u contains a variable of type Int. What the method Range > wants is a "type object of type 'Int'" which is not the same thing.This is > what you would get with a definition like "my UInt $u;". $u is now a > variable containing no definite value, but is of type UInt. If you were to > "say $u" you would get "(UInt)", which is a type object. "say $u.Range" > would then give "0..^Inf". > > This is related to the ":D" and ":U" forms in signatures. "sub x(Int:D > $arg)" would require the subroutine to be passed an actual object of type > Int. "sub y(Int:U $arg)" would need to be passed a "type object of type > 'Int'". If you were to check the source you would find the signature of > Range to be something like "method Range(Int:U --> Range)". > I’d say in general, ToddAndMargo seems to be stuck on signatures of `:D` vs `:U` and how they relate to the type system and definedness. Perhaps this relates to the very different ways in which we relate to undefined values in Raku vs. Perl5. In Perl5, undefinedness meant something that it still _can_ mean, and in the course of ordinary “business logic” programming perhaps still most often means: a yet-to-be-filled container, an unassigned value. In Perl5 it was also very obviously a sort of falseness and frequently used in that manner. In Raku, “an undefined Int” means not only the above but also what it means in English: the notional value of Int-ness. If you try to use rvalue “undef” in Raku as you would in Perl5, you’ll get a very nice error message to explain: ```console > undef ===SORRY!=== Error while compiling: Unsupported use of undef as a value; in Perl 6 please use something more specific: an undefined type object such as Any or Int, :!defined as a matcher, Any:U as a type constraint, Nil as the absence of an expected value or fail() as a failure return ------> undef<EOL> ``` So, to distill and recap: 1. In signatures, `:D` and `:U` mean “defined value” vs. “undefined value” 2. At least as often as `T:U` (where `T` is some type) literally means “a container of type T that has not yet been assigned a value”, it means “the notion of T” or simply “the literal type value, `T`”. Since types are among the things that define namespaces, a unary routine `routine-name` with a `T:U` parameter often means, “something you can usefully call as `T.routine-name” 3. In Perl5 it’s quite rare that a routine (or rather, for Perl5, func and/or sub) works on a variable before it’s assigned to but fails after. In Raku it’s quite common, as `.Range` shows. This may be a source of confusion, but if you remember that definedness doesn’t just mean “assignedness” but “notionality vs. concreteness”, it makes more sense. 4. All that said, in the case of multis it’s not unknown to use `:U` for the “unassigned” rather than “undefined” connotation, as one might use a top-level sub guard, to fail with a useful diagnostic directing one to the proper usage of a routine. 5. `Int` is a type value. Type values are always undefined. `my Int $x;` creates a $x which is a container to hold an Int, but until it does, it _is_ still an `Int`, an undefined `Int`, which makes it exactly equal to the literal `Int`—i.e., a type object. It’s not great programming practice to use a single container as both a type value and a concrete value, but in diagnostics such as the one for Range that surprised you, you need to be aware that it _can_ work that way. Trey