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

Allow delegates / anonymous functions #144

Open
caesay opened this issue Feb 19, 2024 · 6 comments
Open

Allow delegates / anonymous functions #144

caesay opened this issue Feb 19, 2024 · 6 comments
Labels
enhancement New feature or request

Comments

@caesay
Copy link
Contributor

caesay commented Feb 19, 2024

I'm not suggesting that Fusion should support people writing anonymous / delegate functions in Fusion, but that our generated code allows people to provide delegates.

It's a very common library practice to provide a method which takes a delegate for user logic:
void doAthing(Action<string> onComplete)

Since Fusion is already very similar to C#, supporting the the Action<T1, T2, T3, ..> and Func<T1, T2, T3, ..., TResult> would be both easily understandable and very powerful. This would allow some kind of basic async library code to exist without proper async/promise support existing in Fusion.

This declaration can be very straightforwardly translated into the native delegate types for each language.

@pfusik pfusik added the enhancement New feature or request label Feb 20, 2024
@pfusik
Copy link
Collaborator

pfusik commented Feb 20, 2024

This is a major language feature. Fusion used to have delegates in version zero.

A delegate is not only a code reference (function pointer), but also an object reference. In C# you can make delegates to both static and instance methods. How would you map that to C? How about references to abstract/virtual methods?

@caesay
Copy link
Contributor Author

caesay commented Feb 20, 2024

I don't know how we'd do it for C because I am not really a C programmer. However I think a lot of your questions don't matter for what I'm proposing.

My suggestion is that we will not allow delegates or lambda's in Fusion itself, but as a means for external code to pass in functionality. All we need to do in Fusion is:

  • Allow a delegate type to be specified in method parameters (eg. Action and Func)
  • Treat like an object reference for variable/field assignment
  • Allow it to be called like a function (eg fn(myArg))

The developer generating and passing in the delegate will be external code written in the native language. So for C, perhaps our Func<> translates to a raw function pointer, and a C developer trying to use this function will know that it must be to a static method only. We don't care about that, because Fusion does not allow writing delegates in Fusion.

The drawback to this approach is that you will not be able to call a Fusion method containing a delegate parameter in Fusion, because we can't instantiate the delegate ourselves. I think this is a small price to pay because it allows us to create more powerful API's that are designed to be called by the native language anyway.

Perhaps creating anonymous functions and calling delegates from within Fusion code could be implemented later as a separate feature?

@pfusik
Copy link
Collaborator

pfusik commented Feb 20, 2024

C developer trying to use this function will know that it must be to a static method only

That's a very painful restriction.

What you propose is very similar to what I already implemented in version zero. Delegates could be accepted from the outside, but not constructed in Fusion. The C translation was a struct with a function pointer and a void * for the data.

Java actually never had delegates, these are all just interfaces with one method. If Java can get away with no delegates, why not Fusion? Just define abstract methods and subclass in the target language. This works well for my own Fusion projects.

@caesay
Copy link
Contributor Author

caesay commented Feb 21, 2024

If the goal of Fusion is to provide a "native" library, such that it appears to have been written by an expert in said language, I don't think that's a fair requirement. I started out with abstract class/methods when writing my Fusion code, but when I got around to integrating it into sample apps in the native languages it just got totally out of control. So now I am using string replacement after the Fusion build in my build script to hackily support delegates as it provides a much cleaner API.

The restriction to not allow delegates to be created in Fusion (but can be accepted from outside) I think is a logical first step (hopefully with full delegate support coming later). We can use abstract/derived classes in our Fusion code internally, but our public API needs to be logical and easy to use.

I thought Java did support delegates (is that not what Function<T,Y> is?), but I guess if we are targeting a language that really does not support delegates then we can fall back to emitting a class with an abstract method only for those languages...

@pfusik
Copy link
Collaborator

pfusik commented Feb 21, 2024

To be clear, I'm not against delegates. I have limited resources and need to assign priorities to various tasks. In my Fusion code so far delegates did not feel that important.
Yes, the goal is to have a feeling of native code, but not for one, but 10 different languages. What's your experience with these languages so I can better understand your point?
I'd love to have a look at your code to understand the use cases for delegates.

@caesay
Copy link
Contributor Author

caesay commented Feb 21, 2024

I guess this is where it was added the first time a1ed6e1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants