Sunday, June 30, 2013

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.Enums

Sasa.Enums provides a statically typed API for working with enums, analogous to the dynamically typed System.Enum. Every method call in System.Enum that accepts a System.Type representing the enum type, here accepts a type parameter that is constrained to be of type enum.

Sasa.Enums.HasFlag

The Sasa.Enums.HasFlag extension method checks for the presence of flag bits set in an enum that has the FlagsAttribute applied:

[Flags]
enum Foo
{
  Bar = 1,
  Other = 2,
}
var value = Foo.Bar | Foo.Other;
Console.WriteLine(value.HasFlag(Foo.Bar))
Console.WriteLine(Foo.Other.HasFlag(Foo.Bar))
// output:
// true
// false

Sasa.Enums.IsDefined

The Sasa.Enums.IsDefined extension method checks whether the given enum value is valid:

enum Foo
{
  Bar,
}
var defined = Foo.Bar;
Console.WriteLine(defined.IsDefined());

var undefined = (Foo)10;
Console.WriteLine(undefined.IsDefined());

// output:
// true
// false

Sasa.Enums.Names

The Sasa.Enums.Names static method provides a enumerable sequence of strings corresponding to the enum's descriptive names. Essentially, this is the equivalent of System.Enum.GetNames, except it's statically typed with an enum constraint, and it returns a cached immutable sequence so it avoids the overhead of allocating an array for every call:

enum Foo
{
  Bar,
  Other,
}
foreach (var x in Enums.Names<Foo>())
{
  Console.WriteLine(x);
}
// output:
// Bar
// Other

Sasa.Enums.ToEnum

The Sasa.Enums.ToEnum set of extension methods provides simple enum parsing:

enum Foo
{
  Bar,
  Other,
}
Foo bar = "Bar".ToEnum<Foo>();
if (bar == Foo.Bar)
  Console.WriteLine(bar);
// output:
// Bar

An exception is thrown if the provided string is not a valid enum name.

Sasa.Enums.TryParse

The Sasa.Enums.TryParse set of extension methods implements non exception-throwing pattern of parsing enums:

enum Foo
{
  Bar,
  Other,
}
Foo bar;
if ("Bar".TryParse<Foo>(out bar);)
  Console.WriteLine(bar);
// output:
// Bar

Sasa.Enums.Values

The Sasa.Enums.Values method provides all the underlying values of the given enum type. Like the Enums.Names method, it returns a cached immutable sequence so it avoids the overhead of allocating arrays for every call:

enum Foo
{
  Bar,
  Other,
}
foreach (var x in Enums.Values<Foo>())
{
  Console.WriteLine(x);
}
// output:
// Bar
// Other

Saturday, June 29, 2013

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:

AssemblyDescriptionDependencies
Sasa.dllTuples, sums, generic operators, LINQ extensions, string extensions, thread-safe and null-safe events, and more
Sasa.Arrow.dllArrow computations for .NETSasa.dll
Sasa.Binary.dllLow-level functions on bitdata, fast endian conversions, untagged unions, and more
Sasa.Collections.dllPurely functional lists, trees, stacksSasa.dll, Sasa.Binary.dll
Sasa.ConcurrencyConcurrency abstractions including faster thread-local data and simple software transactional memory in pure C#Sasa.dll
Sasa.Contracts.dllA simple API-complete reimplementation of Microsoft's code contracts (rewriter not yet provided)
Sasa.FP.dllMore obscure functional abstractions like binomial collections, lenses and function curryingSasa.dll, Sasa.Collections.dll
Sasa.IoC.dllA simple, efficient inversion of control container based on delegates
Sasa.Linq.dllExtensions on LINQ expressions, including a faster expression compiler, expression substitutions, and base classes for query providers and expression visitorsSasa.dll
Sasa.Mime.dllExtended media type directory and mappings between file extensions and media types
Sasa.Net.dllNetwork extensions, including a POP3 client, MIME message parsing, and a preliminary HTTP session state machineSasa.dll, Sasa.Collections.dll
Sasa.Numerics.dllAnalytical extensions for .NET, including statistical functions, minimal Steiner tree approximations and dense matrix math
Sasa.Parsing.dllTyped, extensible lexing and parsing librarySasa.dll
Sasa.Reactive.dllNamed and anonymous reactive values and propertiesSasa.dll
ilrewrite.exeSasa's IL rewriter performs type erasure on type constraints

