The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 1,862 other subscribers

Archive for the ‘C#’ Category

State machines in Delphi and .NET

Posted by jpluimers on 2023/02/15

Forgot to schedule this in 2014, so here it finally is, as the content is still relevant:

A long time ago (almost 10 years) I did some stuff with State Machines in .NET.

Since then the world has changed, and a lot more libraries have become available.

As I mainly use .NET and Delphi and there is a reasonable chance I need to do some more state machine work, here are some links about State Machines in both environments.

Read the rest of this entry »

Posted in .NET, C#, Conference Topics, Conferences, Delphi, Development, Diagram, Event, Java, Java Platform, Software Development, UML | Leave a Comment »

Google Cloud Shell: tools, languages and “safe mode”

Posted by jpluimers on 2023/01/19

After publishing Free Linux cloud shell for Gmail users – shell in the browser that works in all locations I’ve been so far, the Google Cloud Shell got extended quite a bit.

There is now [Wayback/Archive] Safe Mode (which skips initialisation scripts):

If there’s a problem in your .bashrc or .tmux.conf files, Cloud Shell immediately close after connection. To resolve this, open Cloud Shell in safe mode by appending cloudshellsafemode=true to the URL. This restarts your Cloud Shell instance and logs you in as root, allowing you to fix any issues in the files.

To permanently delete all files in your home directory and restore your Cloud Shell home directory to a clean state, you can reset your Cloud Shell VM.

And there is support for way more [Wayback/Archive] tools and languages:

Read the rest of this entry »

Posted in .NET, C#, Cloud, Development, Go (golang), Google, GoogleCloudShell, Infrastructure, Java, Java Platform, JavaScript/ECMAScript, Node.js, Perl, PHP, Power User, Python, Ruby, Scripting, Software Development | Leave a Comment »

Enabling GitHub pages to a HTML or markdown GitHub project is dead easy: Delphi deadlockempire is now hosted on github.io

Posted by jpluimers on 2023/01/10

A while ago I wrote about Setting up a GitHub project so it is served over https as a github.io and a custom subdomain.

Doing the full “host on your custom domain” route was a big tougher than I hoped for, so I totally forgot how easy it is to convert an existing HTML or markdown documentation repository to use GitHub pages without a custom domain.

