dotnet

Exploring the generic math interfaces and fixed-point arithmetic in .NET

Oliver Brown
— This upcoming video may not be available to view yet.

In .NET 7 (previewed in .NET 6) a series of new interfaces were introduced to make work with mathematical operations easier.

.NET has had generics almost forever allowing you to write algorithms that work with many different types, but this hasn’t been possible for basic maths until this was introduced.

The main reason this has been done now is for machine learning and AI implementations where the classic computing tradeoff of speed vs. space appears - if you’re dealing with very large arrays of numbers, maybe you want to switch from a 64 bit double to 32 bit float (or even the newly introduced 16 bit half).

The in-progress implementation of my expanded Elo rating system is based on this for that reason.

Fixed-point arithmetic

There is another reason to use the interfaces though - perhaps you want a completely different implementation of the basic mathematical operations. One example would be fixed-point arithmetic instead of floating-point arithmetic.

The biggest reason to do this is because floating-point arithmetic is not, in practice, deterministic.

More about floating-point arithmetic determinism

This is a subtle topic. Any specific IEE 754 floating point operation is deterministic for the same inputs. But those inputs include various settings that might change unexpectedly, and things like reordering of operations will give you different results due to rounding.

And it is even worse in .NET (ironically) because of its portable nature. Your code could be JIT compiled completely out of your control on many different processor architectures.

Here are some more resources about it:

There have been a few implementations of fixed-point arithmetic in .NET:

That last one is fairly recent (it targets .NET 6) and is MIT licensed, so I decided to see if I could modify it to support the generic math interfaces.

GamesWithGravitas.FixMath

The (still in-progress) result is available here in GitHub.

It takes the F32 and F64 types from FixPointCS and implements the following interfaces:

  • INumber
  • IBinaryNumber
  • ISignedNumber
  • IRootFunctions
  • ITrigonometricFunction

Most of the work is forwarding to the existing implementations. Some of the things that I had to actually write code for:

Formatting and parsing

There are a bunch of methods relating to converting to and from strings. My implementation uses double as an intermediate type. I guess these have the chance to not be deterministic but for the things I’d use it for it would not matter.

TryConvertFrom… and TryConvertTo…

These methods are used to convert between these types and others. They come in three versions: Checked, Truncating and Saturating. I have currently implemented all three to do the same thing.

Star Trek episode titles: an interlude

Oliver Brown
— This upcoming video may not be available to view yet.

Existing work

Firstly, after doing this much work, I have discovered someone already has done a similar investigation: How long is a Star Trek title? by Bruce Bennett, so check that out. One thing it does have that I don’t, is charts.

Improving workflow

The analysis so far has been done using a Google Docs spreadsheet. I then manually wrote the Markdown for the blog posts, which involved some tedious and error prone tables.

I was originally not going to include the giant list of every single-word episode title, since creating that table did not look like fun.

But… I also started working a little program to do more sophisticated processing, and realised I could also make the program generate the Markdown for me.

The program is a .NET 7 console application writen in C#, and writing it was probably quicker than the manipulation I had to do with the spreadsheet in the first place. It was definitely quicker than producing the Markdown tables in the first post manually.

The end result is I can generate tables of all sorts of random episode lists with different properties of varying levels of interest with very little effort.

Current time abstraction coming to .NET

Oliver Brown
— This upcoming video may not be available to view yet.

It is often necessary in computer systems to get the current date and time. .NET has had a straightforward way to do that since its inception. What it hasn’t had is a built-in way to customize the behavior, particularly for mocking during automated tests.

Quite why this situation has persisted for so long is a bit of mystery. The importance of automated tests has only risen over time and questions about how to deal with this crop up quite frequently. The general solution is to provide an abstraction that you can inject and mock easily.

The popular date and time library Noda Time includes IClock, and any developers are often directed to use Noda Time for anything making use of anything but the simplest of time-based logic. But it is still odd there is nothing built-in, especially considering there is an existing private implementation in .NET, as well as several in ASP.NET.

Well .NET 8 will finally be getting System.TimeProvider:

namespace System
{
    /// <summary>Provides an abstraction for time. </summary>
    public abstract class TimeProvider
    {
        protected TimeProvider();
        public static TimeProvider System { get; }
        public static TimeProvider FromLocalTimeZone(TimeZoneInfo timeZone);
        public abstract DateTimeOffset UtcNow { get; }
        public DateTimeOffset LocalNow { get; }
        public abstract TimeZoneInfo LocalTimeZone { get; }
        public abstract long GetTimestamp();
        public abstract long TimestampFrequency { get; }
        public TimeSpan GetElapsedTime(long startingTimestamp, long endingTimestamp);
        public abstract ITimer CreateTimer(TimerCallback callback, object? state, TimeSpan dueTime, TimeSpan period);
    }
}

