Saturday, December 6, 2025

Functional programming in JavaScript (1)

This post start a short series where we discuss functional programming. We'll discuss what functional approach is, what functional pipes and monads are.

Functional programming is about functions. In an ideal world, functions are pure means they have no side effects. Also, variables should be immutable which means that once variable value is set, it's never modified. This effectively means simple loops (for, while, do) are replaced with recursion.

Why? Well, often, the code is easier to read and reason about.

Before we dig into more complicated examples, let's start with discussing the difference between imperative and functional code. Suppose we need to map an array through a function.

A naive imperative approach would be:

function map( xs, f ) {
    var ret = [];
    for ( var i=0; i<xs.length; i++ ) {
        ret.push( f(xs[i]) );
    }
    return ret;
}

var a = [1,2,3,4,5];
console.log( map( a, _ => _**2 ) )

There's nothing wrong with the code. Note however, some subtle drawbacks. First, the loop index must be carefully controlled. Also, both the index and the return value accumulator are mutable. Under usual circumstances, this is safe, however, in a complicated, multithread code, mutable variables can be a pain if are used without a care.

A functional version of this will still have two parameters but there should be no loop but a recursion. In JavaScript, we can have an auxiliary function hidden inside the original one.

Also, we can show few possible approaches.

Let's start with a common technique, the Accumulator Passing Style. This approach is often the easiest one to understand by imperative programmers. It consists in passing an extra parameter between recursive calls, the parameter that accumulates the return value between recursive calls. In our map function, we start with empty array and then we add a new mapped value in each recursive call:

function map( xs, f ) {
    return (function rec(i, acc) {
        if ( i<xs.length ) {
            return rec(i+1, acc.concat(f(xs[i])));    
        } else {
            return acc;
        }
    })(0, []);
}

Easy. The index is still there, the accumulator is the extra parameter, the recursion seems rather straightforward.

Next approach demonstrates a common technique in which there's no explicit accumulator. Instead, the return value of the inner function is used to accumulate the return value of the outer function:

function map( xs, f ) {
    return (function rec(i) {
        if ( i<xs.length ) {
            return [f(xs[i])].concat( rec(i+1) );    
        } else {
            return [];
        }
    })(0);
}

Please take time to carefully study the difference. Debug if you need.

Next approach is a step forward into the functional world. Instead of passing the index in recursive calls (starting from 0), we will pass the array as a list and in each iteration we'll split the array (the list) into the head and the tail. JavaScript's array mimicks a list, the head (the first element) is just a[0] and the tail is just a.slice(1):

function map( xs, f ) {
    return (function rec(ys) {
        if ( ys.length >= 1 ) {
            return [f(ys[0])].concat( rec(ys.slice(1)) );    
        } else {
            return [];
        }
    })(xs);
}

We are almost there. The next refactoring splits the array (the list) into the head and tail in an explicit way, using the possibility to destructurize function parameters. Note also how the spread operator is used to obtain the tail:

function map( xs, f ) {
    return (function rec([head, ...tail]) {
        if ( head ) {
            return [f(head)].concat( rec(tail) );    
        } else {
            return [];
        }
    })(xs);
}

Technically of course, the if ( head ) is wrong because of null coercions, correct it to if ( head !== undefined ) if you need.

It can be further refactored to be slightly less verbose:

const map = ( xs, f ) =>
    (function rec([head, ...tail]) {
        return head 
        ? [f(head)].concat( rec(tail) )
        : []
    })(xs);

Let's stop there. Go back to the very top and compare both functions, the first imperative one and the last functional one. It's still the same language but two different programming styles.

That's why we say such languages are hybrid - if both paradigms, the imperative (or even object-oriented) and functional styles are possible and feel natural in the language.

Monday, November 10, 2025

Time to move away from classic captchas

Starting from January 2026, reCAPTCHA changes their rules. Site keys are migrated to Google Cloud and you have to provide billing information, otherwise captcha basically doesn't work after 10k monthly assessments (technically it works but it always succeeds, meaning you are vulnerable).

Since reCAPTCHA is used on millions of large and small websites, I don't even imagine what it means. Many of these websites are possibly poorly maintained and their owners won't even notice.

We did some research some time ago, looking at possible alternatives. One of the important factors is captcha's compliance with accessibility. Classic captchas (including reCAPTCHA) provide two interfaces, with additional audio-based challenges that are supposed to be accessible. I always believed this is a wrong approach because it basically gives two completely different vectors of a possible misuse - depending on which interface is easier to bypass, an attacker can focus on one or the other.

Also, reCAPTCHA doesn't provide the audio interface in other languages, try Polish and you'll find that it speaks in English.

What we ultimately decided is a custom version of a Proof-Of-Work captcha. Instead of going with existing solutions, we came with our own. This gives us a 100% control on how difficult the computation is at the client side. There were some critical changes in how SHA256 is computed with the subtle.crypto, namely, despite it's async, it no longer goes back to the event loop each time you await it. The UI is not updated but the performance is much higher. You just adapt to this new behavior by raising the difficulty of the client-side work to be done.

Since it's 6 weeks remaining, take your time to inspect all your reCAPTCHA websites, consider either sticking to it or moving away. But do not let yourself wake up in January and find out that things changed without your awareness.

Thursday, October 16, 2025

KB5066835 went terribly wrong

Yesterday, on 15.10.2025, KB5066835 was released for Windows 11. And guess, what, it causes IIS and IIS Express to reject client connections.

This effectively not only stops people who develop using VS + IIS Express but seems that some websites are affected

