Monthly Archives: March 2022

Hey Swift, how many Range types do you need ?

I was messing around with the random number generator code for Int and noticed that the API has two Range types, Range and ClosedRange. Upon further investigation I found that Swift supports even more range types.

So currently the range types are Range, ClosedRange, PartialRangeFrom, PartialRangeUpTo, PartialRangeThrough and CountableRange.

Range

The Range type is “a half-open interval from a lower bound up to, but not including, an upper bound”. Which basically means the ..< syntax, i.e.

let range = 1..<100

In other words range is from (and including) 1 to 100 (but not including 100).

We might write a function to handle this using the following syntax

// usage rangeTest.range(1..<10)
func range(_ r: Range<Int>) -> Void {
  print("\(r.lowerBound), \(r.upperBound)")
}

ClosedRange

The ClosedRange type is “an interval from a lower bound up to, and including, an upper bound”. Which basically means the … syntax, i.e.

let range = 1...100

In other words range is from (and including) 1 to 100 (and including 100).

We might write a function to handle this using the following syntax

// rangeTest.range(1...10)
func range(_ r: ClosedRange<Int>) -> Void {
  print("\(r.lowerBound), \(r.upperBound)")
}

PartialRangeFrom

The PartialRangeFrom type is “a partial interval extending upward from a lower bound”. Which uses … syntax, i.e.

let range = 0...

We might write a function to handle this using the following syntax

// rangeTest.range(..<10)
func range(_ r: PartialRangeUpTo<Int>) -> Void {
  print("\(r.lowerBound)")
}

PartialRangeUpTo

The PartialRangeUpTo type is “a partial half-open interval up to, but not including, an upper bound”. Which uses ..< syntax, i.e.

let range = ..<100

We might write a function to handle this using the following syntax

// rangeTest.range(..<10)
func range(_ r: PartialRangeUpTo<Int>) -> Void {
  print("\(r.upperBound)")
}

PartialRangeThrough

The PartialRangeThrough type is “a partial interval up to, and including, an upper bound”. Which uses the … syntax, i.e.

let range = ...100

We might write a function to handle this using the following syntax

// rangeTest.range(...10)
func range(_ r: PartialRangeThrough<Int>) -> Void {
  print("\(r.upperBound)")
}

CountableRange

The CountableRange is just a type alias around a Range

Visual Code with vscontainers

Note: It appears in Visual Studio Code 1.73.1 that the process for how to open a container has changed. I’ve added the changes to the post

Visual Code supports vscontainers. Basically a way of running Visual Code, connecting to a docker image and working within that container.

So for example we could run up a Go container with all the Go tooling within it, use Visual Code’s terminal to interact directly with the container and it also support volumes, so allows us to store data directly on our host machine.

If you’re using Windows you’ll need the Docker Desktop and WSL2 installed.

All we need to do is…

Let’s say we wanted to work with a dotnet container. Create a folder to act as your code folder and then create a .vscontainer .devcontainer folder and within that a vscontainer.json devcontainer.json file. Add the following

{
  "image": "mcr.microsoft.com/vscode/devcontainers/dotnet",
  "forwardPorts": [3000]
}

Now use the View | Command Palette (or Ctrl+Shift+P) and run the command >Remote-Containers: Reopen in Container Dev Containers: Reopen in Container. This will restart VS Code and when it’s finished downloading the container image will be ready for you to start interacting with – if you haven’t already got the terminal window open then try opening one. In my case I have a bash terminal. You should now be within the container so just try and run the dotnet CLI command and you should see it’s help/commands.

Obviously if your system already has dotnet installed that probably won’t surprise you or interest you that much, but there’s a bunch of alternative containers, for example, how about a TypeScript Node container

{
  "image": "mcr.microsoft.com/vscode/devcontainers/typescript-node:0-12",
  "extensions": ["dbaeumer.vscode-eslint"],
  "forwardPorts": [3000]
}

To see a list of Microsoft defined containers, take a look at microsoft-vscode-devcontainers.

Here’s another one to try – so I have Swift set up on my Linux server but not on my Windows Box, so using the following will give me a Swift environment

{
  "image": "swift",
  "forwardPorts": [3000]
}

Now from the terminal (as already stated) you’re within the container but you’ll want to store your code on the host machine – well magically works out of the box (so to speak) and I am able to create a folder in the terminal and see it in the host folder I created with .vscontainer within it.

References

Developing inside a Container

.NET HttpClient – the correct way to use it

