Skip to main content

Posts

Showing posts from 2013

Sasa v0.12.0 Released

Just a quick announcement that Sasa v0.12.0 was just released. You can obtain the individual assemblies via Nuget , or the whole set from Sourceforge . The docs are available as a CHM file on sourceforge, or online here . Overview This release includes a few fixes, the most prominent of which are in the HTML parser and the parsing of MIME linked resources. Note that since v0.11.0, some extension methods on MailMessage have been deprecated due to Microsoft's recommended usage guidelines. The headers those extension methods accessed are overwritten whenever a MailMessage is sent via SmtpClient, so it's better not to rely on them. A new feature is the sasametal utility, which is basically a wrapper around sqlmetal that normalizes some of the bizarre property names from sqlmetal into more CLR friendly names. A forthcoming blog post will cover the use of this tool. Other new features include first-class references , and first-class slots . These are currently in the core Sa

First-Class Slots for .NET

Yesterday, I posted about the new extension of IRef<T> to arbitrary reference semantics for the CLR, including referencing inner fields, properties, and array slots. First-class references make it simple to operate on specific mutable data without caring about the underlying type of that data. I just pushed another abstraction that handles a related, but different case: first-class slots . ISlot<T> An object "slot" is a value that designates a mutable location of a specific class of values, not a mutable location of a specific instance like first-class references. Where first-class references hide the underlying object type, slots expose the object type and allow you to mutate the slots of multiple objects at once, as long as they are subtypes of the slot's object type. Here's the declaration of ISlot&ltT>: public interface ISlot<TObj, T> { T Get(TObj obj); T Set(TObj obj, T value); } As you can see, the object we're man

First-Class References for .NET

References in C# are second-class citizens, which is to say, that you cannot pass them around as values. They can appear in function parameter position, but that's it: public static void DoFoo(ref int value) { Action captureRef = () => value = 3; // ERROR: ref can't escape scope } This makes it easy to verify their safety statically, and makes them very efficient, but it somewhat limits their expressiveness. First-class citizens can be passed around as values, and otherwise used in any way that you'd use any other object. The above capture would work, for instance. To make references first-class citizens means constructing an object that exposes get and set operations, and that can reference the internals of any .NET type. IRef<T> Sasa has had the IRef<T> type for quite some time, but its full potential as a first-class reference hasn't been realized. There was only a single implementation, and that was a simple mutable slot as found in ML. I&

Degenerate Implicits in C#

Scala and Haskell both have very useful type-directed concepts for resolving implicit function parameters, called "implicits" and "type classes" respectively. To illustrate the impact of this, consider a generic sorting function like Enumerable.OrderBy . It must define two overloads, one that takes a custom comparer, and one that does not and so should use a default comparison for type TKey: public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer ) public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector ) While it's simple to define the second overload as calling the first with Comparer<TKey>.Default for the custom comparer, in general, for N overridable parameters, you would need to define something like f

Sasa v0.11 Released

A new release of Sasa is now available on Sourceforge and Nuget. This release contains few bugfixes and some minor new convenience features. Changelog MailMessage extension method Reply() now considers the media type of the original body, and if it's not text/plain, then the original body is attached to the reply message as an inline attachment if original e-mail doesn't specify sufficient content-type information, generate it and reset the original e-mail's header new IEnumerable extensions, SingleSelect and FirstSelect, which select a component of the only or first items in a sequence, respectively, that match an optional predicate, even if the item returned is null refactored ToRaw extension to simplify and generalize MIME output more rigourous MIME parsing tests parsing MIME views now properly propagates the transfer encoding and contentId Html parser element tags and content can now be mutated You can also view the full documentation online .

Sasa v0.10 Released

I just uploaded v0.10 of Sasa , my open source class libraries. This release features a few small bugfixes and enhancements to MIME parsing, and some useful new concurrency features. .NET 4.0 binaries are now also provided. Bugixes bugfix: added some runtime fixes due to semantic changes in .NET 4.0 base class libraries bugfix: multipart/alternative MIME messages are now parsed into the containing message's alternate views bugfix: set a MailMessage reply's From property if a source address is available bugfix: ThreadScoped now properly reclaims data across threads bugfix: more efficient and safer Lazy initializer New new: provided builds for .NET 4.0 new: added Atomics.Read and Atomics.Write thread-safe read/write operations that perform atomic reads larger-than-word structs without locks [1] new: added simple load-linked/store-conditional operations, under Atomics.LoadLinked/StoreCondition, and Sasa.Concurrency.LLSC new: added a LockSet object which takes locks in

CLR: The Cost of Dynamic Type Tests

I recently came across Vance Morrison's blog post on the relative costs of dynamic type tests on the CLR, and I was struck by how much my experience differed from the results he received. In past tests, I had concluded that operations and comparisons using System.Type were just as fast as operations on System.RuntimeTypeHandle . This struck me as a little odd at the time, but numbers don't lie. Vance helpfully provided the code he used for his benchmarks, so I decided to see if perhaps I was mistaken. Lo and behold, the numbers I received from running his code matched my past results, ie. RuntimeTypeHandle provided no advantage. This seemed extremely odd, and after digging a little deeper, it turns out that Vance and I are both right. I've been doing most of my development on 64-bit x64 machines, and I suspect Vance was running x86 at the time. It turns out that the x64 runtime for the CLR is woefully underperforming when compared to x86, at least for this type of code