I needed it for the Delphi version of the DeadLockEmpire (see links below, originally it was an interactive tutorial game focusing on the C# language and .NET runtime), as I am trying to get as much as my stuff published and hosted in a manner that will outlive me (I still have a pretty high chance of the rectum cancer metastases returning).

Enabling GitHub Pages on your repository is almost as easy as hosting a page through raw.githack.com (where I already hosted raw.githack.com/jpluimers/deadlockempire.github.io/feature/Delphi-language-and-Delphi-RTL/index.html as raw.githack.com/jpluimers/deadlockempire.github.io/feature/Delphi-language-and-Delphi-RTL/index.html and rawcdn.githack.com/jpluimers/deadlockempire.github.io/feature/Delphi-language-and-Delphi-RTL/index.html).

This is how easy it was to get it hosted as [Wayback/Archive] jpluimers.github.io/deadlockempire.github.io:

  1. In my [Wayback/Archive] jpluimers/deadlockempire.github.io: The Deadlock Empire: Slay dragons, learn concurrency! repository, go to the Settings tab, then click on Pages:
    DeadLockEmpire Settings tab, Pages configuration None

    DeadLockEmpire Settings tab, Pages configuration None.

    Here you see “None” as value for the branch to be published as GitHub Pages.

  2. Here I have chosen the Branch “feature/Delphi-language-and-Delphi-RTL” to be published, and am about to press “Save” (full screenshot below):
    DeadLockEmpire Pages selecting the correct branch

    DeadLockEmpire Pages selecting the correct branch

  3. After pressing “Save“, the site gets published (it takes about a minute for that to complete) at [Wayback/Archive] jpluimers.github.io/deadlockempire.github.io:
    DeadLockEmpire Pages the correct branch has been saved

    DeadLockEmpire Pages the correct branch has been saved which will automagically publish it.

That was it. No more steps.

Each new commit in the selected branch will auto-publish as well.

Related DeadLockEmpire posts

  1. 2016 – If you thought you could do multi-threading, then play “The Deadlock Empire” games.
  2. 2017 – ThreadBarrier/ThreadBarrier.pas at master · lordcrc/ThreadBarrier
  3. 2020 – Davidlohr Bueso on Twitter: A programmer had a problem. He thought to himself, “I know, I’ll solve it with threads!”. has Now problems. two he
  4. [WayBack] One second code: Do YOU know how much your computer can do in a second? is a quiz version of the [WayBack] Numbers Every Programmer Should Know By Year. [WayBack] About this game revealed…Source: One second code: Do YOU know how much your computer can do in a second? « The Wiert Corner – irregular stream of stuff

Read the rest of this entry »

Posted in .NET, About, C#, Conference Topics, Conferences, Delphi, Development, Event, Personal, Software Development, Web Development | 1 Comment »

Kevlin Henney on Twitter: “#FizzBuzzFriday… ” Python table lookup versus C# functional programming

Posted by jpluimers on 2022/12/27

[Archive.is] Kevlin Henney on Twitter: “#FizzBuzzFriday… “.

Related: [Wayback] Your C# is already functional, but only if you let it | In Absentia:

A few days ago I tweeted a C# code snippet, showing a FizzBuzz implementation using some of the new features in C# 8.0. The tweet “went viral”, as the kids say, with several people admiring the terse

–jeroen

Read the rest of this entry »

Posted in .NET, C#, Development, Functional Programming, Python, Software Development | Leave a Comment »

Some links to possible ASP.NET core hosting of private projects

Posted by jpluimers on 2022/12/06

For my link archive for hosting private projects built using technology based on [Wayback/Archive] ASP.NET documentation | Microsoft Docs:

If you also are using other technologies than ASP.NET, Heroku might be an option:

–jeroen

Read the rest of this entry »

Posted in .NET, ASP.NET, ASP.NET core, C#, Development, Hosting, Power User, Software Development, Web Development | Leave a Comment »

.NET: programmatically cutting and pasting files (as opposed to copy/pasting them)

Posted by jpluimers on 2022/11/17

Some notes for my link archive.

A long time ago, I asked [Wayback/Archive] c# – Console application using Clipboard.GetFileDropList: how to check if that came from a cut or copy operation? – Stack Overflow.

Back then, the use case had disappeared, so I didn’t follow up. But a new use case might appear soon, so here it goes:

–jeroen

Posted in .NET, C#, Development, Software Development, VB.NET | Leave a Comment »

Chocolatey 1.0.0 got released last week (chocolatey/choco · GitHub)

Posted by jpluimers on 2022/03/24

Last week finally there was the stable [Wayback/Archive] Release version 1.0.0 · chocolatey/choco · GitHub.

So I fixed the Wikipedia page

It was a few days after the 11th birthday “Celebration”: [Wayback/Archive] Chocolatey Software Blog | This One Goes To 11! Celebrating 11 Years Of Chocolatey. Not a really festive post, though it does have a really nice overview of 11 years of Chocolatey history and clearly showing the momentum of it has been a few years behind us.

The thing is: hardly anybody noticed the celebration nor the 1.0.0 release. Being at various 0.* versions for like a decade makes people not follow sudden version bumps closely. I only noticed when updating a bunch of testing VMs of which one had a problem, so I inspected the logs and saw the 1.0.0 version.

So these recent tweets did not gain much attention:

Anyway: the release notes indicate a few things scheduled for 2.0.0. Given the sudden 0.12.0 -> 1.0.0 bump, I have no clue far (or near!) in the future that will be.

It is kind of both a saddening and relieved feeling: like for instance Stack Overflow/Stack Exchange (both in the same age cohort as Chocolatey), Chocolatey is just there and mostly works.

–jeroen

Posted in .NET, Batch-Files, C#, Chocolatey, CommandLine, Development, Power User, PowerShell, PowerShell, Scripting, Software Development, Windows | Leave a Comment »

pipe – Windows how to redirect file parameter to stdout? (Windows equivalent of `/dev/stdout`) – Super User

Posted by jpluimers on 2022/02/02

TL;DR:

  • Windows has CON: which is an equivalent for /dev/tty
  • Windows has no equivalent for /dev/stdout (the standard output stream)
  • There is a C# PipeServer.cs proof-of-concept that allows to simulate /dev/stdout through a temporary named pipe
  • Windows pipe names start with \\.\pipe\ for names on the local machine
  • The above for /dev/stdout on Windows also holds for /dev/stdin (the standard input stream)

All via [Wayback] pipe – Windows how to redirect file parameter to stdout? (Windows equivalent of /dev/stdout) – Super User.

Read the rest of this entry »

Posted in .NET, C#, Development, Software Development, Windows Development | Leave a Comment »

When floating point code suddenly becomes orders magnitudes slower (via C++ – Why does changing 0.1f to 0 slow down performance by 10x? – Stack Overflow)

Posted by jpluimers on 2022/01/26

When working with converging algorithms, sometimes floating code can become very slow. That is: orders of magnitude slower than you would expect.

A very interesting answer to [Wayback] c++ – Why does changing 0.1f to 0 slow down performance by 10x? – Stack Overflow.

I’ve only quoted a few bits, read the full question and answer for more background information.

Welcome to the world of denormalized floating-point! They can wreak havoc on performance!!!

Denormal (or subnormal) numbers are kind of a hack to get some extra values very close to zero out of the floating point representation. Operations on denormalized floating-point can be tens to hundreds of times slower than on normalized floating-point. This is because many processors can’t handle them directly and must trap and resolve them using microcode.

If you print out the numbers after 10,000 iterations, you will see that they have converged to different values depending on whether 0 or 0.1 is used.

Basically, the convergence uses some values closer to zero than a normal floating point representation dan store, so a trick is used called “denormal numbers or denormalized numbers (now often called subnormal numbers)” as described in Denormal number – Wikipedia:

In a normal floating-point value, there are no leading zeros in the significand; rather, leading zeros are removed by adjusting the exponent (for example, the number 0.0123 would be written as 1.23 × 10−2). Denormal numbers are numbers where this representation would result in an exponent that is below the smallest representable exponent (the exponent usually having a limited range). Such numbers are represented using leading zeros in the significand.

Since a denormal number is a boundary case, many processors do not optimise for this.

–jeroen

Posted in .NET, Algorithms, ARM, Assembly Language, C, C#, C++, Delphi, Development, Software Development, x64, x86 | Leave a Comment »

Delphi: workaround doing math with generic types preventing “E2015 Operator not applicable to this operand type” with TValue (as there is no way to constraint the generic type to be floating point or ordinal)

Posted by jpluimers on 2021/12/14

A while ago on Facebook (it’s a private group, so you cannot see the posts unless you both have a Facebook account and are member of the group), [Archive.is] Niels Tjørnhøj-Thomsen (coming from a C++ templates background) asked why the below method would throw a E2015 Operator not applicable to this operand type in the complex expression:

function TAxis<t>.Calc(const AScalar: T): single;
begin
  Result := fStart + ( ( ( AScalar - fMin ) / fRange ) * fExtent );
end;

The type itself was very simple:

TAxis<T> = record
  fMin, fMax, fRange: T;
  fStart, fEnd, fExtent: single;
  function Calc( const AScalar: T ): single;
end;

He used these small example specialisations that put me on the wrong foot, as the order was TDateTime followed by single:

var
  rXAxis: TAxis<TDateTime>;
  rYAxis: TAxis<single>;

So at first I thought this might be caused by TDateTime to be defined in the System unit as a typed type:

type
  TDateTime = type Double;

It wasn’t.

Splitting the code in 4 lines with assignments of single expression operations would make the error appear in all expressions.

Casting parts of the expression to simple would not help either.

A small test program [Archive.is] might put you, like me, on the wrong foot because the specialisation is in the same source file as the generic type:

program DelphiMathAndGenerics;

type
  TAxis<T> = record
    fMin, fMax, fRange: T;
    fStart, fEnd, fExtent: single;
    function CalcCasted( const AScalar: T ): single;
    function CalcPlain( const AScalar: T ): single;
  end;

function TAxis<T>.CalcCasted(const AScalar: T): single;
var
  Offset: single;
  NormalisedOffset: single;
  ScaledOffset: single;
begin
  // First 2 lines give the same error: E2089 Invalid typecast
  Offset := single(AScalar) - fMin;
  NormalisedOffset := Offset / single(fRange);
  ScaledOffset := NormalisedOffset * fExtent;
  Result := fStart + ScaledOffset;
end;

function TAxis<T>.CalcPlain(const AScalar: T): single;
var
  Offset: T;
  NormalisedOffset: T;
  ScaledOffset: T;
begin
  // All 4 lines give the same error: E2015 Operator not applicable to this operand type
  Offset := AScalar - fMin;
  NormalisedOffset := Offset / fRange;
  ScaledOffset := NormalisedOffset * fExtent;
  Result := fStart + ScaledOffset;
end;

var
  rXAxis: TAxis<TDateTime>;
  rYAxis: TAxis<single>;

begin
end.

Splitting this in two files [Archive.is], a AxisUnit unit having only the TAxis<T> type, and a main program (even without having the specialisations) shows that even the unit itself would not compile.

This shows a major difference between Delphi (and similar C#) generics and C++ templates:

  • generics are compiled and fully verified at the generic stage
  • templates are pre-processed, then finally verified at specialisation stage

A solution would be that Delphi could constraint the generic type T into something like float or ordinal so the compiler would know that more operators are allowed in the code. But alas, Delphi – like C# – has a very limited number of constraints (C# only would allow a constraint for enumerations in version 7.3): Delphi Constraints in Generics – RAD Studio XE documentation wiki.

This StackOverflow question is very similar, and has the same answer (generics in Delphi work differently than templates in C++): [Source] templates – Arithmetic operations with generic types in Delphi – Stack Overflow

I’m new in Delphi. For a project required by my company, I need to translate some code from our existing C++ classes to Delphi. Some of these classes are templates, such …

Workaround: use the TValue.From<T>() function

There is a workaround though, but it is slow, as you need to convert from the generic T type to the actual (in this case floating point) type you can apply the operators on.

This is possible with the (Delphi 2010 introduced) TValue.From<T>() method which returns a TValue record. That TValue record has instance methods like AsExtended to extract or convert the embedded value as a specific type.

Initially, [Wayback] Delphi 2010 Rtti.TValue documentation had the From method signature wrong, maybe because of many wiki and blog HTML editors kill angle bracket pairs < and > in code blocks:

function From(const Value: T): TValue; static;

Since the [Wayback] Delphi XE System.Rtti.TValue documentation, the From method signature is fixed (see the bold parts):

class function From<T>(const Value: T): TValue; static;

With the [Wayback] Delphi XE2 Rtti.TValue documentation, the unit got renamed from Rtti into System.Rtti and has not changed further.

When using TValue.From<T>(), the AxisUnit becomes this:

unit AxisUnit;

interface

type
  TAxis<T> = record
    fMin, fMax, fRange: T;
    fStart, fEnd, fExtent: single;
    function Calc( const AScalar: T ): single;
  strict private
    function AsSingle(const Value: T): single;
  end;

implementation

uses
  System.Rtti;

function TAxis<T>.AsSingle(const Value: T): single;
begin
  Result := TValue.From<T>(Value).AsExtended
end;

function TAxis<T>.Calc(const AScalar: T): single;
var
  Offset: single;
  NormalisedOffset: single;
  ScaledOffset: single;
begin
  Offset := AsSingle(AScalar) - AsSingle(fMin);
  NormalisedOffset := Offset / AsSingle(fRange);
  ScaledOffset := NormalisedOffset * fExtent;
  Result := fStart + ScaledOffset;
end;

end.

–jeroen

Read the rest of this entry »

Posted in .NET, C#, Conference Topics, Conferences, Delphi, Development, Event, Software Development | Leave a Comment »