Live data from Hacker News

.NET Fiddle adds F#

dotnetfiddle.net

51–60 of 72 posts

Re: .NET Fiddle adds F#

#51

Earlier quoted context omitted.

In F#, most pipelined operations are expressed using the pipeline operator all the way. [1; 2; 3; 4] |> List.filter isEven |> List.sum That way you maintain the same operator order as you do in Scala, while maintaining some consistency with currying. In addition, you can add other functions really simply while still maintaining the order. [1; 2; 3; 4] |> List.filter isEven |> List.sum |> printfn "%i"

Interesting, in Scala you do: list filter isEven foreach println Which is, IMO, quite elegant, but then again I'm used to Scala and not yet at all familiar with F# and the reasoning behind the syntax.

  List(1,2,3,4) filter isEven sum println
  error: type mismatch;
   found   : Unit
   required: Numeric[?]
         List(1,2,3,4) filter isEven sum println
                                         ^

Re: .NET Fiddle adds F#

#52

Earlier quoted context omitted.

Isn't there a large difference between supporting interop with code written in other languages and importing all the stuff into the language itself?

Well, if the language was only meant to be an API consumer then eliding OO stuff would make more sense, but they designed it for bi-directional interop. And besides, F# was based on OCaml (as I'm sure you know), which itself was an existence proof that you could successfully bolt OO onto a functional language.

> successfully bolt OO onto a functional language

