News for hackers. Stuff that matters.
Re:Why you should learn F# by cgrealy on Tuesday December 18, 2018 @03:22PM (#18710185)
While I really like the concept of functional programming and F# is definitely on my list of practical useful languages to learn, this article is clearly written by someone who doesn't know C# very well.

Take the "To hell with interfaces" example.

  public interface ISortAlgorithm
  {
    List<int> Sort(List<int> values);
  }

  public class QuickSort : ISortAlgorithm
  {
    public List<int> Sort(List<int> values)
    {
        // Do QuickSort
        return values;
    }
  }

  public class MergeSort : ISortAlgorithm
  {
    public List<int> Sort(List<int> values)
    {
        // Do MergeSort
        return values;
    }
  }

  public void DoSomething(ISortAlgorithm sortAlgorithm, 
  List<int> values)
  {
    var sorted = sortAlgorithm.Sort(values);
  }

  public void Main()
  {
    var values = new List<int> { 9, 1, 5, 7 };
    DoSomething(new QuickSort(), values);
  }
No, no, no, no, nope.

  public static class MergeSort
  {
    public static List<int> Sort(List<int> values)
    {
        // Do MergeSort
        return values;
    }
  }

  public void DoSomething(Func<List<int>, List<int>> 
  sortAlgorithm, List<int> values)
  {
    var sorted = sortAlgorithm(values);
  }

  public void Main()
  {
    var values = new List<int> { 9, 1, 5, 7 };
    DoSomething(QuickSort.Sort, values);
  }
No interface necessary.

Or immutability:

  "public struct Customer
  {
    public string Name { get; }
    public string Address { get; }

    public Customer(string name, string address)
    {
        Name = name;
        Address = address;
    }
  }
So far so good, but unless someone knows C# very well one could have easily gotten this wrong."

Really?? This is beginner stuff.

I 100% agree that null sucks, functions should not need to be in classes and immutability is great, but this kind of strawman doesn't help his point.

