WebSharper 3 had tail call optimization which was not carried over to WebSharper 4 yet due to the common statement-based AST. But it would be easier to include tail call optimization just for the F# path by adapting the WebSharper 3 logic with the change that it is also applied on module/type level let rec definitions.

  • github

    This would be really useful for us. I've been testing some of our modelling tools in WebSharper 4 and a lot works. However, some of the analysis methods immediately stack overflow due to a lack of tail call optimization.

    If it's also possible to make the optimization more generally applied that would be amazing, for example, heavily simplified from our code:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    (* this form **is not** tail call optimised in WebSharper 3.x *)
    let summer = 
        let rec sum acc list = 
            match list with
            | [] -> acc
            | x :: xs -> sum (acc + x) xs
        
        let summed = sum 0 [ 1; 2; 3 ]
        { name = "Calculation"
          answer = summed }

    and I have to manually rewrite to this:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    (* this form **is** tail call optimised in WebSharper 3.x *)
    let summerOptimised =
        let innerSummer list =
            let rec sum acc list = 
                match list with
                | [] -> acc
                | x :: xs -> sum (acc + x) xs
    
            sum 0 list
    
        let summed = innerSummer [ 1; 2; 3 ]
        { name = "Calculation"
          answer = summed }
  • github

    This topic has been closed.

  • JankoA

    Transforming tail-recursion to loops:

    • let rec expressions with single or mutual recursion
    • module or class (in default constructor) let rec expressions with single recursive function
    • class static members, calling itself but no other members of the same class annotated with JavaScript (so inlines do not opt-out of optimization)
    • class instance members, calling itself but no other members of the same class annotated with JavaScript and also calling only on the this object

    There is some possibilities for improving interplay of tail-recursion and curried/tupled argument optimizations, but runtime tests for this are passing in current state.