12

I just ran across http://frankniemeyer.blogspot.com/2010/04/minimalistic-native-64-bit-array.html Which contains the line

(# "sizeof !0" type('T) : nativeint #)

I believe the technical phrase is "what the heck?" I have never in my (~8 months) of F# programming run across something even resembling that...

FSI tells me something about deprecated constructs, used only for F# libs...

And google with (# does uh...well, not much

Any direction in this?

Snark
  • 1,664
  • 14
  • 27

3 Answers3

8

This is the notation for inline IL emission. It used to be a more prominent feature during F#'s earlier years, but has been deprecated. A gentleman named Brian from the F# team has indicated that it is currently used mainly to bootstrap the F# compiler, and that the team had intended to mark this construct as an error, not merely a warning.

See his post here for the full story.

Ben
  • 6,023
  • 1
  • 25
  • 40
4

It's inline IL (intermediate language) code. This construct is used internally by the F# team to implement bits of the F# core library you just can't do any other way. This code will admit a warning saying it shouldn't be used any where other than the F# core libraries, so you probably don't have to worry about it too much as it should never appear in production code.

Robert
  • 6,407
  • 2
  • 34
  • 41
3

Fascinating. But I think F# already gives us the conversion operations (for this particular operation!) you need without resorting to IL.

[<Unverifiable>]
let inline ArrayOffset (itemSize:int64) (length:int64) (start:int64) (idx:int64) = 
    if idx < 0L || idx >= length then raise(IndexOutOfRangeException())
    NativePtr.ofNativeInt(nativeint(start + (idx * itemSize)))
Sebastian Good
  • 6,310
  • 2
  • 33
  • 57
  • You are correct, you could do it that way. But that would cost an `IMUL`; I really wanted to exploit the AGUs for the address generation part, that's why I resorted to that ugly inline IL in that blog post. But please, don't do such things in production code. – Frank May 05 '11 at 08:33
  • I'm not an MSIL-slinger, as you might guess. There's surely still a multiplication involved. What does IMUL do? – Sebastian Good May 05 '11 at 22:23
  • You have to look at the generated machine code to see what's going on. In your case, the JITter will have to emit at least one additional integer shift instruction (or multiplication) to scale the address accordingly for non-byte arrays. When you use the `sizeof` IL instruction, the address computation is performed entierly in the address generation units of the CPU and doesn't block the integer pipeline (single `mov` instruction). – Frank May 06 '11 at 16:49