3

I'm using the following code snippet in a WPF / FsXaml application:

let groupSelected(e: SelectionChangedEventArgs) =
    e.AddedItems
    |> Seq.cast<string>
    |> Seq.head
    |> SelectedGroupChanged

let GroupSelected = groupSelected

When I mouse-over groupSelected, Visual Studio shows the following:

val groupSelected: e:SelectionChangedEventArgs -> ClientGroupEvent

It is slightly different for GroupSelected:

val GroupSelected: (SelectionChangedEventArgs -> ClientGroupEvent)

I have noticed this difference before in other contexts and never thought much of it. If I want to invoke either one, the syntax in my code is the same... groupSelected(e) and GroupSelected(e) both compile fine.

However, when I try to use these two from XAML only this works:

{x:Static local:EventConverters.GroupSelected}

This does not work:

{x:Static local:EventConverters.groupSelected}

What is the difference between those two such that XAML Static extension only works with the second? I would have (mistakenly?) thought they were the same thing.

Wallace Kelly
  • 15,565
  • 8
  • 50
  • 71
  • If anyone has a suggestion for a better title, I'd welcome it. – Wallace Kelly Mar 13 '19 at 02:39
  • 1
    With my dangerous quantity of F# half-knowledge I'm surprised that this works at all. Why doesn't that lead to an indefinite recursion (error)? Are you not pointing the `groupSelected` to itself with `|> GroupSelected`? – Markus Deibel Mar 13 '19 at 06:46
  • @MarkusDeibel Unless I am missing something, there must be a second definition of `GroupSelected` _before_ `let groupSelected` (and it has to accept `string` and not `SelectionChangedEventArgs`). To point to itself, it'd have to be `let rec groupSelected(e) ... and GroupSelected = groupSelected`. – Alexey Romanov Mar 13 '19 at 07:38
  • @MarkusDeibel Sorry. My code snippet was not clear. I have a DU named GroupSelected too. But that is unrelated to my question. I have updated the code snippet. – Wallace Kelly Mar 13 '19 at 11:11

1 Answers1

4

This is one of the areas where simple functional ideas are made a bit more complicated by living in the .NET framework world. F# indeed compiles your groupSelected and GroupSelected in two different ways.

The IntelliSense does tell you this. Most of the time, this is not something you need to worry about, and it is quite sensible to see the following two as the same thing (and, as far as F# itself is concerned, they are):

val groupSelected: e:SelectionChangedEventArgs -> ClientGroupEvent
val GroupSelected: (SelectionChangedEventArgs -> ClientGroupEvent)

The key difference is that the two will be compiled diferently. The first one as a method and the second one as a property that returns a function value. Using C# notation:

// groupSelected is compiled as a method:
ClientGroupEvent groupSelected(SelectionChangedEventArgs e);

// GroupSelected is compiled as a property:
FSharpFunc<SelectionChangedEventArgs, ClientGroupEvent> GroupSelected { get; }
Tomas Petricek
  • 240,744
  • 19
  • 378
  • 553