Comments (5)
Traditionally (IronPython 2), this was solved by using Unicode character U+00F8 trick in the parameter name, which made the name a valid identifier in C# but not in Python. This trick is no longer working with IronPython3 because Python 3 identifiers can contain Unicode letters too.
Actually IronPython 2 allows unicode identifiers as well so the trick just makes it harder to use.
I agree the whole thing is a confusing mess. It seems like not binding to the ParamArray/ParamDictionary parameters would be entirely reasonable. Here are a few questions that come to mind:
- Could a language opt-in to such a behaviour or would it be stuck with whatever we choose?
- Would PositionalOnly/KeywordOnly need to be attributes of the DLR or could the implementation be done at the language level (in IronPython)?
- Do keyword-only attributes exist in languages other than Python? If not could it be implemented at the language level or would the DLR need to be adapted to allow this? Makes me wonder if the
ParamDictionaryAttribute
is used outside IronPython. - What happens if a method using
KeywordOnly
somehow makes its way back to C# and is used as adynamic
? I guess that's also a question if I define a method likedef test(*, a=1): pass
. Maybe the whole thing is already broken, but it would be unfortunate if a method couldn't be invoked when usingdynamic
.
from dlr.
- Could a language opt-in to such a behaviour or would it be stuck with whatever we choose?
I suppose we could add a (few) new protected virtual method(s) to OverloadResolver
to allow the language to override the default opt-out, but it still does not resolve the issue that currently the DLR does not handle such opt-ins well. I have just found another place in the DLR that assumes no binding to args/kwargs.
- Would PositionalOnly/KeywordOnly need to be attributes of the DLR or could the implementation be done at the language level (in IronPython)?
I was thinking of adding it at the DLR level because handling of keyword arguments is done primarily by DefaultOverloadResolver
but also partly in OverloadResolver
. With the extra protected virtual method approach those attributes can be introduced at the IronPython level, though call failure reason propagation up to OverloadResolver
may be tricky (I assume that the existing protected virtuals are part of the unchangeable official API, but that API is somewhat constrained with respect to handling comprehensive error reporting). So some support at the DLR will be needed; I doubt whether support for PositionalOnly/KeywordOnly could be done without any whatsoever change to the DLR.
- Do keyword-only attributes exist in languages other than Python? If not could it be implemented at the language level or would the DLR need to be adapted to allow this? Makes me wonder if the
ParamDictionaryAttribute
is used outside IronPython.
- What happens if a method using
KeywordOnly
somehow makes its way back to C# and is used as adynamic
? I guess that's also a question if I define a method likedef test(*, a=1): pass
. Maybe the whole thing is already broken, but it would be unfortunate if a method couldn't be invoked when usingdynamic
.
Hm, I don't know how to provide keyword arguments to a dynamic method invocation in C#. Perhaps a way to invoke could be though ObjectOperations.Invoke
? The existing Invoke
overloads do not take keyword arguments either, but it could be added?
Since a builtin method after making its way back to C# will be a BuiltinFunction
, maybe another way it can be invoked is though one of the Call
overloads, made public for this purpose? Those guys do take kwargs.
from dlr.
Alright, I think we could go ahead with excluding binding of ParamArray/ParamDictionary parameters. I would probably make the PositionalOnly/KeywordOnly
attributes a separate proposal (I'd hate to add public attributes and then later realize it wasn't what we really wanted).
Hm, I don't know how to provide keyword arguments to a dynamic method invocation in C#.
I was thinking of something along the lines of:
var engine = Python.CreateEngine();
var scope = engine.CreateScope();
engine.Execute("x = sorted", scope);
dynamic sorted = scope.GetVariable("x");
var iterable = new int[] { 1, 3, 2 };
Console.WriteLine(string.Join(", ", sorted(iterable, reverse:true)));
It looks like this currently works (which is nice) so we'd have to make sure not to break it.
Perhaps a way to invoke could be though ObjectOperations.Invoke?
Yes, it seems like some overloads in ObjectOperations would be useful:
public dynamic Invoke(object obj, object[] args, IDictionary<string, object> kwargs);
// InvokeMember
// CreateInstance
Seems to be one of the recommended way to call things (https://stackoverflow.com/questions/8970458/ironpython-call-method-by-name). I don't see how you can invoke the reversed sorted example via ObjectOperations
right now so even if we don't go ahead with the proposal, some overloads may be worth adding.
Since a builtin method after making its way back to C# will be a BuiltinFunction, maybe another way it can be invoked is though one of the Call overloads, made public for this purpose?
Would be best to have something more agnostic and not rely on the fact that it's a BuiltinFunction
. Invoking a user-function with keyword-only arguments should work the same way.
from dlr.
it seems like some overloads in ObjectOperations would be useful
This is my preferred approach too (over IronPython specific), but I am having second thoughts about simply overloading Invoke
(and InvokeMember
, CreateInstance
). While the signature you suggest is exactly what I had in mind as the most convenient, it would create a cornercase incompatibility with the current behaviour. Since currently parameters
is a param array, providing two parameters of type object[]
and IDictionary<string, object>
is now putting them in a 2-item parameters
array representing two positional arguments, but with the overloads, they would be effectively splatted.
To retain existing behaviour, existing user code would have to change from
engine.Operations.Invoke(f, arr, dict)
to something like
engine.Operations.Invoke(f, new object[] { arr, dict})
Are we okay with that?
Otherwise, maybe a different method name, SplatInvoke
etc.?
I would probably make the
PositionalOnly/KeywordOnly
attributes a separate proposal
Fair enough.
from dlr.
Are we okay with that?
Although it seems unlikely to occur it could indeed break people. I'd be fine with a separate name although I can't think of a good one. I think prefixing with the existing method name would be better for discoverability. I'm not sure I like Splat
(I know it comes up in a few places, but mostly internal). These seem kind of verbose, but could be an option: InvokeWithKeywords
or InvokeWithDictionary
.
from dlr.
Related Issues (20)
- StackOverflowException with large DynamicMethod's
- Interpreter
- DLR for Xamarin HOT 1
- Basic how-to for embedding a new language (with coroutines) HOT 3
- .Net Standard support HOT 3
- Make obsolete duplicate methods
- Add .NET Core 3.0 target that includes COM interop features HOT 2
- Variant Interop Bug HOT 3
- MutableTuple.GetSize does not report proper size if the tuple contains another tuple
- Microsoft.Scripting.Generation.CompilerHelpers.Compile<T> throws PNSE on Mono
- License of DLR sample code HOT 3
- Is `ParamDictionaryAttribute` in the right namespace? HOT 1
- Surface DLR docs for deep linking HOT 13
- Control-C handler uses obsolete Thread.Abort HOT 4
- SYSLIB0006
- Properly handle CA1416 in COM related code
- Advice for debugging hang in CreateDelegate in my DLR-based language? HOT 1
- Suggestion about Assembly.Save and Expression.CompileToMethod HOT 2
- How to add/send ancillary info from CallSites to Binders?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dlr.