For ages I’ve been using the HttpClient in .NET without any issues, but usually I have a single endpoint and a singleton (or equivalent) of a class that uses the HttpClient. A while back I needed to call multiple different endpoints using the HttpClient and so I happily wrapped an instantiation of an HttpClient in a using statement, I mean after all it has an IDisposable interface so that makes sense right?

Well NO this is not the case. So don’t do this!

// Don't do this
using(var httpClient = new HttpClient())
{
   // do something with httpClient
}

This post stems from a work colleague pointing me to the post YOU’RE USING HTTPCLIENT WRONG AND IT IS DESTABILIZING YOUR SOFTWARE.

What does the documentation say?

If you take a look at the HttpClient Class documentation states

HttpClient is intended to be instantiated once and re-used throughout the life of an application. Instantiating an HttpClient class for every request will exhaust the number of sockets available under heavy loads. This will result in SocketException errors.

If we take a look at some C# templates in Visual Studio, for example the ASP.NET core Blazor application template, it will give you a scoped instance of the HttpClient, for example

builder.Services.AddScoped(sp => 
  new HttpClient 
    { 
       BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) 
    }
);

So how are we supposed to use a single instance of HttpClient

Let’s now assume that we create an HttpClient per application. Then how do we call multiple service endpoints without having changes affect different endpoint calls and is it threadsafe?

Is the HttpClient thread-safe? Well the answer is both yes and no.

Changing properties on the HttpClient are not threadsafe or at least cannot/should not be modified whilst there are outstanding requests. However methods such as GetAsync, PostAsync, SendAsync etc. are threadsafe which then leads us to how to se set-up different calls, i.e. maybe different headers etc. on all our calls. The answer here is to use SendAsync and create an HttpRequestMessage. This allows us to specify many of the properties we’ll need per HTTP call.

References

YOU’RE USING HTTPCLIENT WRONG AND IT IS DESTABILIZING YOUR SOFTWARE
HTTPCLIENT CREATION AND DISPOSAL INTERNALS: SHOULD I DISPOSE OF HTTPCLIENT?

Nullable reference types in C#

Nullable reference types are now enabled by default on projects created with Visual Studio 2022, so let’s have a quick look at them…

Enabling nullable reference type checking

By default nullable reference types were disabled prior to Visual Studio 2022, so would need enable them at a project or file level. Enabling in the project means adding the following to the .csproj file

<PropertyGroup>
  <OutputType>Exe</OutputType>
  <TargetFramework>net5.0</TargetFramework>
  <Nullable>enable</Nullable>
</PropertyGroup>

If you prefer to enable at a file level then simply add the following to the top of each file

#nullable enable

Now what?

So once you’ve enabled nullable reference type checking, especially if on a legacy code base, be prepared for warnings such as

  • warning CS8625: Cannot convert null literal to non-nullable reference type.
  • warning CS8604: Possible null reference argument for parameter ‘s’ in ‘void Program.SetName(string s)’.
  • warning CS8602: Dereference of a possibly null reference.

I’m sure there are plenty of other warnings, but you get the idea.

Basically what we’re ask the compiler to do is tell us when we might have the potential to be passing a null into a function etc. and highlight the potential issue with a warning. In other words we now need to mark reference types as nullable so the compiler knows we’re expecting a null and in situations where we’re not using a nullable reference type we’ll be warned.

Let’s see some example code. First off, if you default arguments to null, for example

public void SetName(string name = null)
{
   // do something
}

This will result in the warning >warning CS8625: Cannot convert null literal to non-nullable reference type.. All we need to do is tell the compiler we’re expecting a null, by making the argument nullable, i.e. add the ? to the type just like nullable value types.

public void SetName(string? name = null)
{
   // do something
}

Any usage of the variable name will now expect a null check, so if we compile the following

public void SetName(string? name = null)
{
   Console.WriteLine(name.Length);
}

as you’d imagine, the compiler will issue a warning here, in this case warning CS8602: Dereference of a possibly null reference., so obviously we have the potential of a null reference exception here, so adding a conditional check like this will fix that

static void SetName(string? name = null)
{
   if (name != null)
   {
      Console.WriteLine(name.Length);
   }
}

In some situations you may in fact know a variable/argument is not null – in TypeScript it’s not unusual to find the transpiler getting a little confused in which case we use the null-forgiving operator simply an !, so whilst the SetName method, as it stands ofcourse can be null, what if we remove the optional argument and expect all callers of the SetName method – for example maybe it’s a private method and we know each caller must check for null first anyway, then we use the following

static void SetName(string? name)
{
   Console.WriteLine(name!.Length);
}

We’re basically saying, by using name!. we know the value is not null. This example is a little contrived because we could just change the string? to string and not require the !, but you get the idea.