Re:Why you should learn F# by algorithmsRcool on Tuesday December 18, 2018 @04:02PM (#18710535)
You are right about the first example (although the F# version looks nicer =D)

But that struct example is less than great.

Just last night I had a readonly C# struct like that, that I used as a dictionary key and wondered why my perf tests took a nose dive when the Dictionary hit a few dozen entries.

My boneheaded mistake was i forgot to override GetHashCode and Object.Equals. Great my perf was looking decent, but even then I was allocating 32 bytes of memory on every lookup.

I forgot I needed to also implement IEquatable<> to prevent boxing on calls to Object.Equals.

My little 2 item struct is 3 lines of definition and 7 lines of boiler plate to get it right. and my GetHashCode impl is suboptimal.

F# records do all of that for you. every time. automatically.

Re:Why you should learn F# by cgrealy on Tuesday December 18, 2018 @04:25PM (#18710724)
I 100% agree that F# does this better.

but saying "unless someone knows C# very well one could have easily gotten this wrong" is disingenuous at best.

Re:Why you should learn F# by algorithmsRcool on Tuesday December 18, 2018 @04:32PM (#18710789)
Dustin is definitely giving a hard sell here I conceed
Re:Why you should learn F# by sparkie on Tuesday December 18, 2018 @05:26PM (#18711182)
I primarily use F# over C#, and I would prefer the interface version over the functions in many cases. An interface makes it a bit more explicit and self-explanatory what is expected to be passed. A Func<List<int>, List<int>> is not very meaningful and potentially ambiguous. Obviously, anywhere you expect more than one function, an interface is more desirable because it avoid the need to pass around multiple objects.

One thing that makes it a bit nicer in F# than in C# is that you can define object expressions wherever an interface is expected, so there's no need to declare a new type in the static scope somewhere (similar is possible in Java).

    DoSomething { new ISortAlgorithm with
                     member this.Sort values = ... }
                values
In terms of how they work, there's not really much difference. If something expects a function and you need to capture some local variable within that function, the framework will create a new type for that closure anyway.
Re:Why you should learn F# by mobiliakas1 on Tuesday December 18, 2018 @06:05PM (#18711446)
You can use delegates in C# for that.

    delegate List<int> SortAlgorithm(List<int> values);

    List<int> QuickSort(List<int> values) => 
        values; // Do QuickSort

    List<int> MergeSort(List<int> values) =>
        values; // Do QuickSort

    void DoSomething(SortAlgorithm sort, List<int> values)
    {
        var sorted = sort(values);
    }

    public void Main()
    {
        var values = new List<int> { 9, 1, 5, 7 };
        DoSomething(QuickSort, values);
    }
Re:Why you should learn F# by sparkie on Tuesday December 18, 2018 @06:36PM (#18711611)
Yes, my point was more that they're pretty much the same thing. A delegate and an interface with a single method are essentially isomorphic in their behaviour.

The delegate obviously breaks down when you have more than one method. For that interfaces work just fine. Even in the case of using a delegate where you capture variables, the C# compiler creates a new type, instantiates it and passes the method in place of the delegate. It's hardly any different to deriving from an interface.

I just tend to use interfaces more out of habit even for single methods. Creating an object expression in F# is pretty much the same outcome as creating a closure in C#.

EDIT: I guess the other problem is that F# functions are not directly compatible with Func<_> and Action<_> types, so when calling a C# function expecting these, you need to wrap the call in an anonymous function. C# interfaces and F# classes are compatible though.

Re:Why you should learn F# by drblast on Tuesday December 18, 2018 @04:07PM (#18710582)
In the first example the named interface would be easier for me to read in a large project than Func<List<int>, List<int>> and with actual code there for implementation the two lines to define the interface would end up being a tiny fraction of the total lines of code. An interface would also provide better documentation opportunities for someone trying to write a mock or new implementation.

The code in the article isn't outlandish or particularly verbose.

Re:Why you should learn F# by dustinmoris on Tuesday December 18, 2018 @04:08PM (#18710592)
Your sort solution limits which algorithms can be used, because you can't pass in a Func which might need an additional parameter anymore.

This is why most C# developers would use an interface for this. With an interface you add extra parameters or dependencies to the constructor of the concrete implementation. If this example wasn't sort algorithms but password hashing algorithms this would be clear.

So yeah.. it proves my point... writing good C# is not that easy, requires a lot of experience and mistakes before someone knows how to write SOLID code in C#. Thanks for helping my point!

Re:Why you should learn F# by cgrealy on Tuesday December 18, 2018 @04:22PM (#18710697)
"Your sort solution limits which algorithms can be used, because you can't pass in a Func which might need an additional parameter anymore" O RLY?

  void List<int> Sort(List<int> input, bool someParam){}

  var values = new List<int> { 9, 1, 5, 7 };
  DoSomething(x => Sort(x, true), values);
  
Thanks for proving my point that you really don't know C#.
Re:Why you should learn F# by algorithmsRcool on Tuesday December 18, 2018 @04:14PM (#18710629)
Just to be clear, you are arguing the superiority of partial application/currying here right?

Because your F# example is the same except it's trading Func<List<int>, List<int> for (int list -> int list)

Re:Why you should learn F# by AdeptusAquinas on Tuesday December 18, 2018 @04:32PM (#18710786)
Technically its passing 'a list -> 'a list, and only becoming an int array because thats the final input value. The fsharp functions are closer to the C# functions Func<List<IComparable>, List<IComparable>>
Re:Why you should learn F# by algorithmsRcool on Tuesday December 18, 2018 @04:38PM (#18710823)
Or to be even more pedantic it's

Func<T[], T[]> where T : IComparable<T>

But maybe all of that is just stronger arguments for F#'s inferred typing...

Re:Why you should learn F# by AdeptusAquinas on Tuesday December 18, 2018 @04:42PM (#18710853)
Or to be even mooooooore pedantic the fsharp functions would probably be written to be seq<'a> -> seq<'a>, so that would be Func<IEnumerable<T>, IEnumerable<T>> where T : IComparable<T> :)
Re:Why you should learn F# by dustinmoris on Tuesday December 18, 2018 @04:17PM (#18710661)
I think I just tried to say that I didn't specifically intend to write very verbose C# to make a point. I tried to write good real world production C# and then compare it to how I have seen people do DI in real world F#, which is partial application in this case. There is other ways of doing it too, but this is the most common pattern I've seen.
Re:Why you should learn F# by keithnz on Tuesday December 18, 2018 @03:29PM (#18710247)
I agree, it feels like the author is going out of their way to write really really verbose C#