fsharp / fslang-suggestions

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

Preprocessor Directives: #elif missing #1370

Open Thorium opened 5 months ago

Thorium commented 5 months ago

I propose we add #elif to the preprocessor grammar as part of the #if .. #else .. #endif block.

The existing way of approaching this problem in F# is: Nesting another #if under #else.

Pros and Cons

The advantages of making this adjustment to F# are: alignment with C# and simpler syntax.

The disadvantages of making this adjustment to F# are: none (well, it's work to implement).

Motivation

F# seems to have #elif preprocessor directive / pragma missing: https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/compiler-directives#preprocessor-directives

C# has it: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives#conditional-compilation

I know it's not good practice to use lot of these, I'm not trying to do a templating engine, I would just like to do a simple switch like this:

[<Literal>]
let myPath =
#if WIN64
  "/library/x64/runtime.dll"
#elif WIN86
  "/library/x86/runtime.dll"
#elif MAC
  "/library/iOS/runtime-osx.dll"
#else
  "/library/unix/runtime.dll"
#endif

The current workaround:

[<Literal>]
let myPath =
#if WIN64
  "/library/x64/runtime.dll"
#endif 
#if WIN86
  "/library/x86/runtime.dll"
#endif 
#if MAC
  "/library/iOS/runtime-osx.dll"
#endif 
#if !WIN64 && !WIN86 && !MAC
  "/library/unix/runtime.dll"
#endif

Extra information

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

Related suggestions: #273

Affidavit (please submit!)

Please tick these items 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.

Moved from: https://github.com/dotnet/fsharp/issues/17282

abelbraaksma commented 5 months ago

(partial copy of relevant bits of my comment)

I think this is a reasonable suggestion.

It appears to have been suggested in the F# 4 days, but not the whole proposal has made it back then: #273


Note that #if can be nested, so your code example may be easier if turned into this:

let myPath =
#if WIN64
    "/library/x64/runtime.dll"
#else
    #if WIN86
        "/library/x86/runtime.dll"
    #else
        #if MAC
            "/library/iOS/runtime-osx.dll"
        #else
            "/library/unix/runtime.dll"
        #endif
    #endif
#endif

(I mean, it would be easier to read with your suggestion, but at least you won't need the complex boolean expressions)

abelbraaksma commented 5 months ago

(updated the issue to match the issue template, which got lost in moving the issue over, feel free to edit further, @Thorium)