Skip to main content

Posts

Purely Functional Collections vs. Mutable Collections

I've been experimenting with some purely functional collections, also known as persistent collections, and began to wonder precisely how much overhead they incur as compared to the standard framework collections on a VM platform such as .NET. My open source Sasa library has long had a persistent stack type , considered a list in functional languages, and I was considering adding some additional persistent collections. I therefore wanted a better understanding of the various costs involved. I had also wanted to test an interesting design alternative to standard class-based collections. One of the consistent nuisances on widely deployed VM platforms is the widespread presence of null values. C#'s extension methods somewhat mitigate this problem since you can call extension methods on null values and properly handle it, but calling instance methods on a null value throws a NullReferenceException. Therefore, you cannot invoke ToString or Equals without first checking for null. Thi...

Easy File System Path Manipulation in C#

I came across this type-safe module for handling file paths in the Haskell subreddit this week, and thought it looked kind of neat. Handling paths as strings, even with System.IO.Path always bugged me. So I created a close C# equivalent of the Haskell type and added it to the Sasa library , to be available in the upcoming v0.9.3 release: public struct FsPath : IEnumerable<string>, IEnumerable { public FsPath(IEnumerable<string> parts); public FsPath(string path); public static FsPath operator /(FsPath path1, FsPath path2); public static FsPath operator /(FsPath path, IEnumerable<string> parts); public static FsPath operator /(FsPath path, string part); public static FsPath operator /(FsPath path, string[] parts); public static FsPath operator /(IEnumerable<string> parts, FsPath path); public static FsPath operator /(string part, FsPath path); public static FsPath operator /(string[] parts, FsPath path); public static implicit operator FsPath(string ...

Extensible, Statically Typed Pratt Parser in C#

I just completed a statically typed Pratt-style single-state extensible lexer+parser, otherwise known as a top-down operator precedence parser, for the Sasa library . The implementation is available in the Sasa.Parsing dll, under Sasa.Parsing.Pratt . Two simple arithmetic calculators are available in the unit tests . This implementation is novel in two ways: Aside from an alleged implementation in Ada , this is the only statically typed Pratt parser I'm aware of. Pratt parsers typically require a pre-tokenized input before parsing semantic tokens, but I've eliminated this step by using the symbol definitions to drive a longest-match priority-based lexer. Symbols by default match themselves, but you can optionally provide a scanning function used to match arbitrary string patterns. The symbol selected for the current position of the input is the symbol that matches the longest substring. If two symbols match equally, then the symbol with higher precedence is selected. The design...

Abstracting over Type Constructors using Dynamics in C#

I've written quite a few times about my experiments with the CLR type system [ 1 , 2 , 3 ]. After much exploration and reflection, I had devised a pretty good approach to encoding ML-style modules and abstracting over type constructors in C#. A recent question on Stack Overflow made me realize that I never actually explained this technique in plain English. The best encoding of ML modules and type constructor polymorphism requires the use of partly safe casting. An ML signature maps to a C# interface with a generic type parameter called a "brand". The brand names the class that implements the interface, ie. the module implementation. An ML module maps to a C# class. If the module implements a signature, then it implements the corresponding interface and specifies itself as the signature's brand. Since classes and interfaces are first-class values, an ML functor also maps to a class. An ML type component maps to an abstract class that shares the same brand as the modu...

Sasa v0.9.2 Released

The newest Sasa release contains a number of bugfixes and increased compliance with MIME standards, including proper MIME MailMessage subject decoding. Perhaps of wider interest to the .NET community, there are a number of extension methods for thread safe and null-safe event raising ; safe event raising is a major bane of the .NET developer's existence. There are specific overloads for all System.Action delegate types. A general RaiseAny extension method is also provided that isn't very efficient, but which should match the signature of any event in the class libraries. More overloads can be provided for more efficient execution if needed. Here is the complete list of changes from the changelog: = v0.9.2 = * fixed bug where quoted printable encoding failed when = was the last character. * added Pop3Session.Reset method. * compact serializer no longer uses stream positions to track cached objects, so non-indexable streams, like DeflateStream, are now usable. * ISerializi...

SlimTimer Timesheet Processing Utility

I use the very respectable SlimTimer to help me track my hours. Unfortunately, while they display a consistent total across all reports, the entries in each report do not necessarily add up to that total due to the fractional time units and the rounding involved. Unfortunately, the accounting department tends to frown upon inconsistencies like this, no matter the reason. My process thus far has been to simply export a full timesheet with the report settings specifying time units as precisely as possible, and then performing the sum myself on the resulting chart. This got a bit tedious, so I wrote a program to compile the necessary tallies over however many timesheet files I wanted to process. The source and binaries are available for download . Simply drag and drop any number of timesheets generated from SlimTimer, and the utility will generate a new csv file for each timesheet, with an extension "-out.csv". The format of the output csv file is formatted for my invoice struc...