Async Commands with Avalonia FuncUi

Another Avalonia FuncUI post this week! One problem I struggled with initially with Avalonia FuncUI is how to handle async calls. I had some familiarity with the Elmish Cmd.OfAsync module, and wanted to use that if possible (Maxime Mangel has a great post on Cmd and how to use them, if you are curious).

Anyways, using Cmd.OfAsync and its cousin Cmd.OfTask in Avalonia FuncUI is what we will cover in today’s installment!

Without further due, let’s dive in, starting with a very basic example, without anything async to begin with. Our example app will have just a TextBox, where the text of a “Request” can be entered, and a Button, which will send the “Request”, and return a “Response”, a string, which we will display back to our user.

simple app with one input and one button

We’ll start synchronous, and work our way up to asynchronous commands.

More...

Maintainable Avalonia FuncUI screen layouts with DockPanels and Borders

I have been using Avalonia FuncUI quite a bit lately, to develop Windows desktop clients for 2 applications. The UI for these applications is not particularly fancy: select items using listboxes, edit the selected item, and save it, that kind of thing.

As these applications grew, the screens grew in complexity, and I realized that I was struggling a bit when I wanted to re-arrange their layout. The problem was not caused by FuncUI, but rather by how I was using controls, creating layouts that ended up being hard to refactor or re-arrange.

In this post, I will go over what I ended up doing. It’s not particularly earth shattering, but who knows - it might help someone out there avoid some of the pain I went through :)

More...

Micro optimizing F# code with a dash of imperative code

In addition to re-designing my Nelder-Mead solver to improve usability, I have also recently dedicated some time looking into performance improvements. This is usually not my primary concern: I tend to focus first on readability and correctness first, and address performance issues later.

However, in the case of a solver, performance matters. In my specific case, the solver works as a loop, iteratively updating a candidate solution until it is good enough. Anything that can speed up that loop will directly speed up the overall solver, so it is worth making sure the code is as efficient as can be.

One particular code area I worked on is the solver termination rule. The changes I made resulted in a significant speedup (roughly 10x), at the expense of style: the final version does not look like idiomatic F# at all. In this post, I will go over these changes.

More...

Converting an F# pipeline into a C# fluent interface

In my previous post, I went over one of the changes I made to my library, Quipu, to make it more C# friendly. In this installment, I will go over another design change, turning the initial F# version, which used a classic pipeline, into a Fluent Interface.

For reference, here is how the original F# pipeline looks like:

let f (x, y) = pown (x - 1.0) 2 + pown (y - 2.0) 2 + 42.0
let solverResult =
    NelderMead.objective f
    |> NelderMead.withTolerance 0.000_0001
    |> NelderMead.startFrom (Start.around (100.0; 100.0))
    |> NelderMead.minimize

This looks pretty similar to a Fluent Interface. It is not, though: it is a classic F# pipeline, chaining functions using the pipe-forward operator. From the F# side, this feels like a fluent interface, but for a C# consumer, it is more or less unusable.

Can we turn this into an actual C# friendly Fluent Interface? Yes we can, and this is what I will go over in this post.

More...

Making a F# library C# friendly

During December, I have been aggressively redesigning my library, Quipu. I initially wrote Quipu because I needed a Nelder-Mead solver in .NET, and could not find one ready to use. And, because I intended to use it from F#, I wrote Quipu in a style that wasn’t particularly C# friendly.

As I was going through the code base with my chainsaw, I thought it would be an interesting exercise to try and make it pleasant to use from C# as well. This post will go through some of the process.

First, what is Quipu about? Quipu is an implementation of the Nelder-Mead algorithm, and searches for arguments that minimize a function. As an example, suppose you were given the function f(x,y) = (x-1)^2 + (y-2)^2 + 42, and wanted to know what values of x and y give you the lowest possible value for f. With Quipu, now in C#, this is how you would go about it:

#r "nuget: Quipu, 0.5.2"
using Quipu.CSharp;
using System;

Func<Double,Double,Double> f =
    (x, y) => Math.Pow(x - 1.0, 2) + Math.Pow(y - 2.0, 2) + 42.0;

var solverResult =
    NelderMead
        .Objective(f)
        .Minimize();

if (solverResult.HasSolution)
{
    var solution = solverResult.Solution;
    Console.WriteLine($"Solution: {solution.Status}");
    var candidate = solution.Candidate;
    var args = candidate.Arguments;
    var value = candidate.Value;
    Console.WriteLine($"f({args[0]:N3}, {args[1]:N3}) = {value:N3}");
}

This produces the following result, which happens to be correct:

Solution: Optimal
f(1.000, 2.000) = 42.000

I would also like to think that this C# code looks reasonably pleasant, whereas the original version (pre version 0.5.*) definitely was not. Let’s go over some of the changes I made to the original code!

Side note: my C# is pretty rusty at that point, if you have any thoughts or feedback on how to make this better, I am all ears!

More...