Hacker News new | ask | show | jobs
by rtpg 3750 days ago
Is it possible to call F# code easily from C#? Or vice versa?
3 comments

Consuming C# code from F# works fine.

Consuming F# code from C# works pretty well for the most part, although F# specific types are cumbersome to use (records, discriminated unions, computational expressions aka monads). This just means that if you want an F# DLL to be usable from C#, you need to think a little bit about the exposed API (perhaps by adding a C# specific wrapper).

Having said that, IMO the interop between the two is better than the interop between JVM languages like java, scala & clojure (Kotlin is probably different).

Yes, I agree, but you need to be really careful about tail call recursion optimisation when calling f# code from c#. In F# it is always guaranteed, in c# only on 64 bit 4 and above runtime if I remember correctly, so you can't really rely on it for production code.
Unless it's changed, F# doesn't emit "tail." prefixes for tailcall. Nor is it guaranteed. The F# compiler will, in some cases, manually turn your tailcall-OK code into a loop. But it doesn't do it in all cases (nor could it).

The F# compiler used to emit "tail." prefixes in every case that was eligible. But not only does the CLR have lots of restrictions, it was slower to request tailcalls.

Maybe that changed in the last version or two.

Edit: OK I found the email where I had asked fsbugs why tailcalls were no longer generated. But that was in 2009 so I'm more out of date than I remember.

In the release notes[1] for the May 2009 release, there's this section:

Optimizations for Tailcalls

On some implementations of the CLI, normal calls can be more efficient than tailcalls. An optimization is now applied to determine if a function is “closed” in the sense that it never takes any tailcalls outside a finite non-recursive callgraph. If so, the use of tailcalls is suppressed.

1: http://blogs.msdn.com/dsyme/archive/2009/05/20/detailed-rele...

Wouldn't C# interface only with compiled il code and not directly with F# so any tail call optimizations in F# wouldn't depend on what you later do in C# compiler?
Yeah, right, the f# compiled code will be already optimised for the tail call recursion so it can be called safely from the c# code. What I remembered applies only to the c# generated IL.
Have they fixed the intellisense yet? Last time I tried to call c# from f# it compiled but autocompletion in vs didn't work.
Yeah, the intellisense is a lot better than it was in earlier versions.

That said, it doesn't attempt to read your mind, so the intellisense only kicks in when the type you're interacting with is unambiguous. So, for example, you'll need to explicitly state a function parameter's type before intellisense will help you figure out what methods you can call on it.

In general you should follow Demeter's law and not expose types behind value types if you can avoid it.
Regarding this 'law', Wikipedia put it quite nicely, saying quote, it is more suited as a metric for code smell as opposed to a methodology for building loosely coupled systems.
Yes, I have a WebAPI module written in C# that calls into an F# module for some file processing. From the C# project's perspective, the F# assembly is just another assembly with static methods. It was a great use case for me to highlight the benefits of mixed paradigm programming. By making the WebAPI module state based, it made certain operations easier, while the F# module can do the heavy lifting of processing the data.

You can also do a pure WebAPI module in F#.

That's a confusing post. You talk about WebAPI which is all JSON/AJAX, of course you can cross communicate there, the above poster is talking about direct inter-CLR calls (which you can do but have nothing to do with WebAPI).
I'm guessing the poster means an ASP.NET WebAPI controller that relies on an assembly written in F#, not a process making web API calls.
Why does it being WebAPI-exposed interface matter at all then? It is an extremely confusing way of phasing it. It literally doesn't matter, and even reading back if that IS what they meant then it is still a really circular way of wording it.
Most likely they're referring to the C# part being written for Microsoft's "ASP.Net Web API" framework, rather than just being a web API in general.

That framework is designed for C# programmers and most of the resources (tutorials/stackoverflow answers/etc) around it will assume you are writing C#. So it makes some sense to use C# for that part of your application even if most of the underlying business logic is implemented in separate F# libraries.

That's probably why they specified it - to explain why they're using both C# and F#. I can see how it could be confusing, especially if you're not familiar with that rather generically named framework.

It doesn't. That was just an incidental piece of detail.

If it makes it more comfortable to you, replace "WebAPI" with any other technology that interfaces your code with the outside world. Maybe a UI toolkit or something.

> From the C# project's perspective, the F# assembly is just another assembly with static methods.

It sounds like he's calling the F# functions directly.

Yes, the C# WebAPI project receives a file, and then passes it off to an F# module for processing. The WebAPI takes care of authorization, authentication, and some basic checks against the file, whereas the F# library is responsible for data processing.
Yes, very easily. Both are compiled to .NET assemblies and can see types of each other.