Hi everybody,

I'm just transferring here a StackOverflow topic 
https://stackoverflow.com/questions/52117678/coercion-type-checking-manually-reproduce-perl6-standards
 because what was a question over there turned immediately into a discussion 
which doesn't fit into SO format. Not sure if I gonna get any concrete answers. 
But hope to make it a food for thought about some of the language rough edges I 
stumbled upon over the last month or so. Also please keep in mind that despite 
my 20 years with Perl 5 I'm a complete newby in Perl 6 with roughly just 2.5 
months of real life use on my hands.

First of all, I would like to answer the most important question raiph (sorry, 
don't know your real name) has asked me: why? 

My motivation for writing AttrX::Mooish was very much strait-forward: I have a 
work project on my hands which I wanna implement in Perl6. Yet, I have an 
internal framework for such projects written in Perl 5. I wanted to adapt the 
framework for the new language because me trying to avoid intermixing Perl5 and 
Perl6 as much as it only possible. Since the framework is based on Moo and 
utilizing all the lazy, triggers, etc. stuff it was desirable to get it all for 
Perl6. Of all Moo's functionality the existing Perl6 modules were only about 
laziness and their implementation wasn't even close resembling Moo/Moose 
behavior.

So, the key point of my module: I needed it a month ago. Hopefully, this 
sufficiently explains the approach I chose.

Now, on the decisions I made while implementing it.

First of all, I wanted to make the module as transparent for a user a possible. 
It basically means that one should not be worried much about using 'is mooish' 
trait and what side effects would it cause to his code. This is why Proxy is 
used as an attribute container. It allows for using of auto-generated accessors 
or user-provided ones without extra headache of how to deal with conflicts. 
It's being said that Proxy is problematic in many aspects, but it would be 
eventually fixed, wouldn't it? So far it does the job for me.

This is where I get to the original point of SO subject. It is clear that with 
Proxy I had to use an external storage for attribute values. It also means that 
the default Perl's coercion and type checking rules are not applicable. But as 
it was told above, I wanted

has Str @.a;

and

has Str @.a is mooish(...);

to be totally identical. Which is non-trivial as in the second case the actual 
array would be stored as value in a hash (the external storage). This is why 
mimicking the default Perl's rules had to be done manually by AttrX::Mooish. I 
wish I could re-delegate it to Perl6 itself, but so far my research of the core 
source didn't provide any useful results. Though, frankly, I didn't have enough 
time for it. (While writing this I have achieved an acceptable level of 
compatibility which allows me to proceed with the main project.)

Hope the above answers most of raiph questions. Now, I'd try to answer a couple 
of others.

Aiui the existing implementation of Proxys suffers from repeated calls. So a 
read or write can happen several times where you might expect only one.

So far, I only seen this bug with say. And no, this is not the problem.

What is confusing me is that it's the second time I get advised against use of 
Proxy because of its problems. Is it a first-class member of Perl6 class family 
or is it just a play toy? 

my Array[Str] $a = ["a", "b", "c"];
my Str @a = ["a", "b", "c"];

Regarding the explanations on differences between these two lines. Well, when 
you explain this it makes sense. But look at the situation from the decent user 
(which is what I am most of the time) perspective. He takes the second line, 
sees that it works as excepted. Then he takes what @a.WHAT reports back and 
sees that it is actually Array[Str]. He tries the first line and... boomer? 
"Type check failed in assignment to $a; expected Array[Str] but got Array"!! 
What??? On SO raiph says:

because the = is doing list assignment, i.e. assigning each of the elements on 
the right into a Str type constrained Scalar on the left and all of those 
assignments pass the individual scalar type checks. 

But this difference between list and scalar assignment isn't mentioned anywhere 
on docs.perl6.org. All one can find is that they exists and have different 
precedence. Otherwise the difference between the two assignments is quite 
counterintuitive and, to my view, it contradicts to DWIM.

Similar case is with Array ~~ List against List ~~ Array. If for any reason one 
needs to test if a value could be assigned to a container prior to the actual 
assignment it would really be hard to grasp for the first time why my @a = <a b 
c> works whereas my Array $a = <a b c> fails.

PS. BTW, while researching the core sources I discovered a potential problem 
with DefiniteHOW and SubsetHOW. They both define their own find_method() which 
is re-delegating to their base type HOW.find_method. But they don't support 
named parameters. Combined with classes with FALLBACK this may cause some 
unwanted side-effects. Shall it be reported as a bug? (BTW, quick grepping has 
also found RolePunning, MethodDelegation with potentially same problem).

Best regards,
Vadim Belman

Reply via email to