Blog Series

My blog posts on Sasa cover some of the features in various assemblies:

I recently completed a blog series covering the core Sasa.dll assembly:

If anyone has any problems with the code or the documentation, please post here or in the Sasa forums. I'm happy to help!

Sunday, June 9, 2013

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: more obscure functional abstractions like binomial collections, lenses and function currying (depends on Sasa.dll and Sasa.Collections.dll)
  • Sasa.IoC on Nuget: a simple inversion of control container based on delegates (no dependencies)
  • Sasa.Linq on Nuget: extensions on LINQ expressions, including a faster evaluator/compiler, expression substitutions, and base classes for query providers and expression visitors (depends on Sasa.dll)
  • Sasa.Mime on Nuget: extended media type directory and mappings between file extensions and media types (no dependencies)
  • Sasa.Net on Nuget: network extensions, including a POP3 client, MIME message parsing, and a preliminary HTTP session state machine (depends on Sasa.dll and Sasa.Collections.dll)
  • Sasa.Numerics on Nuget: analytical extensions for .NET, including statistical functions, minimal steiner tree approximations and dense matrix math (no dependencies)
  • Sasa.Parsing on Nuget: typed, extensible lexing and parsing library (depends on Sasa.dll)
  • Sasa.Reactive on Nuget: reactive properties (named and unnamed) and futures (depends on Sasa.dll)
  • Sasa's ilrewrite on Nuget: Sasa's IL rewriter (no dependencies)

Please let me know if there are problems with any of the downloads, or with Sasa itself.

Saturday, June 8, 2013

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:

After this post, I will have covered everything in the core Sasa assembly, Sasa.dll. The first two posts covered Sasa.Parsing.dll and Sasa.Dynamics.dll, and now that the core assembly has been covered, I have only a few final cleanups of the codebase before I release v0.9.4 final on Sourceforge and Nuget.

Of course, there still remains Sasa.Concurrency, Sasa.Binary, Sasa.Collections, Sasa.Numerics, Sasa.Linq, Sasa.Mime, Sasa.Net, and Sasa.Reactive to document, at the very least. The world of Sasa is far larger than what's been covered so far, so there's plenty left to explore! I will continue to write periodic blog posts or other sorts of documentation covering these assemblies, but I won't hold up the v0.9.4 release any further.

Sasa.Lazy<T>

.NET 4.0 was released with a Lazy<T> type, although the one in Sasa predates this one by quite a bit and is somewhat simpler. In principle, there is little difference between a Lazy<T>, a Task<T>/Future<T> and a reactive value, React<T>, like that found in the Sasa.Reactive assembly. In fact, the latter largely generalizes the semantics of the previous three since you can easily register for notifications and construct chained computations ala promise pipelining. As such, Sasa.Lazy<T> may one day be replaced by React<T> or something even more general. But it's available in the meantime, it's simple, and it's well tested in production environments.

Sasa.Lazy<T> Interfaces

The lazy type implements the following core interfaces: IValue<T>, IOptional<T>, IResolvable<T>, IVolatile<T>, and IResult<T>. To summarize, this set of interfaces exports the following methods and properties:

// starts the lazy computation, if not already
// run, and returns the computed value
T IRef<T>.Value { get; }

// returns false if the computation has not yet started
// or it returned an error of some kind
bool IResolvable<T>.HasValue { get; }

// returns false if the computation has not yet started
// or it returned an error of some kind and sets
// 'value' to the encapsulated value
bool IVolatile<T>.TryGetValue(out T value);

// provides the exception generated by the lazy computation
// if any was generated; if an exception was generated, then
// HasValue and TryGetValue both return false
Exception IResult<T>.Error { get; }

Sasa.Lazy<T> Constructors

The lazy constructors either accept a function describing the lazy computation, or accept a value to construct an already resolved lazy type. These constructors are also defined as implicit conversions:

Lazy<int> x = 3;
Lazy<int> y = new Lazy<int>(() =>
{
  Console.WriteLine("Please enter a number:");
  return int.Parse(Console.ReadLine());
});
Console.WriteLine(x.HasValue);
Console.WriteLine(y.HasValue);
// output:
// true
// false

Sasa.Lazy.Create

Lazy.Create are an overloaded set of static methods used to construct lazy types, somewhat akin to the constructors:

Lazy<int> x = Lazy.Create(3);
Lazy<int> y = Lazy.Create(() =>
{
  Console.WriteLine("Please enter a number:");
  return int.Parse(Console.ReadLine());
});
Console.WriteLine(x.HasValue);
Console.WriteLine(y.HasValue);
// output:
// true
// false

Sasa.Values

Sasa.Values is a static class intended to encapsulate a set of useful methods defined for all values. It currently exports only a single overloaded extension method.

Sasa.Values.IsIn

Sasa.Values.IsIn is an overloaded extension method used to check if a value is contained within a collection of other items. Logically, it's equivalent to SQL's "IN" operator. In it's most general form, IsIn is a shorthand for Enumerable.Contains, but the more specific overloads are far more efficient and don't require the construction of a collection to check membership:

Console.WriteLine(3.IsIn(1,2,3,4));
Console.WriteLine("xxx".IsIn("hello", "world!"));
// output:
// true
// false

As explained before, you can already perform this check in standard C#, but it's far more verbose. You either have to create a switch statement, or a set of logical conjunctions in an if-statement, or you have to construct a collection and call Contains like so:

Console.WriteLine(new[] { 1,2,3,4 }.Contains(3));
Console.WriteLine(new[] { "hello", "world!" }.Contains("xxx"));
// output:
// true
// false

Using the IsIn extension is far more concise, and I'd argue, much clearer. A set of overloads accepting an IEqualityComparer.

Sasa.Collections.Dictionaries

The Sasa.Collections.Dictionaries static class exports a small set of extension methods on IDictionary<TKey, TValue>.

Sasa.Collections.Dictionaries.FindOrDefault

Dictionaries.FindOrDefault checks for the presence of a key, and if not present, returns Option<TValue>.None:

var dict = new Dictionary<string, int>
{
  { "foo",          0 },
  { "hello world!", 9 },
};
var hasBar = dict.FindOrDefault("bar")
          || 666;
Console.WriteLine(hasBar);
// output:
// 666

Sasa.Collections.Dictionaries.InsertDefault

Dictionaries.InsertDefault is a set of extension methods that inserts a default value only if the key is currently unbound:

var dict = new Dictionary<string, int>
{
  { "foo",          0 },
  { "hello world!", 9 },
};
dict.InsertDefault("bar", 666);
dict.InsertDefault("foo", () => 1234);

Console.WriteLine(dict["foo"]);
Console.WriteLine(dict["bar"]);
// output:
// 0
// 666

As you can see above, there are two overloads, one accepting a simple value, and one accepting a function that produces a value for the cases where the default value may be expensive to produce.

Note that there may be a few more abstractions or extension methods in the core Sasa dll that weren't entirely documented in this series, but these are abstractions whose API isn't entirely satisfactory, and may soon be refactored or removed. For instance, this is the case with Dictionaries.FindOrOtherwise, which has been in Sasa for quite awhile, and which I've used in some production code, but will probably be replace by the more genreal FindOrDefault.

Friday, June 7, 2013

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:

It's well known that C# forbids certain core types from appearing as constraints, namely System.Enum, System.Delegate, and System.Array. Sasa.TypeConstraint are two purely declarative abstract classes that are recognized by Sasa's ilrewrite tool, and which permit programs to specify the above forbidden constraints. This pattern is used throughout Sasa to implement functionality allowed by the CLR but that would normally be forbidden by C#.

There are two definitions of TypeConstraint, one with only a single type parameter, and one with two type parameters. The second extended definition is unfortunately required to express some corner cases. It's primarily used in Sasa.Operators, and it's generally only needed if you're going to use some methods defined with TypeConstraint within the same assembly. If you can factor out those constrained methods into a separate assembly, you shouldn't ever need it.

Sasa's ilrewrite tool basically crawls the generated assembly IL and erases all references to TypeConstraint wherever it appears. In type signatures, a T : TypeConstraint<Foo> then becomes T : Foo.

Sasa.TypeConstraint.Value

The Sasa.TypeConstraint.Value property allows code compiled assuming a value of type TypeConstraint<Foo> to access the underlying value of type Foo. The ilrewrite tool erases calls to this property as well, leaving the access to the raw value. The following example is actually the definition of Sasa.Func.Combine:

public static T Combine<T>(this T first, T second)
    where T : TypeConstraint<Delegate>
{
    return Delegate.Combine(first.Value, second.Value) as T;
}

The ilrewrite tool erases all references to TypeConstraint so the final output is exactly:

public static T Combine<T>(this T first, T second)
    where T : Delegate
{
    return Delegate.Combine(first, second) as T;
}

TypeConstraint also defines implicit conversion from T to TypeConstraint<T> and TypeConstraint<T, TBase>, so you should never have to construct such an instance manually. If you forget to run ilrewrite on an assembly, attempting to construct or access any members of TypeConstraint will throw a NotSupportedException naming the assembly that needs rewriting.

Sasa's ilrewrite Tool

Sasa's ilrewrite tool has a fairly straightforward interface:

Usage:
ilrewrite /dll:<.dll or .exe> [/verify] [/key:<.snk file>] [/debug]

  /dll:    path to the file that will be rewritten.
  /verify: ensure the rewritten IL passes verification tests.
  /debug:  rewrite debugging symbols too.
  /key:    optional .snk key file used to sign all code.

Any options not listed above will simply be ignored by ilrewrite. The /verify option runs the platform's "peverify" tool to ensure the output passes the CLR verification tests. The /key option additionally creates strongly named assemblies from the given key file. This way you can keep strong names, you just need to defer signing to ilrewrite.

I should also note that this is how Sasa is complying with the LGPL while also providing strongly named assemblies with a privately held key. The LGPL stipulates that Sasa users ought to be able to replace my assemblies with their own whenever they wish, and this is possible using ilrewrite. An assembly that was built against my Sasa.dll simply needs to pass through ilrewrite that's given a different Sasa.dll signed with another key, and the output assembly will then be bound to the new assembly and key. After a brief exchange with a associate member of the EFF, these terms seemed satisfactory, although I should note that he isn't licensed to practice law, and his opinion does not constitute an official EFF response on this issue.

To integrate ilrewrite into my VS builds, I simply place ilrewrite in a bin\ folder under the root folder of my solution, then add the following line to my post-build event:

..\..\..\bin\ilrewrite /verify /dll:$(TargetFileName) /key:..\..\..\key.snk /$(ConfigurationName)

When running a DEBUG build, $(ConfigurationName) specifies the /DEBUG option, and any other configuration specifies an unknown option that ilrewrite simply ignores.

Sasa.Raw: Building on Sasa's Constrained Operations

From time to time, it may be necessary to build upon the constrained operations provided by Sasa, ie. defining a generic but different Func.Combine from the one above, but which takes some additional parameters. Here you'll run into a little trouble because you'll need to specify TypeConstraint<T> on your function, but the rewritten function in Sasa.dll is expecting a T. For this reason, Sasa also ships with Sasa.Raw.dll, which is Sasa.dll prior to rewriting and signing. This means all the TypeConstraint IL is intact, and you can write your extensions as needed.

The step by step procedure is:

  1. Link to Sasa.Raw.dll, not Sasa.dll, when building your project.
  2. In the post-build event, delete Sasa.Raw.dll and copy over Sasa.dll.
  3. In the post-build event, run ilrewrite as you normally would.

This is exactly the same procedure you'd follow when replacing my Sasa release with someone else's. For instance, here's the post-build event for Sasa.Reactive:

copy ..\..\..\bin\Sasa.dll .
del Sasa.Raw.dll
..\..\..\bin\ilrewrite /verify /dll:$(TargetFileName) /key:..\..\..\Sasa.snk /$(ConfigurationName)

If there's anything unclear about any of the above, please don't hesitate to ask here or on the Sasa help forum.

Wednesday, June 5, 2013

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.IO.DisposableFile is a simple object intended to automate the handling of temporary files. Like most IDisposable objects, a DisposableFile is intended to be used within a "using" block, and the file it references is deleted upon exiting the block:

using (var tmp = new DisposableFile(true, "foo.txt"))
{
    File.WriteAllText(tmp.Path, "hello world!");
    Console.WriteLine(File.ReadAllText(tmp.Path));
}
Console.WriteLine(File.Exists("foo.txt"));
     
// output:
// hello world!
// false

Any FileNotFoundException's thrown on dispose are ignored, so you can safely move the file within the "using" block.

Sasa.IO.DisposableFile Constructor

The DisposableFile constructor creates a temporary file:

using (var tmp = new DisposableFile(createIfNotExists: true,
                                    path: "foo.txt"))
{
    ...
}

Sasa.IO.DisposableFile.Path

The Path property exposes the path to the disposable file:

using (var tmp = new DisposableFile(createIfNotExists: true,
                                    path: "foo.txt"))
{
    Console.WriteLine(tmp.Path);
}
// output:
// foo.txt

Sasa.IO.DisposableFile.CreateTemporary

The CreateTemporary static method invokes System.IO.Path.GetTempFileName and returns a DisposableFile instance encapsulating the created file:

using (var tmp = DisposableFile.CreateTemporary())
{
    File.WriteAllText(tmp.Path, "hello world!");
}

Monday, June 3, 2013

Hash Array Mapped Trie Optimizations

It's been awhile since I posted about Sasa's new immutable hash-array mapped trie (HAMT), and I've only just gotten around to running some benchmarks and profiling the code. I just pushed a new project under the "Sasa/Bench" in the repo where I will place all Sasa benchmarks going forward.

Initially the benchmarks were disappointing, but 2 minutes with the profiler revealed the problem was the Tree.Add method, which was using a very simple but poor implementation. Basically, it was checking if the key was already in the tree before attempting to update, thus performing the traversal twice for every addition. I refactored this to share the same implementation as Tree.Update which performs only a single traversal, and the results are now more reasonable.

The benchmarks were run on an FX-8120 performing 200,000 individual inserts and 200,000 individual membership checks on a set of unique integers, ie. treating the dictionaries and trees as a set. The inserts were separately clocked from the membership tests.

Insertions into the HAMT appear to be about ~15x slower than insertions into the mutable dictionary when averaged over the bulk insert benchmark. There is a way to perform bulk inserts much more efficiently, but it wouldn't give a sense for incremental update costs.

Membership tests are ~2x slower for the HAMT, which seems like it's in the right ballpark for an initial implementation. The HAMT also uses a little less than twice the memory of the mutable collections according to the memory statistics after forcing a full GC.

According to profiling data, about 40% of the time in the insert benchmark is spent allocating new arrays, so there doesn't seem to be much room to improve the runtime of updates except perhaps by reducing allocations. I believe Clojure's persistent vectors implement some optimizations here, but I haven't had the need to dig into their implementation.

Lookup costs seem almost entirely related to virtual dispatch overhead while performing recursive lookups on sub-trees. About 45% of the time in the lookup benchmark is spent there. I'm not quite sure how to reduce this overhead, except perhaps to eliminate the class hierarchy that defines the tree structure and use faster type tests and casts. I'm not convinced it would make that much of a difference, but perhaps I'll give it a try if I'm bored some day.

If anyone has any suggestions or pointers to a simple explanation of Clojure's tricks or some other HAMT optimizations, please let me know!

Sunday, June 2, 2013

Sasa.Collections.Arrays - Purely Functional Array Combinators

This is the twentieth post in my ongoing series covering the abstractions in Sasa. Previous posts:

Many abstractions in Sasa provide purely functional semantics since such features tend to be absent in .NET's base class libraries. Sasa.Collections.Arrays is then exactly what it sounds like: a purely functional interface for manipulating one-dimensional arrays. The exported API includes extension methods for slicing, setting slots, appending, inserting and removing elements, all without mutating the original array.

I don't recall the original inspiration for this API, but it was likely some combination of APL and concatenative languages like Forth and Factor. The interface is also not necessarily complete, but it's sufficiently complete that I could relatively easily implement a hash-array mapped trie.

Sasa.Collections.Arrays.Append

The Arrays.Append extension method creates a new array with a new value appended to the end:

var array = new[] { 1, 2, 3 }.Append(4);
foreach (var x in array)
    Console.Write("{0}, ", x);
// output:
// 1, 2, 3, 4, 

Sasa.Collections.Arrays.Bound

