Skip to content

if let expression #705

@vasily-kirichenko

Description

@vasily-kirichenko

https://github.com/MangelMaxime/Fulma/blob/1cbbc35e046007029e4b382d502cd9b301443a69/src/Fulma/Elements/Form/Textarea.fs#L144-L151

if Option.isSome opts.Id then yield Props.Id opts.Id.Value :> IHTMLProp
if Option.isSome opts.Value then yield Props.Value opts.Value.Value :> IHTMLProp
if Option.isSome opts.DefaultValue then yield Props.DefaultValue opts.DefaultValue.Value :> IHTMLProp
if Option.isSome opts.ValueOrDefault then
    yield Props.Ref <| (fun e -> if e |> isNull |> not && !!e?value <> !!opts.ValueOrDefault.Value then e?value <- !!opts.ValueOrDefault.Value) :> IHTMLProp
if Option.isSome opts.Placeholder then yield Props.Placeholder opts.Placeholder.Value :> IHTMLProp
if Option.isSome opts.OnChange then yield DOMAttr.OnChange opts.OnChange.Value :> IHTMLProp
if Option.isSome opts.Ref then yield Prop.Ref opts.Ref.Value :> IHTMLProp

I propose we add if let <pattern> then <expression> expression, so the above code would be rewritten as following:

if let (Some id) = opts.Id then yield Props.Id id :> IHTMLProp
if let (Some value) = opts.Value then yield Props.Value value :> IHTMLProp
if let (Some defValue) = opts.DefaultValue then yield Props.DefaultValue defValue :> IHTMLProp
if let (Some value) = opts.ValueOrDefault then
    yield Props.Ref <| (fun e -> if e |> isNull |> not && !!e?value <> !!value then e?value <- !!value) :> IHTMLProp
if let (Some p) = opts.Placeholder then yield Props.Placeholder p :> IHTMLProp
if let (Some onChange) = opts.OnChange then yield DOMAttr.OnChange onChange :> IHTMLProp
if let (Some r) = opts.Ref then yield Prop.Ref r :> IHTMLProp

It's inspired by the same Rust's feature, see https://doc.rust-lang.org/book/second-edition/ch06-03-if-let.html, and the same Swift's feature, see https://medium.com/@abhimuralidharan/if-let-if-var-guard-let-and-defer-statements-in-swift-4f87fe857eb6

The existing way of approaching this problem in F# is (see the first snippet, or match ... with Some x -> ... | None -> (), which is even more verbose, but safer).

Pros and Cons

The advantages of making this adjustment to F# are:

  • Shorter and safer code

The disadvantages of making this adjustment to F# are:

  • Nothing

Extra information

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

Affidavit (please submit!)

Please tick this by placing a cross in the box:

  • This is not a question (e.g. like one you might ask on stackoverflow) and I have searched stackoverflow for discussions of this issue
  • I have searched both open and closed suggestions on this site and believe this is not a duplicate
  • This is not something which has obviously "already been decided" in previous versions of F#. If you're questioning a fundamental design decision that has obviously already been taken (e.g. "Make F# untyped") then please don't submit it.

Please tick all that apply:

  • This is not a breaking change to the F# language design
  • I or my company would be willing to help implement and/or test this

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions