using Programming;

A Blog about some of the intrinsics related to programming and how one can get the best out of various languages.

.NET Gotcha: TimeSpan: Invalid Format String

F# / .NET: Gotcha's

This is another annoying "feature" in .NET. For some reasons, TimeSpan.ToString with a custom format string does all sorts of wonky stuff, particularly it will give you the "Invalid Format String" error on any unescaped character that isn't a valid format specifier.

Basically, take this list: Custom TimeSpan Format Strings and treat it literally.

Want to add a space between days and hours/minutes/seconds? Escape it: d\ hh\:mm\:ss. Yes, even spaces.

.NET Gotcha: A Generic Error Occurred in GDI+

F# / .NET: Gotcha's

This is one of the biggest, most painful errors I've ever seen in my life. There's absolutely no direction this error can take you.

Here's the thing: GDI+ doesn't really report any errors it encounters down the stack properly. They're all "Generic Errors".

So, some things to look for:

  • Is the resource disposed? If you have a Using / using / use, and you try to access the resource outside of that scope, you'll probably get this error.
  • Calling to .Save? There's a whole list of stuff for that. If you get this error when calling .Save on an Image / Bitmap / etc., you might want to check any and all of the following:
    • Does the directory exist? GDI+ won't create it.
    • Do you have permission to the directory / file? GDI+ won't tell you if that's the problem.
    • Did you dispose of the MemoryStream? That'll be a generic error. You'll want to make sure you save before disposal.

There are many, many more, and I'll be updating this list as time permits.

F# Gotcha: Giraffe Task "FS0708"

F# / .NET: Gotcha's

If you are a user of Giraffe with ASP.NET Core and F#, you might have come across the following error:

FS0708: This control construct may only be used if the computation expression builder defines a 'Bind' method

This happens if you try to use a let! expression inside a task computation expression:

task {
    let! x = ...Async()

The problem here is that task as a computation expression doesn't define a "Bind" method, from what I can tell. There is, however, a quick workaround:

open FSharp.Control.Tasks.V2.ContextInsensitive

For some reason, this open fixes it. I assume that it allows the async computation-expression version of the Bind to be used, so that the code above works.

There's been discussion around this, from what I can tell, but it hasn't really resolved this issue, not sure if it's a version thing, or entirely unrelated: Q: remove async await bind from task {}?.

The Giraffe folks do a great job, so I want to make sure you can work around this particular issue if and when you encounter it.

F# / .NET: "Gotcha's"

Recently I've been digging more-and-more into F#, so I want to start putting together a list of things that I occasionally (or regularly) run into that new users of the language (or even those who are substantially experienced) might not have a great time with.

I'll be notating if it's a general .NET "gotcha", or an F#-specific "gotcha."

F#:

.NET:

If you have something you want to see in the list, please let me know either via Twitter or as a comment. I'll try to check back here regularly to keep this list as up-to-date as possible.

Getting started with programming and getting absolutely nowhere (Part 9)

Knowing the terminology is important

Lesson 8: Let's Normalize Our Data!

Recently I was talking with a colleague of mine, and we were discussing certain syntax differences between two of the major .NET languages: C#, and VB.NET. (Sorry, he's not a fan of F# so there's no love for it there.) One of the issues we came across was the following syntax:

VB.NET:

Public Property Items As List(Of String)

C#:

public List<string> Items { get; set; }

In particular, we were concerned with the (Of String) and <string> bits - if you remember back to lesson 4, I talked about the <'a> bit of let flatten<'a> : 'a array array -> 'a array = Array.collect id, which was an F# generic-type parameter, or a placeholder for a type. It means you can call essentially replace 'a with any type (in this case you actually can, because there are no type constraints) and the function should still work. The (Of String) and <string> bits of the examples above are the same principle: each one is a type substituted for a generic type parameter, that is, the "generic type" of List is now a string. In VB.NET this is accomplished by the verbose Of T, in C# and F# it's accomplished by <T>, which hilariously, as my friend Chris points out on Twitter, is pronounced as Of T by pretty much any seasoned developer. (This should make things a little easier to understand: a 'a array is just an array of 'a.)

But this brought up an even larger issue - it's important for people to understand the terminology of the system they work in. I can't stress this enough, and if you remember back to that lesson, I even had the following to say:

The <'a> is an F# generic type-parameter. Feel free to look those up to learn more.

I really hope you looked it up, because it's important to understand what it means. Often times in any field we get into the habit of using field-specific terms, in this case "generic type parameter", but other terms may be things like "monad" (often found in Haskell documentation), "access(ibility) modifier" (public/protected/internal/private, etc.), or even something as simple as a "mouse". (When talking to a computer group, "mouse" often refers to the physical device used to move a cursor on a GUI, but if you are speaking to a verternarian or someone from animal-control, I assure you it's not as clear-cut.)

The Electronics Example

In fact, recently I was looking for advice on a specific motor to use with a PLC, and I mentioned to a person that I needed a "DC brushless motor" - now if you don't know how "DC" or "brushless" apply to "motor", that sentence can be confusing, misleading, or altogether unable to be understood, but in the context it meant "a device that converts direct-current electric energy into rotary motion, without the use of any brushes." Again, not too confusing, but if you don't understand or incorrectly understand the term, it can be very difficult to rectify the situation. (The particular person I was talking to kept telling me "you can use a car starter" - this is problematic because a car starter is usually a brushed DC motor - I specifically needed brushless.)

So, I want to take a moment today to, instead of writing code, go over some of the common (and hopefully some of the less common) terms you might run into in programming. Some of which I'll describe, and some of which I'll tell you the term, but expect you to research it.