The Arrays.Bound extension method ensures that the given array is of exactly the size passed in as an argument. If the array is longer, it creates a slice of the given array starting at index 0:

var array = new[] { 1, 2, 3, 4 }.Bound(2);
foreach (var x in array)
    Console.Write("{0}, ", x);
// output:
// 1, 2, 

Sasa.Collections.Arrays.Concat

Arrays.Concat operates much like Enumerable.Concat, but returns an array instead of an IEnumerable<T>:

var array = new[] { 1, 2, 3 }.Concat(4, 5);
foreach (var x in array)
    Console.Write("{0}, ", x);
// output:
// 1, 2, 3, 4, 5, 

Sasa.Collections.Arrays.Create

Arrays.Create is a simple convenience method for constructing arrays:

var array = Arrays.Create(1, 2, 3, 4);
foreach (var x in array)
    Console.Write("{0}, ", x);
// output:
// 1, 2, 3, 4, 

Sasa.Collections.Arrays.Dup

Arrays.Dup creates an exact duplicate of the given array:

var orig = new[] { 1, 2, 3 };
var dup = orig.Dup();
Console.WriteLine(orig == dup);
Console.WriteLine(orig.SequenceEqual(dup));
// output:
// false
// true

Sasa.Collections.Arrays.Fill

Arrays.Fill is an extension method that fills a given array with a given value between certain bounds. The following code sample utilizes C#'s named parameters for clarity:

var array = new int[4];
array.Fill(item: 1, start: 0, count: 2);
foreach (var x in array)
    Console.Write("{0}, ", x);
// output:
// 1, 1, 0, 0, 

Sasa.Collections.Arrays.IndexOf

Arrays.IndexOf is an extension method that searches an array from beginning to end and returns the first item that matches a predicate, or -1 if no item matches:

var array = new[] { 1, 2, 3, 4 };
var i = array.IndexOf(x => x > 2);
Console.WriteLine(i);
// output:
// 2

Sasa.Collections.Arrays.Insert

Arrays.Insert is an extension method that creates a new array with the given element inserted at the given index:

var orig = new[] { 1, 2, 3 };
var array = orig.Insert(index: 1, value: 99);
foreach (var x in array)
    Console.Write("{0}, ", x);
// output:
// 1, 99, 2, 3, 

Sasa.Collections.Arrays.Remove

Arrays.Insert is an extension method that creates a new array with the element at the given index removed:

var orig = new[] { 1, 99, 2, 3 };
var array = orig.Remove(1);
foreach (var x in array)
    Console.Write("{0}, ", x);
// output:
// 1, 2, 3, 

Sasa.Collections.Arrays.Repeat

Arrays.Repeat is an extension method that repeats all elements up to the given index as many times as will fit in the given array:

var array = new[] { 1, 2, 3, 4, 5 }.Repeat(2);
foreach (var x in array)
    Console.Write("{0}, ", x);
// output:
// 1, 2, 1, 2, 1, 

Sasa.Collections.Arrays.Set

Arrays.Set is an extension method that creates a new array with the given index initialized to the given value:

var orig = new[] { 1, 2, 3 };
var array = orig.Set(index: 1, value: 99);
foreach (var x in array)
    Console.Write("{0}, ", x);
// output:
// 1, 99, 3, 

Sasa.Collections.Arrays.Set

Arrays.Slice is an extension method that extracts a sub-array from the given array delimited by a start and end index:

var array = new[] { 1, 2, 3, 4, 5, 6, 7, 8 }
            .Slice(start: 2, end: 5);
foreach (var x in array)
    Console.Write("{0}, ", x);
// output:
// 3, 4, 5, 

Sasa.Collections.Arrays.ToArray

Arrays.ToArray is a set of extension methods that copies an enumerable sequence into a newly created array given by the lower bounds and lengths:

var source = new[] { 1, 2, 3, 4 };
var twod = source.ToArray<int[,],int>(new[]{ 0, 0 }, new[]{ 2, 2 });
Console.Write("| {0}, {1} |", twod[0,0], twod[0,1]);
Console.Write("| {0}, {1} |", twod[1,0], twod[1,1]);
// output:
// | 1, 2 |
// | 3, 4 |

This extension attempts to copy the array using the fastest means possible, and only uses the slow, generic array indexing interface when the array type has more than 3 indexes.