CLR Concurrency: Preventing Torn Reads Without Locks

The CLR's value types are incredibly useful for reducing memory usage of programs, but they have a severe limitation in concurrent scenarios: structs larger than the atomic type on a given machine can suffer from torn reads . Most typical applications won't encounter this because their concurrent accesses, both reads and writes, are protected by locks. However, there are some scenarios where locks just aren't viable for various reasons. For instance, if a few shared variables are read an order of magnitude more often than they're written, then all the lock contention is 90% wasted work among readers that aren't performing any updates. In principle, the lock is really there to permit only one writer to modify the variable at a time. This means we can possibly use some other signalling mechanism to notify readers that a write is taking place, or has taken place. Ideally, this mechanism shouldn't cause contention among readers thus permitting more read parallel

On Confluence and Type Parameter Unification in C#

Awhile back I had written about a a type unification nuisance I had run into. In a nutshell, the problem occurs when a class with two type parameters tries to implement the same interface twice, once for each type parameter: // compiler error: // 'Foo<T0,T1>' cannot implement both 'IEnumerable<T0>' and // 'IEnumerable&;lt;T1>' because they may unify for some type // parameter substitutions public class Foo<T0, T1> : IEnumerable<T0>, IEnumerable<T1> { } As Doug McClean pointed out in the comments, the reason behind this error is because the two implementations of the interfaces may not be confluent, ie. behaviourally identical, in which case there's no legitimate way to choose between the two. The application I had in mind at the time used marker interfaces, ie. interfaces with no methods or properties, so they were guaranteed to be confluent. I also had a sneaking suspicion that C# already permitted this structure el

Combinator Calculus EDSLs in C#

A bit of departure from my usual practical posts in C#, I decided to try my hand at an abstract computer science topic. I've become interested in concatenative programming, and combinator calculi are right up this alley. The quintessential combinator calculus is the well-known SKI calculus , which features two core combinators, S and K, and one optional combinator I. SKI is quite simple, and it's pretty straightforward to implement as an EDSL. I suspect the key stumbling block for most programmers unfamiliar with functional programming will be the pervasive partial application inherent to combinators. Partial Application Partial application is a pretty simple concept for anyone whose done even a little programming with LINQ. C#/.NET features first-class functions called "delegates" with types like: public delegate T2 Func<T0, T1, T2>(T0 arg0, T1 arg1); That's the type declaration for a delegate that accepts two arguments of types T0 and T1, and retu

Brief Announcement - Sasa v0.9.4.3 Bugfix Release

Some minor bugfixes to the new Sasa.Net.Message.ToRaw extension method prompted a minor release of Sasa v0.9.4.3 . Nothing else was changed. I apologize for the excessively long version numbers. The next major Sasa release will be v1.0, and henceforth, point releases will be reserved for bugfixes and other API/backwards-compatible changes. Incompatible changes will increment the major version number,

Sasa.Enums - Typed Enum API

I recently realized that I had missed one important class in the core Sasa.dll assembly, so my blog series isn't technically complete. So here's my twenty-fourth post in the series: Sasa.Func - Type-Safe Delegate Combinators Sasa.Option - Handling Optional Values Sasa.Result - Handling Exceptional Values Sasa.Numbers - Generic Number Extensions Sasa.Strings - General String Extensions Sasa.Types - Runtime Types And CLR Metadata Sasa.Weak - Typed Weak References Sasa's Tuples Sasa's Core Interfaces Sasa.Events - Type-Safe, Null-Safe, Thread-Safe Events Sasa.Web.Url64 - URL-Safe Base64 Encoding Sasa.Operators<*> - Generic Arithmetic and Logical Operators Sasa.IO.FilePath - Easy and Safe Path Manipulations Sasa.IO.Streams - Convenient Stream Extensions Sasa.Linq.Enumerables - Extensions on IEnumerable<T> Sasa.Either - Simple Sums for .NET Sasa.Atomics - Simpler, More Scalable Atomic Operations Sasa.Collections.Arrays - Purely Functional Array

Sasa 0.9.4 Released

I've just uploaded the final Sasa v0.9.4 release to Sourceforge and Nuget . The full API documentation for all assemblies in the Sasa framework is available here . The full changelog is available in the Sourceforge download, or directly in the repo here . Suffice it to say, changes since v0.9.3 include hundreds of bugfixes, and many, many new features. A brief overview of what Sasa is, and what features it provides is covered on the wiki , and reproduced below. Sasa Class Libraries for .NET Sasa is a set of organized class libraries for the .NET framework 3.5 or higher. Here's an overview of the assemblies available and the features they provide: Assembly Description Dependencies Sasa.dll Tuples, sums, generic operators, LINQ extensions, string extensions, thread-safe and null-safe events, and more Sasa.Arrow.dll Arrow computations for .NET Sasa.dll Sasa.Binary.dll Low-level functions on bitdata, fast endian conversions, untagged unions, and more Sasa.Collections.

