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

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...

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 ...

WPF tips & tricks: Dispatcher thread performance

Not blogged for an age, and I received an email last week which provoked me back to life. It was a job spec for a WPF contract where they want help sorting out the performance of their app especially around grids and tabular data. I thought I'd shared some tips & tricks I've picked up along the way, these aren't probably going to solve any issues you might be having directly, but they might point you in the right direction when trying to find and resolve performance issues with a WPF app. First off, performance is something you shouldn't try and improve without evidence, and this means having evidence proving you've improved the performance - before & after metrics for example. Without this you're basically pissing into the wind, which can be fun from a developer point of view but bad for a project :) So, what do I mean by ' Dispatcher thread performance '? The 'dispatcher thread' or the 'UI thread' is probably the most ...