Some Terms

The first set of terms is pretty basic, these are usually basic types in a programming language, or can be trivially represented.

  • Method: a section of programming code with an identifier and optionally parameters that may be called by other code, and may or may not return a value;
  • Function: a method that always returns a value;
  • Subroutine: a method that never returns a value, or returns a void-type;
  • Boolean or Bool: a value that has two states: true or false;
  • String: a sequence of characters that represent a section of text;
  • Integer: a whole number (that is, a number with no fractional portions);
  • Single-Precision Floating-point Value, Single or Float: a number with a fractional part, often represented as a 32-bit value (Do note that some languages treat a float as a double, research the language ahead of time to make sure you understand which is the case);
  • Double-Precision Floating-point Value or Double: a number with a fractional part, often represented as a 64-bit value;
  • Char: a single character, often represented as an 8-bit, 16-bit or 32-bit value (Different languages and systems use different endian-ness, bit-sizes and encodings for char, your specific details may vary);
  • Byte: an 8-bit value either signed or unsigned depending on language;
  • Endian-ness: the order in which bits and bytes appear, this may be most-significant value first, or least-significant value first (see big-endian and little-endian);
  • Bit: see Boolean, this is a single value that is represented by either a 0 or 1;
  • Signed/Unsigned: whether a number has the ability to represent values below 0 (signed) or may only represent values above 0 (unsigned);
  • Short or Int16: typically a 16-bit integer, either signed or unsigned;
  • Long or Int64: typically a 64-bit integer, either signed or unsigned;
  • Word: this is not a "word" in the sense of a sentence, but is typically an alias for a "short" or "Int16" - it is two bytes, always (I separated this and the next two from the number types closest to them because they have a literal translation: they are always the specified number of bytes - often times platforms and languages will indicate that a "numeric" type is actually one of these, such as "int" typically being a "DWord");
  • DWord or Double Word: two words (4 bytes);
  • QWord or Quad Word: four words (8 bytes);

Regarding numbers: often times languages provide number types in a pair, such as sbyte and byte for "signed byte" and "unsigned byte", or short and ushort for "signed short" and "unsigned short", respectively. This often creates confusion between languages, and to make matters worse C and C++ don't always use the same bit-length for each data-type. (On some platforms int in C may be 8, 16, or 32 bits.) The terminology I'm using is referring to the .NET types, for the most part, and it also refers in general on a broader level. (An Int16 is the same 16-bits no matter what, and most people in the software development industry understand short is an alias for Int16.)

Some more types and type-modifiers:

  • Class: often refers to a reference-type that is a collection of related fields, properties, methods and events;
  • Struct: often refers to a value-type that is a collection of related fields, properties, methods and events;
  • Reference-Type: a type that is, by default, treated as a reference rather than an actual value, this is similar but not the same as a pointer - the value of the reference type is a memory-address that points to the actual values;
  • Value-Type: a type that is, by default, treated as an actual value, that is, a single continuous grouping of memory that represents a single result (things like "numbers" - one would never expect int value = 0 to be a pointer to a memory location holding an "object" with the value 0 - it's just expected that value is now the literal 0);
  • Interface, Protocol or Contract: usually refers to a collection of properties, methods and events which a class or struct intends to fully implement;
  • List: may either refer to a "linked-list" or a "non-linked list" of values, usually of the same type - the list often has a "count" of the number of items contained, and often methods like "add", "remove" and "contains" to indicate if an element is in the list;
  • Sequence or Enumerable: any sequence of values, usually of the same type, that are in order but may not always be known ahead-of-time - these are often "lazily" processed, in that only the current element of the sequence is known, the next element may or may not actually have been found already - usually a List can be treated like a Sequence, as a List is inherently a sequence of values;
  • Array: a set of values, usually of the same type, that are directly indexable and statically referenced in memory - a string, for example, can be seen as an "array of characters" - these may or may not expose a "count";
  • Access(ibility) Modifier: a keyword that indicates what "access level" a class, interface, enumeration, property, field, event or method allows;
  • Base Class: in the concept of OOP and inheritance, the class that is the next level up the heirarchy;
  • Abstract Class: a class that is not concrete, but may provide some portions of an implementation of - may only be inherited by other classes;

Paradigms and paradigm-related terms:

  • OOP or Object-Oriented Programming: designing programs around the model of data-flow being done through inheritance, and polymorphism (often statement-based);
  • Functional Programming: designing programs around the model of data-flow being done through functions and functional composition, rather than classes or inheritence (often expression-based);
  • Expression: a series of instructions that evaluate to a value (such as 1+1);
  • Statement: typically an "expression" that doesn't return a result (a call to a method, for example, with a void return type);
  • Polymorphism - look this one up on your own, far too long to describe properly here;
  • Instruction: typically refers to a basic operation that may be performed on a lower-level than usual programming;

Some basic algorithms you should research:

  • Binary Search
  • Binary Search Tree
  • Heap Sort
  • Quicksort
  • Insertion Sort

I'll probably be updating this list as time goes on, but at the very least these are some terms you should get mostly acquainted with.


Todays post is (obviously) more about the higher-level aspects of programming, and less about doing something. I should have convered this information previously, but I didn't. This will become a reference document for future ideas as well (anything I explain here I'll not explain in the future), so keep updated on it. As we've progressed quickly, we'll continue to do so. I'm largely out of content for this series, we'll do a few updates to our existing program to make it slightly more effective and easier to follow, but I hope to have a new adventure worked out by Monday.