Hello, I'm really glad to read of your experience, because I was wrestling just yesterday with a problem that feels similar. I wanted to write a simple sub which could accept both an Array and a List, and that was simple:
use NativeCall; sub s(Positional $a) { CArray[num64].new: $a.map(|*)».reals.flat.flat; } # List argument say s((1..6)».Complex).list; # Array argument my @a = (1..6)».Complex; say s(@a).list; (I'm writing a module to interface with libfftw3, which needs arrays of complex numbers expressed as pair of real/complex parts) The next problem was that that sub should actually be a multi, accepting different types and doing different preprocessing before creating the native CArray. I wouldn't find a solution with the ability to accept List and Array and having a type at the same time. This doesn't work: use NativeCall; multi s(Positional[Real] $a) { say 'Real'; CArray[num64].new: $a.map(|*).flat; } multi s(Positional[Complex] $a) { say 'Complex'; CArray[num64].new: $a.map(|*)».reals.flat.flat; } say s((1..6)».Complex).list; my @a = (1..6)».Complex; say s(@a).list; because a List can't be typed. It returns an error: Cannot resolve caller s(List); none of these signatures match: (Positional[Real] $a) (Positional[Complex] $a) I have to admit that I didn't work on this very much, but Vadim's email today ringed a bell. On Sun, Sep 2, 2018 at 2:34 AM Vadim Belman <vr...@lflat.org> wrote: > 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 > > -- Fernando Santagata