title: Coercion/type checking: manually reproduce Perl6 standards
body: <p>I have a Module <code>AttrX::Mooish</code> which implements some of attribute features of Moo/Moose frameworks (lazyness, trigger, etc.). I also wanted the module to be as transparent to the end user as possible meaning support for both private and public attributes. It works by replacing attribute's container with a <code>Proxy</code> and storing its value in external storage. It also means that all the type checking and coercion Perl6 was doing is now my responsibility. My target is to mimic the default behavior is much as possible. I.e. for the end user:</p>
  <p><code>has MyClass @foo is mooish(...);</code></p>
  <p>must work the same as it would without the trait applied. Unfortunately, the subject of type manipulations is so much complicated and ununified in the language core that the more problems I fix the more problems I get afterwards. For example:</p>
  <p><code>my Str @a = &lt;a b c&gt;; my Str @b = [1,2,3]</code></p>
  <blockquote>
  <p><code>Type check failed in assignment to @b; expected Str but got Int (1)</code></p>
  </blockquote>
  <p>As expected.</p>
  <p><code>my Str @a; say @a.WHAT</code></p>
  <blockquote>
  <p><code>(Array[Str])</code></p>
  </blockquote>
  <p>Sure.</p>
  <p><code>my Array[Str] $a = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;];</code></p>
  <blockquote>
  <p><code>Type check failed in assignment to $a; expected Array[Str] but got Array ($[&quot;a&quot;, &quot;b&quot;, &quot;c&quot;])</code></p>
  </blockquote>
  <p>Well....</p>
  <p><code>my Array[Str] $a = &lt;a b c&gt;;</code></p>
  <blockquote>
  <p><code>Type check failed in assignment to $a; expected Array[Str] but got List ($(&quot;a&quot;, &quot;b&quot;, &quot;c&quot;))</code></p>
  </blockquote>
  <p>Not even coercing <code>List</code> to <code>Array</code>!</p>
  <p>No wonder that the final typecheck line in my trait code:</p>
  <p><code>$coerced-value ~~ $attr.type</code></p>
  <p>Fails here and there despite same values/types used in variable/attribute assignments work OK.</p>
  <p>I have a question with no hope of getting any positive answer to it: is there a single entry point used by the assignment operator which does all the coerce/typecheck? Ideally I would simply:</p>
  <pre class="lang-perl prettyprint-override"><code>$value = coerce($value, $type);
  check-type($value, :type($attr.type), :name($attr.name))
  </code></pre>
  <p>I tried to trace down from the grammar, but haven't got enough spare time to complete this yet. Besides, it is mostly nqp which I don't know and can't really understand.</p>
  <p>But since the existence of such entry point(s) is unlikely I would like to ask for any advises related to this area. Like, for example, SmokeMachine on #perl6 provided me with a great idea of obtaining base type of a parametrized type using <code>.^parents</code> method.</p>
  <p>So far, the biggest problems are with:</p>
  <ol>
  <li>To check if type is parametrized I can't use a single role or class to match against. So far the only approach I have is by finding if  there is <code>of</code> method and testing its output. Unfortunately, if a class provides <code>FALLBACK</code> very unclear error message (the one about AUTOGEN) is produced. <code>:no_fallback</code> is desirable, but definite and subset types have their own <code>find_method</code> which doesn't support named parameters and I end up with another error message.</li>
  <li>If a prepare type-related attributes (<code>$!coerce-type</code>) in <code>compose</code> method of my trait role applied to the <code>Attribute</code> object (where actually the attributes are declared) I find them later at run-time unitialized. Guessing its something related to compose time. But wanna be sure if nothing is missed here.</li>
  <li>Is there any better way to perform type-check than <code>$value ~~ $type</code>?</li>
  </ol>