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

Reply via email to