Property based testing in Java with kqwik

There are a couple (maybe more) libraries for property based testing, I found that jqwik worked well for me.

I’m not going to go too deep into what property based testing is, except to state that for my purposes, property based testing allows me to generate random values to pass into my tests. I can generate multiple “tries” or items of data and even restrict ranges of values.

Specifically I’m using property based testing to generate values for some unit conversion code, the values get converted to a different unit and back – if the resultant value is the same as the input value we can assume that the conversion back and forth works correctly.

Anyway there are plenty of resources to read on the subject, so let’s get stuck into some code.

First off we need the following dependency to our pom.xml (obviously change the version to suit)

<dependency>
  <groupId>net.jqwik</groupId>
  <artifactId>jqwik</artifactId>
  <version>1.6.2</version>
  <scope>test</scope>
</dependency>

Let’s look a an example unit test

@Property(tries = 100)
public void testFromDegreesToGradiansAndBack(@ForAll @DoubleRange(min = -1E12, max = 1E12) double value) {
  final double convertTo = Angle.Degrees.toGradians(value);
  final double convertBack = Angle.Gradians.toDegrees(convertTo);
  assertEquals(value, convertBack, 0.01);
}

The @Property annotation tells the jqik runner to supply data for the method, creating 100 items of data (or tries) and @ForAll is used to assign data to the double value. Finally for this test I wanted to constrain the range of double values to [-1E12, 1E12].

The output (upon success) looks similar to this

timestamp = 2022-01-05T20:00:08.038391600, AngleTests:testFromDegreesToGradiansAndBack = 
                              |--------------------jqwik--------------------
tries = 100                   | # of calls to property
checks = 100                  | # of not rejected calls
generation = RANDOMIZED       | parameters are randomly generated
after-failure = PREVIOUS_SEED | use the previous seed
when-fixed-seed = ALLOW       | fixing the random seed is allowed
edge-cases#mode = MIXIN       | edge cases are mixed in
edge-cases#total = 7          | # of all combined edge cases
edge-cases#tried = 6          | # of edge cases tried in current run
seed = -3195058119397656120   | random seed to reproduce generated values

Errors will cause the test to fail and output the failure for you to review.

Cargo

As part of a little project I’m working on, I’m back playing within Rust.

Whilst we can use rustc to build our code we’re more likely to use the build and package management application cargo. Let’s take a look at the core features of using cargo.

What version are you running?

To find the version of cargo, simply type

cargo --version

Creating a new project

Cargo can be used to create a minimal project which will include the .toml configuration file and the code will be written to a src folder. Cargo expects a specific layout of configuration and source as well as writing the building artifacts to the target folder.

To generate a minimal application run the following (replacing app_name with your application name)

cargo new app_name

We can also use cargo to create a minimal library using the –lib switch

cargo new lib_name --lib

Building our project

To build the project artifacts, run the following from the root of your application/library

cargo build

This command will create the binaries in the target folder. This is (by default) a debug build, to create a release build ass the –release switch i.e.

cargo build --release

Running our project

In the scenarios where we’ve generated an executable, then we can run the application by cd-ing into the target folder and running the .exe or via cargo we use

cargo run

Check your build

In some cases, where you are not really interested in generating an executable (for example) you can run the check command which will simply verify your code is valid – this will likely be faster than generating the executable and is useful where you just want to ensure your code will build

cargo check

Creating Mac icons with GIMP

When developing for iOS, the OS handles the masking of the image to give it a rounded rectangle look, but for the Mac icons this does not currently appear to happen. The icon asset set expects 16×16, 32×32, 64×64, 128×128, 256×256, 512×512 and 1024×1024 square images (they also require 16×16@2 and so on, i.e. 2x the images up to but not including 1024×1024).

If you supply a full sized squared image, as per the stated dimensions, no mask is supplied and hence the icons looks much larger than the standard Mac ones and also lack the style of them (i.e. rounded corners).

