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

Support [<InlineIfLambda>] #3431

Open
MangelMaxime opened this issue Apr 21, 2023 · 3 comments
Open

Support [<InlineIfLambda>] #3431

MangelMaxime opened this issue Apr 21, 2023 · 3 comments

Comments

@MangelMaxime
Copy link
Member

Description

If I understand correctly this news: https://learn.microsoft.com/en-us/dotnet/fsharp/whats-new/fsharp-6#inlineiflambda

This code:

let inline iterateTwice ([<InlineIfLambda>] action) (array: 'T[]) =
    for j = 0 to array.Length-1 do
        action array[j]
    for j = 0 to array.Length-1 do
        action array[j]

let arr = [| 1.. 100 |]
let mutable sum = 0
arr  |> iterateTwice (fun x ->
    sum <- sum + x)

should be equivalent to

let arr = [| 1.. 100 |]
let mutable sum = 0
for j = 0 to arr.Length-1 do
    sum <- sum + arr[j]
for j = 0 to arr.Length-1 do
    sum <- sum + arr[j]

However, when looking at the generated JS it seems like [<InlineIfLambda>] does nothing:

export const arr = toArray(rangeDouble(1, 1, 100));

export let sum = createAtom(0);

(function () {
    const action_1 = (x) => {
        sum(sum() + x);
    };
    const array_1 = arr;
    for (let j = 0; j <= (array_1.length - 1); j++) {
        action_1(array_1[j]);
    }
    for (let j_1 = 0; j_1 <= (array_1.length - 1); j_1++) {
        action_1(array_1[j_1]);
    }
})();

Expected and actual results

Should generates something like that I think:

export const arr = toArray(rangeDouble(1, 1, 100));

export let sum = createAtom(0);

for (let j = 0; j <= (arr.length - 1); j++) {
    sum(sum() + arr[j]);
}

for (let j = 0; j <= (arr.length - 1); j++) {
    sum(sum() + arr[j]);
}

Related information

  • Fable version: 4.0.6
  • Operating system: Linux
@MangelMaxime
Copy link
Member Author

MangelMaxime commented Apr 21, 2023

To give a bit of context:

[<InlineIfLambda>] is useful when using CEs for building a DSL and it can greatly improve memory and performance usage from what I understood

I am trying to work on a CE DSL for JSX and I feel like if [<InlineIfLambda>] was working then I could have a DSL with almost zero cost in term of performance compared to JavaScript.

@alfonsogarciacaro
Copy link
Member

I think it's possible, although I'm not sure how much work it will involve. This would require "conditional" inlines and check the argument to decide if the function must be inlined or not.

In any case, be careful when using CEs to design a DSL. I've received reports that when used in a large project compilation starts to get really slow, see: dotnet/fsharp#14429

@MangelMaxime
Copy link
Member Author

Rah that's really unfortunate ... thank you for letting me know of this problem.

I thin I will still explore that direction but probably keep it as a POC depending on the situation.

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

No branches or pull requests

2 participants