Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wishlist] Make Signatures and Parameters first class citizens #2594

Closed
scovit opened this Issue Jan 9, 2019 · 22 comments

Comments

Projects
None yet
3 participants
@scovit
Copy link

scovit commented Jan 9, 2019

The Problem

It is very complicated to dynamically create Parameter and Signature objects in code. At the moment, this task requires reverse engineering and writing nqp code setting up all the attributes correctly. In contrast, typing Signature literals is very easy (using the :() syntax) but does not cover all the use cases. A particularly interesting use-case is to link at runtime to frameworks providing functions and type informations such as Cocoa or GObject.

Example use case

With nativecast it is already possible to link to an exported C function symbol at runtime, this allow, for instance, this code to run:

dlsym(Pointer, Str --> Pointer) is native { };
my $point = dlsym(Pointer.new(0), "puts");
my &f = nativecast( :( Str --> int32), $point);
f("ciao")

This issue aims at completing this functionality, and allowing the following code to also work:

my $par1 = Str;
my $ret    = int32;

dlsym(Pointer, Str --> Pointer) is native { };
my $point = dlsym(Pointer.new(0), "puts");
my &f = nativecast(
      Signature.new(
            parameters => (
                  Parameter.new(nominal_type => $par1, flags => $SIG_ELEM_MULTI_INVOCANT),
            ),
            returns => $ret
      ), $point
);
f("ciao")

Expected Behavior

I think it should work

Details

Both Signature and Parameter are defined in BOOTSTRAP.nqp and expanded in core, World.nqp contains the nqp code to create Signature and Parameter used by the Perl compiler.

@lizmat

This comment has been minimized.

Copy link
Contributor

lizmat commented Jan 9, 2019

Wouldn't $SIG_ELEM_MULTI_INVOCANT need to be externalized as well then? Or some interface to it?

@lizmat

This comment has been minimized.

Copy link
Contributor

lizmat commented Jan 9, 2019

So if I understand your request: you want Parameter and Signature to become first class citizens, without spilling too much of the internals.

@scovit

This comment has been minimized.

Copy link
Author

scovit commented Jan 9, 2019

Yes: it would be great to have a nice interface and the multi invocant is very internal. I think that this is not trivial because many properties of the parameters, including this, are there just to serve the signature.

For my task, making Signature a first class citizen might be enough. This might be easier.

@scovit

This comment has been minimized.

Copy link
Author

scovit commented Jan 9, 2019

E.g.

      Signature.new(
            parameters => (
                  Str,
            ),
            multi-invocants => 1,
            returns => $ret
      ), $point

and multi-invocants can default to the number of parameters

@scovit

This comment has been minimized.

Copy link
Author

scovit commented Jan 9, 2019

also parameters can be an Array that allows names, types and certain flags (e.g. positional or named, where clauses, etc) at the same time. In this sense, it makes sense to make Parameter also first-class, but to provide interfaces only to parts of it. I really think the API should be decided by somebody with more insight than me.

@scovit scovit changed the title [wishlist] add BUILD submethods to Parameter and Signature classes [wishlist] Make Signatures first class citizens Jan 9, 2019

@scovit scovit changed the title [wishlist] Make Signatures first class citizens [wishlist] Make Signatures and Parameters first class citizens Jan 9, 2019

@vrurg

This comment has been minimized.

Copy link
Contributor

vrurg commented Jan 10, 2019

If anybody going to count votes on this, take mine, pls! I didn't get enough time and guts to go as deep, as @scovit managed to.

@lizmat

This comment has been minimized.

Copy link
Contributor

lizmat commented Jan 10, 2019

First stab at making Parameter a first class citizen: 3d3578b

@scovit

This comment has been minimized.

Copy link
Author

scovit commented Jan 10, 2019

Thank you @lizmat ! I think your code still needs some work: for some reason it cannot create a Parameter with an imported type, e.g. Pointer

$ perl6 -Ilib -MNativeCall -e 'my $type = Str; say Parameter.new(type => $type)'
Str $

$ perl6 -Ilib -MNativeCall -e 'my $type = Pointer; say Parameter.new(type => $type)'
Failure $
@lizmat

This comment has been minimized.

Copy link
Contributor

lizmat commented Jan 11, 2019

Fixed with c4723cb .

@lizmat

This comment has been minimized.

Copy link
Contributor

lizmat commented Jan 11, 2019

BTW, Parameter.new(type => $par1 should be enough now: the $SIG_ELEM_MULTI_INVOCANT is set unless inhibited by specifying exclude => True or of course :exclude.

@scovit

This comment has been minimized.

Copy link
Author

scovit commented Jan 11, 2019

Great, I think it is a very good job! I keep the issue open for now to do some extra testing.

@lizmat

This comment has been minimized.

Copy link
Contributor

lizmat commented Jan 11, 2019

Commits so far caused NativeCall breakage for Parameter objects that got roles mixed in. This has been fixed in e463518

@scovit

This comment has been minimized.

Copy link
Author

scovit commented Jan 13, 2019

Do you have any objection to add support for binding also the $!sub_signature attribute? This is quite common and useful in NativeCall to define callbacks, and in general for de-structuring arguments.

@lizmat

This comment has been minimized.

Copy link
Contributor

lizmat commented Jan 13, 2019

No, I don't :-) How would you propose to do that?

@lizmat

This comment has been minimized.

Copy link
Contributor

lizmat commented Jan 13, 2019

Just add a sub-signature => Signature:D parameter ?

@scovit

This comment has been minimized.

Copy link
Author

scovit commented Jan 13, 2019

Yes, that would do the job 👍

@lizmat

This comment has been minimized.

Copy link
Contributor

lizmat commented Jan 13, 2019

Added with 7be075e

@lizmat

This comment has been minimized.

Copy link
Contributor

lizmat commented Jan 13, 2019

(Untested, I might add :-)

@scovit

This comment has been minimized.

Copy link
Author

scovit commented Jan 13, 2019

I think I spotted a bug in Signature.new:

$ perl6 -e 'sub ciao { }; say &ciao.signature'
()
$ perl6 -e 'say Signature.new()'
Type check failed in binding to parameter '$returns'; expected Any but got Mu (Mu)
  in block <unit> at -e line 1

Signature.newshould probably generate the void signature instead of throwing an error.

@lizmat

This comment has been minimized.

Copy link
Contributor

lizmat commented Jan 13, 2019

Fixed with 081b15e

@lizmat

This comment has been minimized.

Copy link
Contributor

lizmat commented Jan 18, 2019

Any other things that need to be implemented? Or can this ticket be closed now?

@scovit

This comment has been minimized.

Copy link
Author

scovit commented Jan 18, 2019

Thank you for asking, I close the ticket since what has been done is working for me

@scovit scovit closed this Jan 18, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.