This post is basically about creating icons that look more the part using GIMP.

  • Create a 1024×1024 image
  • Add an Alpha Layer
  • Select All of the image and clear it
  • Create a second image around 880×880 in size – you might want it larger or smaller depending on the icon but you’re really aiming to have the actual icon smaller than the full image size.
  • Now we want to round the image, in GIMP select the Select | Rounded Rectangle option and set the Radius to 42% or you might prefer to right mouse click on the image and select Filters | Decor and then Round Corners (the former will not add any drop shadow whereas the second will.
  • You may want to remove the background by inverting the selection then Edit | Clear or simply copy/cut the selected and round image and copy to the larger image we created
  • You may need to align the image using Tools | Transform Tools and Align (or short cut Q)

That’s about it – experiment with the radius % and size of the image as I’m not sure I have them as perfect replicas of the Mac standard icons, but they’re a lot close than a full sized image.

Creating a console app. in Swift (on Linux)(part 2)

In my post Creating a console app. in Swift (on Linux) I demonstrated creating a console app. using Swift. I used top level statement to create the application, but there’s another way.

Note: Those familiar with C# will see how C# now offers both the traditional class based Program as well as top level statement style, well Swift offers similar.

After creating your application using

swift package init --type executable

Create a file in the Sources folder named App.swift or whatever you like except I found that main.swift didn’t seem to work and caused errors such as error: ‘main’ attribute cannot be used in a module that contains top-level code.

Now in your App.swift paste the following

@main
struct App {
    static func main() {
        print("Hello World")
    }
}

Note: The @main attribute is important to mark the type as the main application code.

If you now use the following from the command line, you should see Hello World output.

swift run

Erlang modules and functions

Modules

Modules are (what you might expect) a way to group together functions.

We declare a module with the first line

-module(Name).

This is always the first line of a module and the Name is an atom (an atom being a literal/constant).

Next up in our module, we’ll be exporting functions along with their arity (arity being an integer representing the number of arguments that can be passed to the function). So for example, if we have add with two arguments we would export it like this

-export([add/2]).

We can export multiple functions within the -export for example

-export([add/2, delete/2, multiply/2, divide/2]).

So let’s put those pieces together and we get a math module something like this

-module(math).
-export([add/2, subtract/2, multiply/2, divide/2]).

add(A, B) -> 
    A + B.

subtract(A, B) -> 
    A - B.

multiply(A, B) -> 
    A * B.

divide(A, B) -> 
    A / B.

Functions

So we’ve seen some example of functions, let’s look at the syntax.

Functions take the form Name(Args) -> Body. where each expression in the body ends with a comma, so for example

start() -> 
    S = "Hello World",
    io:fwrite(S).

Publishing Dart packages to pub.dev

Dart packages can be published to pub.dev and it’s a pretty simple process.

  • 1. Sign up to create an account on pub.dev
  • 2. Don’t worry about the Publisher, you can create and upload packages without this

Next up, let’s assume you don’t yet have a package yet – check out Creating packages to learn about the expected project layout of folders/files. We can simply run the following Dart command to create the template for us

dart create -t package-simple mypackage

Obviously change the mypackage name to that of your package.

Before we look into the requirements for publishing, let’s just state that pub.dev (when you publish your package) runs some analysis across your package and assigns you PUB POINTS – for example to follow Dart file conventions you’re expected to supply a valid pubspec.yaml, a valid README.md and a valid CHANGELOG.md.

  • Update the pubspec.yaml description field – ensure it has 60-180 characters
  • The package created by the Dart CLI gives a good starting point for the README.md and CHANGELOG.md – don’t forget to update the CHANGELOG.md to match each version
  • Implement your code in the lib/src folder – files should use lowercase, snakecase, or you’ll lose PUB POINTS
  • Ensure you’re lib .dart file has
    library mypackage;
    

    Replacing mypackage with your package name if you change the package name at any point during development.

  • Add your tests to the test folder
  • Add an example to the example folder
  • Ensure your code has doc comments to your lib .dart file as well as to the lib/src files, i.e.
    /// My Doc Comments
    

Assuming you’ve got everything in place, run

dart format .

to adhere to Dart formatting preferences. You’ll lose PUB POINTS if you publish with format issues.

Ensure your tests all run successfully using

dart test

Run the publish process in dry-run mode using

dart pub publish --dry-run

When ready, run

dart pub publish

You can exclude files from publishing by prefixing the filenames with a ., any directory with the name packages is ignored. Finally, files and directories within .pubignore or .gitignore are also excluded.

If I recall when publishing, you may be asked to log into pub.dev – just follow the publish command’s prompts and if all went well you’ll have the package upload to pub.dev.

Remember, once you’ve published a package it cannot be deleted, but you can mark them as discontinued. So make sure you have your package named as your want it to be (at the very least) before you publish it.

Ensure versions are correct and updated each time you publish, along with CHANGELOG.md updates to show what happened for each new version.

Finally pub.dev will run it’s analyse process and then supply a PUB POINT score out of 130 and will give information on what’s missing or needs attention to get a 130/130 score – for example, my current package needs a couple of files formatting correctly and an example as I didn’t use the package template but wrote mine from scratch.

Lastly, try to get your README.md etc. right before publishing as you’ll have to increment the version of your app just to change the README.md (yes I learned the hard way).