fsharp / fslang-suggestions

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

Allow single backticks #505

Closed vasily-kirichenko closed 8 years ago

vasily-kirichenko commented 8 years ago

Allow single backticks everywhere double backtickes are used

Double backticks introduce too much visual noise, which prevent people to use more self-explaining names.

Pros and Cons

The advantage of making this adjustment to F# is more readable code.

Double backticks:

[<Test>]
let ``should not create XML Doc for module-level let bounds which already have non-empty XML Docs``() =
    Set.contains (XmlDocable(79, 0, ["x"])) output.Value |> assertEqual false
    Set.contains (XmlDocable(82, 0, ["x"])) output.Value |> assertEqual false

[<Test>]
let ``should not create XML Doc for types which already have non-empty XML Docs``() =
    Set.contains (XmlDocable(89, 0, [])) output.Value |> assertEqual false

type Format =
    | ``ARC/ZIP`` = 0
    | ``ARC/CAB`` = 1
    | ``PE/EXE`` = 2
    | ``PE/DLL`` = 3

let fmt = Format.``ARC/ZIP``

let _ =
    match fmt with
    | Format.``ARC/ZIP`` -> ()
    | Format.``ARC/CAB`` -> ()
    | Format.``PE/EXE``  -> ()
    | Format.``PE/DLL``  -> ()

Single backticks:

[<Test>]
let `should not create XML Doc for module-level let bounds which already have non-empty XML Docs`() =
    Set.contains (XmlDocable(79, 0, ["x"])) output.Value |> assertEqual false
    Set.contains (XmlDocable(82, 0, ["x"])) output.Value |> assertEqual false

[<Test>]
let `should not create XML Doc for types which already have non-empty XML Docs`() =
    Set.contains (XmlDocable(89, 0, [])) output.Value |> assertEqual false

type Format =
    | `ARC/ZIP` = 0
    | `ARC/CAB` = 1
    | `PE/EXE` = 2
    | `PE/DLL` = 3

let fmt = Format.`ARC/ZIP`

let _ =
    match fmt with
    | Format.`ARC/ZIP` -> ()
    | Format.`ARC/CAB` -> ()
    | Format.`PE/EXE`  -> ()
    | Format.`PE/DLL`  -> ()

The disadvantage of making this adjustment to F# is that we will have two syntaxes for defining long symbol names. However, it's not that unusual. We have two syntaxes for defining generic types, for example (type ('k, 'v) Map = ... and type Map<'k, 'v> = ...) for "OCaml backward compatibility".

Extra information

Already implemented in https://github.com/Microsoft/visualfsharp/pull/1692

Affidavit (must be submitted)

Please tick this by placing a cross in the box:

Please tick all that apply:

7sharp9 commented 8 years ago

I think single ticks are clearer, Ive always thought of double ticks as extra noise.

theprash commented 8 years ago

This would be a breaking change for any names containing a single backtick.

theprash commented 8 years ago

Actually, I suppose it wouldn't be!

dsyme commented 8 years ago

My initial feedback:

smoothdeveloper commented 8 years ago

Single backticks are used in haskell for using prefix function as an infix operator:

https://wiki.haskell.org/Infix_operator#Using_infix_functions_with_prefix_notation

That could be a place where we would like to use single backtick notation (although it would be awkward for those double-back-tick symbols).

vasily-kirichenko commented 8 years ago

@smoothdeveloper

  1. I strongly doubt we will reach the point in F# evolution when infix function application syntax would be approved.
  2. Scala uses single backticks to achieve exactly the same result as F#’s double backticks.
  3. Yes, double backticks are completely unique thing. Let's think for a minute why.
dsyme commented 8 years ago

Single backticks are used in haskell for using prefix function as an infix operator:

Yes, this is another point of cognitive dissonance for people coming to F#. Uniqueness and distinctiveness has advantages, the use of double backticks was chosen to achieve that result.

I strongly doubt we will reach the point in F# evolution when infix function application syntax would be approved.

I know why you're saying this and it's a fair point.

However even if we never approved this for F#-on-.NET-as-it-exists-today, I can still see the potential for future deployments of variants of F# in situations where single-backticks would be used for something.

For example, if F# were ever used as the scripting language for an LCF theorem prover (e.g. HOL-lite), then it would be very natural for single-backticks to be used to delimit terms and types in the syntax of the object-language. Or that might force the use of single-backticks for infix operators like THEN in HOL-lite.

Similar considerations apply for potential future variants of F# that interoperate closely with a different host environment (e.g. on Javascript), or ones that need to interoperate closely with a language supporting infix identifiers. The single-backtick syntax is a unique syntactic card we can play at some point in the future of F# variations. Playing it just to save a couple of characters doesn't seem worth it.

There's a long history in programming languages where we regret using up syntactic wiggle-room too cheaply (e.g. I regret the way we used up :: and @ and ! and ref so easily, but am glad of the work we did to make sure x.[y] is reusable for different types)