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

Should we allow [<Erase>] to works for members? #3929

Closed
MangelMaxime opened this issue Oct 18, 2024 · 2 comments · Fixed by #3940
Closed

Should we allow [<Erase>] to works for members? #3929

MangelMaxime opened this issue Oct 18, 2024 · 2 comments · Fixed by #3940

Comments

@MangelMaxime
Copy link
Member

Description

I was looking into optimising the output of Oxpecker.Solid because it contains a lot of noise not used by the library (it is using Fable.CompilerPlugin to rewrite some of the output).

In theory, the generated noise should be removed by bundlers like Vite, etc. but not having it generating is even better IHMO. It makes the code easier to read.

open Fable.Core
open Fable.Core.JsInterop
open System

[<Erase>]
type input() =
    
    [<Erase>]
    member this.onChange
        with set (_: obj -> unit) = ()

generates

export function input__set_onChange_61A0B331(this$, _arg) {
}

This function is never used by Oxpecker output, so it would be nice to not generate it at all.

One way of doing it is by inlining the onChange member but by doing so Fable.AST doesn't contains information about onChange call anymore.

module Test

open Fable.Core
open Fable.Core.JsInterop
open System

[<Erase>]
type input() =

    [<Erase>]
    member inline this.onChange
        with set (_: obj -> unit) = ()

let x = input(onChange = fun _ -> ())

generates

export const x = (() => {
    let returnVal = input_$ctor();
    const this$ = returnVal;
    return returnVal;
})();

@ncave Do you see a danger in allowing [<Erase>] to apply to members?

One of them is that if someone apply [<Erase>] to a member and try to use that said member later it would fails at runtime but this is expected and is already the case when used on the type.

[<Erase>]
type MyClass() =
    class end

generates

export const x = MyClass_$ctor(); // MyClass_$ctor doesn't exist
@ncave
Copy link
Collaborator

ncave commented Oct 19, 2024

@MangelMaxime For me [<Erase>] on type is mostly useful for types that have [<Emit>] members.
But I can see extending this to cleanup more generated members. Perhaps a more concrete example can clarify the use, if you have one.

@MangelMaxime
Copy link
Member Author

The use case in Oxpecker.Solid is that the user write:

[<SolidComponent>]
let MyButton =
    button(class' = "button", onChange=onChangeHandler){
        "My button"
    }

and then thanks to Oxpecker.Solid.FablePlugin the output becomes something like

const MyButton =
	<button class="button" onChange={onChangeHandler}>
		My button
	</button>

The properties on types like button are here only for the purpose of exposing the API to F#. This is kind of a new type of binding made for this specific syntax in mind.

We could perhaps add a custom attribute to Oxpecker.Solid.FablePlugin to flag such properties and remove them from the output. But I don't know if Fable plugin can remove code and not just modify it. This would also feel redundant with [<Erase>].

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

Successfully merging a pull request may close this issue.

2 participants