fslang-suggestions icon indicating copy to clipboard operation
fslang-suggestions copied to clipboard

Preprocessor Directives: #elif missing

Open Thorium opened this issue 1 year ago • 2 comments

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:

  • [x] This is not a question (e.g. like one you might ask on StackOverflow) and I have searched StackOverflow for discussions of this issue
  • [x] This is a language change and not purely a tooling change (e.g. compiler bug, editor support, warning/error messages, new warning, non-breaking optimisation) belonging to the compiler and tooling repository
  • [x] 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
  • [x] I have searched both open and closed suggestions on this site and believe this is not a duplicate (#273 is similar, but not a duplicate)

Please tick all that apply:

  • [x] 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

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

Thorium avatar Jun 06 '24 11:06 Thorium

(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 avatar Jun 06 '24 11:06 abelbraaksma

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

abelbraaksma avatar Jun 06 '24 11:06 abelbraaksma

I am marking this as approved in principle for preprocessor regularity with C#. The detailed proposal should enumerate potential impact on commonly used F# tooling, e.g. on Fantomas.

(breaking existing tooling is a disadvantage and it is good to be aware of it)

T-Gro avatar Jan 20 '25 15:01 T-Gro