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

Addition of int array elements #72

Closed
Ekul34 opened this issue Aug 8, 2023 · 1 comment
Closed

Addition of int array elements #72

Ekul34 opened this issue Aug 8, 2023 · 1 comment
Assignees
Labels
Help/Question A question the answer to which may help other users in the future On discussion

Comments

@Ekul34
Copy link

Ekul34 commented Aug 8, 2023

I might be misunderstanding how this is meant to work, but why is it that the following results in an error.

var runtime = Funny.Hardcore
    .Build("a = x[0] + x[1]");
runtime["x"].Value = new int[] { 1, 1 };
runtime.Run();
Unhandled exception. System.InvalidCastException: Unable to cast object of type 'System.Int32' to type 'System.Double'.
   at NFun.Functions.AddFunction.DoubleFunction.Calc(Object a, Object b)
   at NFun.Interpretation.Nodes.FunOfTwoArgsExpressionNode.Calc()
   at NFun.Runtime.FunnyRuntime.Run()

But if I call a function that just returns without any changes, there is no casting issue.

var runtime = Funny.Hardcore
    .WithFunction("func", (int number) => number)
    .Build("a = func(x[0]) + func(x[1])");
runtime["x"].Value = new int[] { 1, 1 };
runtime.Run();
@tmteam tmteam self-assigned this Aug 9, 2023
@tmteam
Copy link
Owner

tmteam commented Sep 5, 2023

That's a good question.
In this example, this is the expected behavior at the moment.

Since the Hardcore api is used, Nfun is obliged to fully determine the types of input variables by the time of launch.

In the first example, a = x[0] + x[1] - x will be defined as real[]

In the second example, a = func(x[0]) + func(x[1]) - x will be defined as int[]

Explanation

Since all we know is that the type of an array element can be added - that is, it is some kind of arithmetic type (int32 uint32 int64 uint64 real). Since nothing else is known, Nfun uses the most common type - real.

Btw - if we created a custom function in the script f(x) = x[0]+x[1], then such a function would be generalized. But the body of the script must be solved without any generics

In the second case, we see that the type of the array element is used only as int32

How to fix

if we are sure that x is always int[], then we can tell nfun about it via the apriori api:

var runtime = Funny.Hardcore
    .WithApriori<int[]>("x")
    .Build("y = x");

If we do not know this before compiling the script (only the user can set this), then this can be specified in the script in one of the ways:
either a:int = x[0] + x[1]
either x:int[]; a = x[0] + x[1]

Or initialize the variable value with the correct type

runtime["x"].Value = new double[] { 1, 1 };
But in difficult cases, this may require additional verification:

if(runtime["x"].Type.Equals( FunnyType.ArrayOf(FunnyType.Int32))
// do assignment here

Why doesn't Nfun do the conversion itself?

You can make your example work, but the question arises - does the user understand exactly what he is doing? After all, if int[] is installed in the script where real[] is expected, then it turns out that we will simply hide the problem - after all, the user gets an unexpected type and sooner or later, on a more complex example, it can all break in the most unexpected way. I'm not sure yet that we need to change the current behavior. Maybe improve the error message. But this is a debatable point (I'm waiting for additional arguments)

@tmteam tmteam closed this as completed Sep 5, 2023
@tmteam tmteam added the Help/Question A question the answer to which may help other users in the future label Dec 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Help/Question A question the answer to which may help other users in the future On discussion
Projects
None yet
Development

No branches or pull requests

2 participants