Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify usage of resx files by generating the source code similar to c# but with f# semantics #802

abelbraaksma opened this issue Oct 28, 2019 · 1 comment


Copy link

@abelbraaksma abelbraaksma commented Oct 28, 2019

Create a resx code file generator

I propose we create a code file generator similar to ResXFileCodeGenerator used by C# projects, but that creates a Designer.fs file. And giving the nature of F# to have magic strings, I suggest we return properties that behave similar to sprintf, i.e. that have signature Printformat<'T> -> 'T.

An alternative is to use a resx type provider, but that doesn't have the benefit of recognizing printf-style format strings.


<data name="InputError" xml:space="preserve">
  <value>Wrong input '%s', expected maximum %i characters.</value>

This would translate to:

/// Returns a localized string similar to "Wrong input '%s', expected maximum %i characters."
let InputError = sprintf """Wrong input '%s', expected maximum %i characters."""

Which could be called something like this:

let maxChars = 20
let inputStr = Console.ReadLine()
if inputStr.Length > maxChars then
    InputError inputStr maxChars

Some conderations:

  • The proposal as-is is tied with the resx file, that is, changes in the resource file only have effect if the generated code is also recompiled. This is slightly different with C#, where the code creates ResourceManager.GetString(...) calls. We could (and perhaps should) do the same, but that means that creating the printf-style functions becomes trickier
  • let-bound functions in a module may not be the best way to go as that may lead to a hit on the JIT compiler the moment you access one of those functions, and the infamous call on StartupCode$.XXX cctors. With large resources that can be significant. There are several ways to ease this pain, if it is indeed significant
  • Since as written, the literal texts become a designer.fs file, the need for embedding the resource itself may be lessened.
  • We could extend this to allow methods for non-string resources as well

The existing way of approaching this problem in F# is to use a C# project to do the heavy lifting.

Pros and Cons

The advantages of making this adjustment to F# are:

  • Simpler project management
  • Clear separation of resources and code (existing code in F# tends to have many inline strings in printf-like functions which should better go in resources)
  • Resources become part of the project where they are supposed to be part of
  • Type safety for usages of resource strings that take parameters like %s or %i
  • Intrinsic support of format strings right out of the box
  • Simpler transition from C# to F# for new programmers

The disadvantages of making this adjustment to F# are

  • Existing resource files will not translate properly if they have {0} in the strings (they would not be recognized)
  • Added complexity in the project system
  • Introduction of auto-generated files (currently we don't have that out of the box)

Extra information

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

Questions and suggestions of this nature have existed before, but I think this version is simple enough to be picked up (I hope ;).

On SO this has been asked before and caused confusion:

And on Github:


  • 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

This comment has been minimized.

Copy link

@dsyme dsyme commented Oct 28, 2019

I'll leave this open but feels like a tooling suggestion?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
2 participants
You can’t perform that action at this time.