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

Reply via email to