Here is the original GitHub issue and the pull request implementing it.

As well as providing a mockable abstraction to get the current time (including a default implementation providing the system time), it also adds supports to a bunch of other APIs to use a specified instance instead including Task and Timer.

And, best of all, despite my earlier claim that this is a .NET 8 feature, this will also be made available as a package targeting .NET Standard 2.0, so it can be used on .NET Framework and other targets.

Blazor Numbers Game

Oliver Brown
— This upcoming video may not be available to view yet.

Over the weekend I was playing around with Blazor and created a little number game based on part of a popular British TV show.

In the future this may expand in functionality as part of my exploration into Blazor.

You can try the number game full screen.

Blazor custom elements

Oliver Brown
— This upcoming video may not be available to view yet.

There is now a preview package for Blazor that allows creating custom elements.

Custom elements are part of the Web Components standards and are intended to be a way of defining tags that can be consumed in HTML and interoperate with each other.

The docs mostly focus on using them with Angular or React, but that isn’t why they are interesting to me.

The site for Tic-tac-toe Collection includes pages that show some information about specific game mode (for example four-player Tic-tac-toe misère rumble).

That content is rendered as a custom element (in this case <ttt-settings short-code="T_D4_S6x6_W3_T0_P0_M1_O1_F0"></ttt-settings>). Since the site is statically generated with no frontend framework, I wrote the element in vanilla JavaScript. Blazor support for custom elements means I could rewrite that component in C#.

Accessing the UI in Xamarin.iOS

Oliver Brown
— This upcoming video may not be available to view yet.

An interesting discussion happened recently, triggered by a code review of (something like) the following C#:

public class ProductViewController
{
    private UIView _detailsView { get; set; }
    private ProductViewModel _viewModel { get; set; }

    private void Process()
    {
        if (_viewModel.ProcessDetails)
        {
            InvokeOnMainThread(() =>
            {
                if (_detailsView != null)
                {
                    UpdateDetailsView();
                }
            });
        }
    }
}

One of the reviewers suggested moving the second if outside the call to InvokeOnMainThread (and then combining it with the other if).

The theory was that it would more efficient to check if we need to be on the main thread before we do it, instead of doing the check on the main thread and finding out we have nothing to do.

The original author pushed back saying you can’t access _detailsView off the main thread since you would get an exception.

On the surface this sounds reasonable - everyone knows you can only access UIKit objects on the main thread. But it naturally leads to the question: what does “accessing a UIKit object” actually mean?

So I wrote a quick sample that intentionally tries to do lots of UIKit manipulation on background threads in various ways:

The tests

Quick refresher. The View property of a newly constructed UIViewController is not populated until it is first accessed. Some of the tests below refer to accessing this property either before or after it is created. By default properties declared in C# will not be visible to any native iOS code. They can be made visible by adding the [Export] attribute.

  • Create a UIViewController.
  • Create a UIView.
  • Create a UIColor.
  • Check if a view controller’s View property is equal to null.
  • Check if a view controller’s View property is null using pattern matching.
  • Check if a view controller’s IsViewLoaded property is equal to true.
  • Check if a view controller’s View property is equal to null after previously creating View on the main thread.
  • Check if a view controller’s View property is null using pattern matching after previously creating View on the main thread.
  • Check if a view controller’s IsViewLoaded property is equal to true after previously creating View on the main thread.
  • Check if a new UIView property, that is not exported is equal to null.
  • Check if a new UIView property, that is not exported is null using pattern matching.
  • Check if a new UIView property, that is exported is equal to null.
  • Check if a new UIView property, that is exported is null using pattern matching.
  • Check if a view controller’s NavigationController property is equal to null.
  • Check if a view controller’s NavigationController property is null using pattern matching.
  • Set a new UIView property, that is not exported, with a view created on the main thread.
  • Set a new UIView property, that is exported, with a view created on the main thread.

Results

Test Result
Create UIViewController Exception
Create UIView Exception
Create UIColor OK
Check if View is equal to null Exception
Check if View is null pattern Exception
Check if View is loaded Exception
Check if View is equal to null after creating View Exception
Check if View is null pattern after creating View Exception
Check if View is loaded after creating View Exception
Check if non-exported view is equal to null OK
Check if non-exported view is null pattern OK
Check if exported view is equal to null OK
Check if exported view is null pattern OK
Check if NavigationController is equal to null Exception
Check if NavigationController is null pattern Exception
Set non-exported view OK
Set exported view OK

Summary

This is by no means exhaustive, but it seems in general, acessing properties declared natively in iOS will throw an exception whereas accessing properties you have declared yourself will be fine. I had a suspicion that an exported view might behave the same as a native property, but apparently not.

The code for this test is available on GitHub.

The future of Microsoft MAUI (and Xamarin Forms)