Yes, I think that's a good description. It's not great, but it somehow works (although the whole F# community tends to tell people to stay away from OOP when not necessary).

Would have been interesting to explore better ways to support OOP so that it doesn't need to be considered a second class citizen, but I guess it's too late for that now.

Re: .NET Fiddle adds F#

#53

Earlier quoted context omitted.

> that approach fits better with traditional functional idioms Just interested, what's the real value here? "Familiarity" alone seems to be a pretty poor reason. > They're really just static methods in the .NET VM and bytecode. Doesn't this mean that either your methods won't be dynamically dispatched or that you would need to rewrite your code if you ever change from e. g. List to Array? Looks like a bad compromise…

One of the big values is currying. Instance methods don't always interact well with partial application and design patterns that rely on it, because with instance methods one of the function's (logical) operands is a special snowflake that isn't curried.

But currying isn't even consistently supported, e. g. when calling C# APIs as far as I remember. Wouldn't it have been better to explore a way which either works for all code or, if that doesn't work out, just embrace instance methods?

The current API situation looks kind of weird. What's the point of having an API (like the collection one) which is meant to be chained together, but needs additional boilerplate (|>) to actually work that way?

Maybe it would have been better to do away with these inconsistencies and make the idiomatic way of writing code the default one, working without any additional effort of flipping stuff around?

Re: .NET Fiddle adds F#

#54

Earlier quoted context omitted.

Isn't there a large difference between supporting interop with code written in other languages and importing all the stuff into the language itself?

There's an enormous difference. And it's a good thing F#'s designers chose the latter option; it's a huge win on the interoperability front. Libraries have a tendency to be write-once-use-often, so exporting object-oriented APIs from F# code is way better than consuming functional APIs from C# code.

I think there is a huge way between allowing developers consume F# code from C# and importing all the ugliness of stuff like static members into the language. I don't think it has to be that way.

What's the value of having a runtime with a language-independent intermediate representation if one just adds half of C#'s complexity into F#?

Re: .NET Fiddle adds F#

#55

Earlier quoted context omitted.

One of the big values is currying. Instance methods don't always interact well with partial application and design patterns that rely on it, because with instance methods one of the function's (logical) operands is a special snowflake that isn't curried.

But currying isn't even consistently supported, e. g. when calling C# APIs as far as I remember. Wouldn't it have been better to explore a way which either works for all code or, if that doesn't work out, just embrace instance methods? The current API situation looks kind of weird. What's the point of having an API (like the collection one) which is meant to be chained together, but needs additional boilerplate (|>)…

> Wouldn't it have been better to explore a way which either works for all code or, if that doesn't work out, just embrace instance methods?

I suppose the answer to that question ultimately depends on one's preferences. I like F#'s way of doing things because I like functional programming and idioms, but I also like being able to play nice with a rich pre-existing ecosystem, and don't want to have to do it through a (probably) leaky abstraction.

When I instead want a primarily object-oriented language with some extra support for functional programming slapped on top, I just use C#.

Re: .NET Fiddle adds F#

#56

Earlier quoted context omitted.

There's an enormous difference. And it's a good thing F#'s designers chose the latter option; it's a huge win on the interoperability front. Libraries have a tendency to be write-once-use-often, so exporting object-oriented APIs from F# code is way better than consuming functional APIs from C# code.

I think there is a huge way between allowing developers consume F# code from C# and importing all the ugliness of stuff like static members into the language. I don't think it has to be that way. What's the value of having a runtime with a language-independent intermediate representation if one just adds half of C#'s complexity into F#?

Q: What's the difference between a static method and a function that belongs to a module?

A: One's object-oriented jargon, the other's functional jargon. They both mean pretty much the same thing.

Re: .NET Fiddle adds F#

#57

Earlier quoted context omitted.

> So the List class mostly sticks to static methods in its public interface because that approach fits better with traditional functional idioms. And also fits perfectly with the C# and VB.NET extension method syntactic sugar, which was used extensively for LINQ. They're really just static methods in the .NET VM and bytecode.

> that approach fits better with traditional functional idioms Just interested, what's the real value here? "Familiarity" alone seems to be a pretty poor reason. > They're really just static methods in the .NET VM and bytecode. Doesn't this mean that either your methods won't be dynamically dispatched or that you would need to rewrite your code if you ever change from e. g. List to Array? Looks like a bad compromise…

> Doesn't this mean that either your methods won't be dynamically dispatched...

The MSIL (.NET bytecode) for calling an extension method and a static method are exactly the same. So yes, it will not be dynamically dispatched. Specifically, it emits a "call" and not a "callvirt" instruction.

However, the compiler will always prefer a class method over an extension method of the same signature. Meaning that extension methods can be specifically implemented by a class and the compiler will emit a "callvirt" instruction for that instance method instead.

> ... or that you would need to rewrite your code if you ever change from e. g. List to Array?

I'm not sure what you mean here. Arrays implement IList, so if you need random access, you would just write a method against IList. If you don't need random access, you should write it against IEnumerable, which all collections implement.

Re: .NET Fiddle adds F#

#58

Earlier quoted context omitted.

> that approach fits better with traditional functional idioms Just interested, what's the real value here? "Familiarity" alone seems to be a pretty poor reason. > They're really just static methods in the .NET VM and bytecode. Doesn't this mean that either your methods won't be dynamically dispatched or that you would need to rewrite your code if you ever change from e. g. List to Array? Looks like a bad compromise…

> Doesn't this mean that either your methods won't be dynamically dispatched... The MSIL (.NET bytecode) for calling an extension method and a static method are exactly the same. So yes, it will not be dynamically dispatched. Specifically, it emits a "call" and not a "callvirt" instruction. However, the compiler will always prefer a class method over an extension method of the same signature. Meaning that extension m…

Perhaps what the parent is saying is that if you implement an extension method to IList, you can't subsequently implement an extension method to Array and expect it to be called on an Array stored in an IList variable? Which is true for exactly the reason you state.

Re: .NET Fiddle adds F#

#59

Earlier quoted context omitted.

Interesting, in Scala you do: list filter isEven foreach println Which is, IMO, quite elegant, but then again I'm used to Scala and not yet at all familiar with F# and the reasoning behind the syntax.

List(1,2,3,4) filter isEven sum println error: type mismatch; found : Unit required: Numeric[?] List(1,2,3,4) filter isEven sum println ^

I didn't write what you wrote ;-)

foreach takes a collection and applies some function (in this case println).

I've actually had a use case for what you're trying do, so created an extension method on Any, which means you can then do, on Any-thing:

(list filter isEven sum).echo

I also hate typing "println". "echo" I can bang out instantly, and can do so on any expression, before or after its definition.

Re: .NET Fiddle adds F#

#60

Earlier quoted context omitted.

Interesting, in Scala you do: list filter isEven foreach println Which is, IMO, quite elegant, but then again I'm used to Scala and not yet at all familiar with F# and the reasoning behind the syntax.

List(1,2,3,4) filter isEven sum println error: type mismatch; found : Unit required: Numeric[?] List(1,2,3,4) filter isEven sum println ^

`sum` does not accept a function as a parameter, the original example had an `foreach` instead of `sum`.

    list filter isEven foreach println
As a side note omitting that many commas and parenthesis is very rare at least based on the Scala projects I've worked on. The above example is equal to the one below:

    list.filter(isEven).foreach(println)
Post reply on HN