Sasa-0.9.4-RC5 Uploaded to Sourceforge and Nuget

Since I recently finished documenting the core Sasa assembly , I decided to upload -RC4. Of course, then I ran into an issue with Nuget, which forced me to update my version number to -RC5 in order to overwrite an improperly uploaded package. So here is Sasa 0.9.4-RC5: Sourceforge : download all assemblies and ilrewrite in one package. CHM documentation file available as a separate download. Documentation available online here . Sasa on Nuget : the core Sasa.dll (no dependencies) Sasa.Arrow on Nuget: arrows for .NET (depends on Sasa.dll) Sasa.Binary on Nuget: low-level functions on bitdata (no dependencies) Sasa.Collections on Nuget: purely functional lists, trees, stacks (depends on Sasa.dll, Sasa.Binary.dll) Sasa.Concurreny on Nuget: concurrent abstractions including faster thread-local data and software transactional memory (depends on Sasa.dll) Sasa.Contracts on Nuget: a simple reimplementation of Microsoft's code contracts (no dependencies) Sasa.FP on Nuget: mor

Sasa Wrap-Up - Lazy<T>, Value, and Dictionary Extensions

This is the twenty third post in my ongoing series covering the abstractions in Sasa . Previous posts: Sasa.Parsing - type-safe, extensible lexing and parsing framework Sasa.Dynamics - type-safe polytypic/reflective programming Sasa.Func - Type-Safe Delegate Combinators Sasa.Option - Handling Optional Values Sasa.Result - Handling Exceptional Values Sasa.Numbers - Generic Number Extensions Sasa.Strings - General String Extensions Sasa.Types - Runtime Types And CLR Metadata Sasa.Weak - Typed Weak References Sasa's Tuples Sasa's Core Interfaces Sasa.Events - Type-Safe, Null-Safe, Thread-Safe Events Sasa.Web.Url64 - URL-Safe Base64 Encoding Sasa.Operators<T> - Generic Arithmetic and Logical Operators Sasa.IO.FilePath - Easy and Safe Path Manipulations Sasa.IO.Streams - Convenient Stream Extensions Sasa.Linq.Enumerables - Extensions on IEnumerable<T> Sasa.Either - Simple Sums for .NET Sasa.Atomics - Simpler, More Scalable Atomic Operations Sasa.Coll

Sasa.TypeConstraint and IL Rewriting - Generic Constraints (No Longer) Forbidden in C#

This is the twenty second post in my ongoing series covering the abstractions in Sasa . Previous posts: Sasa.Parsing - type-safe, extensible lexing and parsing framework Sasa.Dynamics - type-safe polytypic/reflective programming Sasa.Func - Type-Safe Delegate Combinators Sasa.Option - Handling Optional Values Sasa.Result - Handling Exceptional Values Sasa.Numbers - Generic Number Extensions Sasa.Strings - General String Extensions Sasa.Types - Runtime Types And CLR Metadata Sasa.Weak - Typed Weak References Sasa's Tuples Sasa's Core Interfaces Sasa.Events - Type-Safe, Null-Safe, Thread-Safe Events Sasa.Web.Url64 - URL-Safe Base64 Encoding Sasa.Operators<T> - Generic Arithmetic and Logical Operators Sasa.IO.FilePath - Easy and Safe Path Manipulations Sasa.IO.Streams - Convenient Stream Extensions Sasa.Linq.Enumerables - Extensions on IEnumerable<T> Sasa.Either - Simple Sums for .NET Sasa.Atomics - Simpler, More Scalable Atomic Operations Sasa.Col

Sasa.IO.DisposableFile - Simple Temporary File Handling

This is the twenty first post in my ongoing series covering the abstractions in Sasa . Previous posts: Sasa.Parsing - type-safe, extensible lexing and parsing framework Sasa.Dynamics - type-safe polytypic/reflective programming Sasa.Func - Type-Safe Delegate Combinators Sasa.Option - Handling Optional Values Sasa.Result - Handling Exceptional Values Sasa.Numbers - Generic Number Extensions Sasa.Strings - General String Extensions Sasa.Types - Runtime Types And CLR Metadata Sasa.Weak - Typed Weak References Sasa's Tuples Sasa's Core Interfaces Sasa.Events - Type-Safe, Null-Safe, Thread-Safe Events Sasa.Web.Url64 - URL-Safe Base64 Encoding Sasa.Operators<T> - Generic Arithmetic and Logical Operators Sasa.IO.FilePath - Easy and Safe Path Manipulations Sasa.IO.Streams - Convenient Stream Extensions Sasa.Linq.Enumerables - Extensions on IEnumerable<T> Sasa.Either - Simple Sums for .NET Sasa.Atomics - Simpler, More Scalable Atomic Operations Sasa.Coll