Skip to main content

Simple F# REPL in WPF - part 1

I'm currently working on a C# WPF app which makes use of F# as a modelling language to dynamically create data points from static data in the system. The user enters the F# in the UI via a code editor window, it is then validated & compiled by back-end services for use in reporting & charting views. This all works well but the feedback loop is rather long - instead of being seconds it can take a couple of minutes! What would be nice is a REPL window in the UI, which would allow the user to test the F# code snippet they've just created without having to communicate with the back-end services.

What follows is the first in a set of posts (not sure how many there will be) in the creating of a simple F# REPL UI for use in an WPF app - the end goal is to be able to include a WPF user control in a XAML data template.

The F# interactive window in Visual Studio is done using the fsi.exe executable, this functionality is what I want to achieve in any WPF app - the ability for the user to enter some F# code and execute and get the results displayed immediately.

The F# interactive (fsi.exe) executable provide in visual studio is own & copyrighted by Mircosoft so using this is out of the question. Fortunately F# has been open sourced and is available here - I'll be using the latest version of the F# code base (v3.0).

Shown below is the F# interactive window from visual studio, and as you can I see I've enter a simple F# expression which has been executed  - let answer = 42.00;;
Menu: View -> Other Windows -> F# Interactive.

My goal for this post is to use the F# interactive executable behind the following interface - this will then allow me to easily host and use the F# interactive executable in any .net app in the future - for this post the host will be a console application:
I'm using Reactive Extensions to expose the output from the F# interactive executable to the host app. Hopefully the interface is self explanatory - but if not, the idea is you will start the F# REPL engine and then 'Execute' F# scripts, and you observe any output via the Rx stream exposed as the 'Output' property.

Just like in visual studio I'll be using the F# interactive as an out of process executable and manipulating the standard input & output streams to communicate. This is done using an instance of the Process class and redirecting the input & output streams, shown below is how I'm creating the F# interactive process:
The input stream is used as follows - the stream used to send text input to the process:
Using the output stream is a little more complicated because reading a line of text from the process is a blocking operation in v4.0 of .net  - a simple extension method gets around this issue:
As you can see this is an infinite loop - it will block the calling thread until the cancel is called on the CancellationTokenSource. To avoid this the code is executed asynchronously using the Rx method Observable.Start, below is the complete method block for reading the output stream:
The complete REPL engine is shown below, the F# interactive process is created on the calling thread with the output stream observed on a task pool thread using Rx. There is logic to safely shutdown process & background thread.  The API isn't designed to be thread-safe as I'll be using this in a WPF app and it will only be called from the UI (dispatcher) thread.
Loading ....
The required F# interactive binaries will be added as a 'solution folder' because I couldn't find a relevant nuget package - hopefully I've just not been able to find it:
Testing this is now easy in a simple console test harness, it's a bit strange to use a console app to test another console app which has been wrapped behind an interface but it demonstrates perfectly how easy this will be from WPF:
Loading ....
With output looking very similar to the F# interactive executable, the only difference is the name of the executable in the title bar:
I've pushed the code up onto github, I'll be adding the WPF parts to the code base over the next couple of posts.

Comments

Popular posts from this blog

Showing a message box from a ViewModel in MVVM

I was doing a code review with a client last week for a WPF app using MVVM and they asked ' How can I show a message from the ViewModel? '. What follows is how I would (and have) solved the problem in the past. When I hear the words ' show a message... ' I instantly think you mean show a transient modal message box that requires the user input before continuing ' with something else ' - once the user has interacted with the message box it will disappear. The following solution only applies to this scenario. The first solution is the easiest but is very wrong from a separation perspective. It violates the ideas behind the Model-View-Controller pattern because it places View concerns inside the ViewModel - the ViewModel now knows about the type of the View and specifically it knows how to show a message box window: The second approach addresses this concern by introducing the idea of messaging\events between the ViewModel and the View. In the example below

Implementing a busy indicator using a visual overlay in MVVM

This is a technique we use at work to lock the UI whilst some long running process is happening - preventing the user clicking on stuff whilst it's retrieving or rendering data. Now we could have done this by launching a child dialog window but that feels rather out of date and clumsy, we wanted a more modern pattern similar to the way <div> overlays are done on the web. Imagine we have the following simple WPF app and when 'Click' is pressed a busy waiting overlay is shown for the duration entered into the text box. What I'm interested in here is not the actual UI element of the busy indicator but how I go about getting this to show & hide from when using MVVM. The actual UI elements are the standard Busy Indicator coming from the WPF Toolkit : The XAML behind this window is very simple, the important part is the ViewHost. As you can see the ViewHost uses a ContentPresenter element which is bound to the view model, IMainViewModel, it contains 3 child v

Custom AuthorizationHandler for SignalR Hubs

How to implement IAuthorizationRequirement for SignalR in Asp.Net Core v5.0 Been battling this for a couple of days, and eventually ended up raising an issue on Asp.Net Core gitHub  to find the answer. Wanting to do some custom authorization on a SignalR Hub when the client makes a connection (Hub is created) and when an endpoint (Hub method) is called:  I was assuming I could use the same Policy for both class & method attributes, but it ain't so - not because you can't, because you need the signatures to be different. Method implementation has a resource type of HubInnovationContext: I assumed class implementation would have a resource type of HubConnectionContext - client connects etc... This isn't the case, it's infact of type DefaultHttpContext . For me I don't even need that, it can be removed completely  from the inheritence signature and override implementation. Only other thing to note, and this could be a biggy, is the ordering of the statements in th