Oliver Brown
— This upcoming video may not be available to view yet.
Xamarin
Xamarin

Since Google seems to like my post about the future of Xamarin Forms so much (and I have a slight history of such posts), I’d figure I’d post an update about interesting things happening in the Xamarin Forms repo specifically related to MAUI.

Renaming

The change that actually made me write this post - a large PR with 5000+ changed files that changes the Xamarin Forms name to MAUI.

Not much of a thing for actual functionality, but a significant symbolic milestone.

Handlers and the great big architecture shift

.NET MAUI will completely change the way renderers are handled in Xamarin Forms. There are many advantages of doing it the new way, but the mechanics of how it is done are fairly complex. This video by Javier Suárez covers it well.

Interacting with this video is done so under the Terms of Service of YouTube
View this video directly on YouTube

This is all happening right now in the main-handler branch.

Update

While I was writing this, work officially moved to the dotnet/maui repo and it is accepting pull requests directly.

AppHost and Microsoft.Extensions

Originally an ASP.NET concept, that then migrated its way to Windows client development, this provides a common way to provide dependency injection, logging, and lots of other infrastructure stuff. In isolation, the pattern and implementation is good and will make it easier to override certain things in MAUI (such as handlers). It’s also useful in a wider sense since it will make configuring different styles of .NET apps more similar.

Single project

Over the past couple of years there has been a move towards producing Xamarin libraries (and .NET libraries in general) using a single multi-targeted project. The most significant is probably Xamarin Essentials. This PR adds support for creating applications following the same pattern.

Merging in Xamarin Essentials

There is a lot of functionality in Xamarin Essentials that Xamarin Forms would like to use. Likewise there is some functionality in Forms that is useful when not using Forms. This lead to some overlap in functionality (and occasionally overlap in APIs but not a perfect match in functionality).

There was an attempt to add Essentials as a dependency of Forms but it faced some problems, and there was a “change of plans”.

Now the solution is to have Forms and Essentials in the same repo. I hope Essentials remains available as its own Nuget package (and it looks like that will be the case).

Resizetizer.NT

Resizertizer.NT, like its predecessor Resizetizer, is a package for generating platform specific images in all the right sizes at build time.

Managing image assets across iOS and Android (and using Visual Studio) has always been an unpleasant process. This tool makes it much easier and will be included in MAUI by default.

The future of Xamarin Forms

Oliver Brown
— This upcoming video may not be available to view yet.

Microsoft have just announced the future of Xamarin and Xamarin forms - the .NET Multi-platform App UI (or MAUI for short). As a name, it’s not great. The highlights are as follows:

  • It’s an evolution of Xamarin Forms. It basically is Xamarin Forms, but finally accepting some breaking changes. To be honest, I’m hoping for a lot since there is a lot of weirdness in Xamarin Forms that has been holding it back.
  • Single project, multi-targeted. It took a long time to get to the point where this was possible. From shared projects, to PCL projects, through .NET Standard. This should make things a lot easier.
  • Still based on platform renderers using native controls. This is a mixed bag. Using native controls has long been a selling point of Xamarin (with or without Forms). With the rise of Flutter this has been shown to be less important. Many people have been asking for consistent platform agnostic renderers instead.
  • The end of “Xamarin” as a name. Some time in the .NET 6 timeline (end of 2021) Xamarin.iOS will become .NET for iOS and Xamarin.Android will be .NET for Android. I have mixed feeling about this since this was a fairly succinct way to describe by top skillset.

I also already have my own enhancement issue submitted.

Xamarin Forms frame is the wrong color

Oliver Brown
— This upcoming video may not be available to view yet.
screenshot

screenshot

Xamarin Forms uses a naive conversion from it’s platform independent Color class to iOS’s CGColor, and as a result, Frame controls end up with inconsistent background colors. I’ve added a demo here.

Clarifying my position on ASP.net

Oliver Brown
— This upcoming video may not be available to view yet.

One of my most read (and most commented on) posts was the one claiming “ASP.NET sucks”, which only goes to show being a little offensive goes disappointingly far on the internet. Since it has now been five years since I posted that, I thought a quick follow-up was in order.

I stand by most of what I said my initial post, but with a little specificity. It’s not ASP.net that’s the problem but Webforms. Unfortunately at the time Webforms was all you ever saw. There are alternatives around today (and may have been back then but none were especially high profile and none were by Microsoft). These days of course Webforms are very much out of fashion. Following on from the success of Rails Microsoft realised that Webforms weren’t an idea that could keep up with modern web development. A quick glance at the ASP.net home page today shows four out of five articles talking solely about ASP.net MVC and one article talking about both MVC and Webforms (of course that will vary by day I but I doubt the result will be very different).

So taking into account a minor title change (ASP.net Webforms suck!) I’d say my original point stands.