Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# nameof operator not a first-class function

I'm using F# 4.7 with <LangVersion>preview</LangVersion> in my project file.

I have a type like this:

type Record = {
  Name : string
  Description : string
  FieldNotInterestedIn: int
}

I'd like to get the names of certain fields in a type-safe way, but not all of them. I know I can get all the field names using reflection.

Here's the most concise code I came up with. Can it be any more concise?

let certainFieldNames =
  let r = Unchecked.defaultof<Record>
  
  [
    nameof r.Name
    nameof r.Description
  ]
like image 790
Brett Rowberry Avatar asked Jul 20 '20 19:07

Brett Rowberry


People also ask

What does ⟨F⟩ mean?

This sound is usually considered to be an allophone of /h/, which is pronounced in different ways depending upon its context; Japanese /h/ is pronounced as [ɸ] before /u/. In Welsh orthography, ⟨f⟩ represents /v/ while ⟨ff⟩ represents /f/. In Slavic languages, ⟨f⟩ is used primarily in words of foreign (Greek, Latin, or Germanic) origin.

What does the letter F mean in math?

In countries such as the United States, the letter "F" is defined as a failure in terms of academic evaluation. Other countries that use this system include Saudi Arabia, Venezuela, and the Netherlands. In the hexadecimal number system, the letter "F" or "f" is used to represent the hexadecimal digit fifteen (equivalent to 15 10 ).

What does F stand for in the Etruscan alphabet?

In the Etruscan alphabet, 'F' probably represented /w/, as in Greek, and the Etruscans formed the digraph 'FH' to represent /f/.

Is the letter F doubled at the end of words?

It is often doubled at the end of words. Exceptionally, it represents the voiced labiodental fricative / v / in the common word "of". F is the twelfth least frequently used letter in the English language (after C, G, Y, P, B, V, K, J, X, Q, and Z ), with a frequency of about 2.23% in words.


1 Answers

The special function nameof is a compile time feature, and returns the static name of the identifier. As such, it cannot be used at runtime, your runtime code will not contain any references to the function, the result is always a compile time constant.

As a consequence of this, you cannot use it with piping, or as a first class function. When you try it, you'll get the error as given.

The code you wrote is about the most concise, since you seem to want to get the name of these identifiers. There's no syntactic way to do this dynamically (other than with reflection, but that's a whole different approach).

The main reason this special function/operator was added was to help with renaming operations in code, or to safely use the name of a parameter in exceptions like ArgumentNullException.

Full details are in the RFC, in particular the section "other considerations", which details your use case: https://github.com/fsharp/fslang-design/blob/master/preview/FS-1003-nameof-operator.md

In the implementation, a long discussion was held with respect to not requiring the use of Unchecked.defaultof, but we couldn't find a good way of doing that without a significant rewrite of the parser. Note that that code doesn't add runtime overhead, it's erased.

like image 196
Abel Avatar answered Oct 06 '22 17:10

Abel