kb5066835 breaks IIS Express - Developer Community

KB5066835 update causing IIS Service to not work - Microsoft Q&A

Localhost not working anymore after 2025-10 cumulative update Windows 11 - Microsoft Q&A

Localhost applications failing after installing "2025-10 Cumulative Update for Windows 11 Version 24H2 for x64-based Systems (KB5066835) (26100.6899)" - Stack Overflow

windows - Http 2 Protocol error connecting to localhost web sites - Server Fault

Visual Studio - IIS Express - Site won't run / connect / SSL error - Umbraco community forum

Most people suggest uninstalling the KB, however, if your Windows refuses it, try the workaround from the last link above:

  1. In the registry, navigate to: HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\HTTP\Parameters
  2. Under the Parameters folder, right-click in the right-hand pane and select New > DWORD (32-bit) Value.
  3. Name the value EnableHttp2Tls and set its data to 0 (zero).
  4. Repeat the process to add another DWORD (32-bit) Value named EnableHttp2Cleartext and set its data to 0.
  5. Restart the machine.

Edit:Seems that it has been patched in a seemingly unrelated Security Intelligence Update for Microsoft Defender Antivirus - KB2267602 (Version 1.439.210.0).

Thursday, May 15, 2025

OldMusicBox.ePUAP.Client.Core 1.25.5

I am proud to announce that the NET8 port of the OldMusicBox.ePUAP.Client is published at GitHub and Nuget.
Please find more details on the package home page.

Wednesday, March 26, 2025

Tests in the very same console app - compilation error in .NET Core

Having unit tests in the very same console app causes a compilation error:

Program has more than one entry point defined. Compile with /main to specify the type that contains the entry point.

Kind of unexpected, there's definitely a single Main.

There problem seems to be there for all these years, despite being first described back in 2017

The solution is alread provided in the link above, just add

<GenerateProgramFile>false</GenerateProgramFile>

to the *.csproj

A brave little cookie-footer

One of our apps contains a page and the page has a div. The div's class name is cookie-footer.

The div itself has nothing to do with actual cookies, it contains a content that user is supposed to see.

And what? Turns out Brave doesn't show that div. It just adds:

// user agent stylesheet
.cookie-footer {
    display: none !important;
}

What's bizzare, Brave doesn't add this always. We have the app on multiple domains, the user agent style is added on most of domains but not all of them!

Tried other variants:

  .cookie-footer  - blocked
  .cookiefooter   - blocked
  .cookie--footer - works
  .cookiee-footer - works
  .coookie-footer - works

Great times. It's not only the legal regulation that can block your content, it's also your browser heuristic.

Monday, March 17, 2025

A fairy tale of misusing the C# typesystem

Once upon a time in a kingdom far far away someone wrote a code that required two string arguments:

    public class Worker
    {
        public void DoWork( string name, string surname )
        {
            Console.WriteLine( $"{name} {surname}" );
        }
    }

All the people used the code for years without any issues:

    new Worker().DoWork( "john", "doe" );

Then, someone in a hurry did something bad which should never happen. Arguments were swapped in a call:

    new Worker().DoWork( "doe", "john" );

Consequences were severe.

The culprit was tried and expelled from the kingdom. The king called for his best wizards and asked them to do something so that it never ever happens in the future.

One of the wizards suggested that introducing types would make it clear of what real intentions of arguments are:

    public class Name
    {
        public Name( string value )
        {
            this.Value = value;
        }

        public string Value { get; set; }

        public override string ToString()
        {
            return this.Value;
        }
    }

    public class Surname
    {
        public Surname( string value )
        {
            this.Value = value;
        }

        public string Value { get; set; }
        public override string ToString()
        {
            return this.Value;
        }
    }


    public class Worker
    {
        public void DoWork( Name name, Surname surname )
        {
            Console.WriteLine( $"{name} {surname}" );
        }
    }

Initially people complained a bit but then started to get used to the new calling convention:

    new Worker().DoWork( new Name( "john" ), new Surname( "doe" ) );

The problems were gone. Everyone was happy.

Years passed, some wizards were gone, new wizards came to the kingdom. One of new wizards reviewed the code and came up with an idea.

- Why this convention is that awkward, why wrap strings in auxiliary types? - thought the wizard.

And he came up with an idea to add implicit conversion operators:

    public class Name
    {
        public Name( string value )
        {
            this.Value = value;
        }

        public string Value { get; set; }

        public override string ToString()
        {
            return this.Value;
        }

        public static implicit operator Name( string value )
        {
            return new Name( value );
        }
    }

    public class Surname
    {
        public Surname( string value )
        {
            this.Value = value;
        }

        public string Value { get; set; }
        public override string ToString()
        {
            return this.Value;
        }

        public static implicit operator Surname( string value )
        {
            return new Surname( value );
        }
    }
 

The new wizard was very proud of himself. He barely told anyone of his conversion operators so everyone else was still using the well established convention:

   new Worker().DoWork( new Name( "john" ), new Surname( "doe" ) );

But, since the conversion was now implicit, the wizard was able to make his own code shorter:

   new Worker().DoWork( "john", "doe" );

Years passed, new people arrived and then, someone in a hurry did something bad which should never happen. Arguments were swapped in a call:

    new Worker().DoWork( "doe", "john" );

Consequences were severe.

Was the culprit tried and expelled from the kingdom, same as last time?

Not really, the Wizard Council blamed the new wizard, the one who introduced both implicit conversion operators.

He was tried and expelled from the kingdom. His changes were reverted forever and everyone lived happily ever after.


This is based on a (almost) true story.