Open aolney opened 8 years ago
This seems a better fit for pythonnet mailing list or a wiki page, since I do not see any issue, is there? I also copied your answer here:
http://stackoverflow.com/a/34207705/2230844
Folks from Deedle that is written in F# use pythonnet extensively.
Not issue in the sense of bug but perhaps in the broader sense https://guides.github.com/features/issues/
I'm not sure if there is an appropriate label that could be applied to this issue. It is not an enhancement per se but might be useful in future planning as another case study in dynamic.
Thanks for the Deedle/pythonnet connection
The main problem I have with F# is not being able to use the standard arithmetic operators. This is a limitation of the language, of course, not of Python.NET.
I resorted to this for the time being but needless to say it's not an optimal solution:
let (?+) a b = a?__add__(b)
The only other solution I can think of at this moment is forking pythonnet to define the respective static methods (e.g. op_Addition) in PyObject (so they become accessible from F#) and maybe using a custom ? operator that always returns a PyObject (as opposed to a raw obj)
Another way would be to submit a pull request to pythonnet with f# specific code enabled using compilation symbol (like it is done now for various platforms) or even runtime detection. Of course basic tests would be welcome.
BTW, why F# uses special arithmetic operators?
On Friday, March 18, 2016, Steven notifications@github.com wrote:
The main problem I have with F# is not being able to use the standard arithmetic operators. This is a limitation of the language, of course, not of Python.NET.
I resorted to this for the time being but needless to say it's not an optimal solution:
let (?+) a b = a?add(b)
The only other solution I can think of at this moment is forking pythonnet to define the respective static methods (e.g. _opAddition) in PyObject (so they become accessible from F#) and maybe using a custom ? operator that always returns a PyObject (as opposed to a raw obj)
— You are receiving this because you commented. Reply to this email directly or view it on GitHub https://github.com/pythonnet/pythonnet/issues/112#issuecomment-198602887
It's actually the other way around: DynamicObject has direct support from the C# compiler, so the dot operator gets mapped to DynamicObject.TryInvokeMember/TryGetMember/etc and the arithmetic operators get mapped to DynamicObject.TryBinaryOperation/TryUnaryOperation/etc F# has no such thing which is why you need to import the third party FSharp.Interop.Dynamic library so you can use the ? operator and for the time being there's no solution regarding the arithmetic operators.
@matthid did you encounter the issues above in your F# code with pythonnet? If yes, how did you workaround this?
I think @royalstream has said just about everything. There is no particular issue either on this (pythonnet) or the F# side. There is no (and probably wont be) dynamic support by the F# compiler.
I like the suggestion to add the operators at PyObject (eg op_addition).
I should note here that I immediately typed/casted/converted all results to static types. Therefore I did never notice this issue.
https://github.com/matthid/googleMusicAllAccess/blob/develop/src/GMusicApi/GMusicApi.fs#L176
https://github.com/matthid/googleMusicAllAccess/blob/develop/src/GMusicApi/PythonInterop.fs#L742
And I build a computation expression to not forget to gather and release the GIL: https://github.com/matthid/googleMusicAllAccess/blob/develop/src/GMusicApi/PythonInterop.fs#L20
More details: https://yaaf.de/blog/post/2016-05-28/Having%20Fun%20with%20Computation%20Expressions
@matthid thank you for the feedback, I included a link to your blog post in wiki:
https://github.com/pythonnet/pythonnet/wiki
BTW, congratulations on being featured in Microsoft weekly news!
https://blogs.msdn.microsoft.com/dotnet/2016/05/31/the-week-in-net-5312016/
@aolney I found your blog post as well (Using NLTK from F#) and linked it in wiki.
As described below the most significant complaint is that you can't use F# primitive operators like (+) on numpy arrays without an error. The workaround is to use the corresponding numpy function as demonstrated.
It would make sense to track this with an F# language suggestion. But the techniques you are using today make sense.
FSharp.Interop.Dynamic has operators now for dynamic objects. Version 4.0 (current beta package on nuget. )
open FSharp.Interop.Dynamic.Operators
some F# related issues: https://github.com/pythonnet/pythonnet/issues/574
I've used F# to do some of the nice dynamic interop with pythonnet rather than the c# dynamic keyword approach. Not sure if it is truly helpful over c# dynamic, but it may be a bit more concise and interesting.
Here is some code that shows the functionality. The key is to use fsprojects/FSharp.Interop.Dynamic@318f50b234bc8248c78451a0fac0d783b493663e (actually whatever is currently available in nuget). This helped me get closer to the goal behavior of fsprojects/FSharp.Interop.PythonProvider@f3cdabf0f4e198fe5d02bd36d68aacb424c7cbe4 but of course without the type provider mojo (meaning user perceived behavior rather than implementation behavior). I used pythonnet from tonyroberts/pythonnet@21270ebe858267dc11db74c57181ce5c61ee5a29 , CPython3.4, the matching NLTK distribution, VS2015, Windows 10.
As described below the most significant complaint is that you can't use F# primitive operators like (+) on numpy arrays without an error. The workaround is to use the corresponding numpy function as demonstrated.
Also if a complicated call is made like
nltk?corpus?brown?tagged_words(Py.kw("categories", "news") )
the debugger seems to time out the expression evaluation (requiring print statements). Though in general the expression evaluation on the dynamic types returned is not very helpful, so this isn't a major drawback.