fsharp / fslang-suggestions

The place to make suggestions, discuss and vote on F# language and core library features
341 stars 20 forks source link

Allow limiting intellisense in computational expressions with custom methods #1159

Open wilbennett opened 2 years ago

wilbennett commented 2 years ago

I propose we ... (describe your suggestion here)

Have a way to limit the items that show up in intellisense when creating CEs with custom methods. Usually, the intent of these is to populate some structure and having every binding and function under the sun show up is counterproductive. If we can limit intellisense to just the custom methods, they will be much more discoverable and easier for someone who isn't familiar with the expression to use.

One way of approaching this could be to leverage the EditorBrowsable attribute:

[<EditorBrowsable(EditorBrowsableState.CustomMethodsOnly)>]
type MyBuilder() =
    ...

This is opt-in for the creator and the end user could have the option to override.

The existing way of approaching this problem in F# is ...

Every binding and method in scope shows up.

As an aside - I'm not pushing for the following but since they are related, I just wanted to mention:

Here is a sample DSL from Feliz:

    [<ReactComponent>]
    static member Counter() =
        let (count, setCount) = React.useState(0)

        Html.div [
            Html.h1 count
            Html.button [
                prop.style [
                    style.marginLeft 5
                    style.marginRight 5
                ]
                prop.onClick (fun _ -> setCount(count + 1))
                prop.text "Increment"
            ]
        ]

This allows targeted intellisense at every level which allows capabilities to be easily discovered.

  1. It would be nice to be able to replicate this with computation expressions. One of the barriers is not being able to have simple nested CEs. I know that suggestion was previously shot down so, like I said, I'm not pushing. The nice thing about being able to do that using CEs is that you can carry state behind the scenes and allow for more advanced scenarios.

  2. Are the braces for computation expressions really necessary?

let result =
    async
        let! a = ...
        and! b = ...
        return a + b
    |> Async.StartImmediate

Again, not pushing - I can live with the braces. It's times like these when I start having C# PTSD flashbacks though (or is it Post Traumatic Brace Disorder?) :)

Pros and Cons

The advantages of making this adjustment to F# are ...

Easier for a dev new to a CE to discover methods and get up to speed.

The disadvantages of making this adjustment to F# are ...

I can't think of any since this is opt-in and scoped to custom CEs with custom methods.

Extra information

Estimated cost (XS, S, M, L, XL, XXL):

?

Related suggestions: (put links to related suggestions here)

Affidavit (please submit!)

Please tick this by placing a cross in the box:

Please tick all that apply:

For Readers

If you would like to see this issue implemented, please click the :+1: emoji on this issue. These counts are used to generally order the suggestions by engagement.

uxsoft commented 2 years ago

I'm not sure if this needs to be a language feature, maybe it can be solved without attributes or any changes to the language in the tooling by putting all the custom operations to the top and/or letting you filter by suggestion type.

That said I'm using CE's heavily for building UI (https://github.com/uxsoft/fable.builders.antdesign, Fun.Blazor, Fabulous 2.0) and the IntelliSense is awful. Doing something in this direction would go a long way to make F# more suitable for UI development.

cartermp commented 2 years ago

So this is really a tooling concern and not a language concern, but it would need to include an attribute in FSharp.Core to limit whatever is in a completion list only to custom operations as-suggested.

For reference, here are some issues tracking custom operations tooling improvements:

https://github.com/dotnet/fsharp/issues/11784 https://github.com/dotnet/fsharp/issues/4832 https://github.com/dotnet/fsharp/issues/11578

WilBennettJr commented 1 year ago

Hi @cartermp,

Apologies for posting this in the wrong place. Please feel free to remove since this is already covered.