Topics

Featured in Development

Understandability is the concept that a system should be presented so that an engineer can easily comprehend it. The more understandable a system is, the easier it will be for engineers to change it in a predictable and safe manner. A system is understandable if it meets the following criteria: complete, concise, clear, and organized.

Featured in Architecture & Design

Sonali Sharma and Shriya Arora describe how Netflix solved a complex join of two high-volume event streams using Flink. They also talk about managing out of order events and processing late arriving data, exploring keyed state for maintaining large state, fault tolerance of a stateful application, strategies for failure recovery, data validation batch vs streaming, and more.

Featured in Culture & Methods

Tim Cochran presents research gathered from ThoughtWorks' varied clients and projects, and shows some of the metrics their teams have identified as guides to creating the platform and the culture for high performing teams.

Interactive Extensions for LINQ to Objects

Interactive Extensions (Ix) is a set of additional LINQ to Objects query operators based on the work done in the Reactive Extensions (Rx). A quick look through the API reveals a set of IEnumerable extension methods under the System.Linq namespace. While most developers already have many of these in their own utility libraries, having a standard implementation for these missing features would be useful.

First up is ForEach, the extension method that pretty much every developer has written at some point. There are two variants, with the second including a zero-based index.

Buffer will chop up an enumeration into smaller enumerations based on a given size. The buffer method uses a mixture of eager and lazy loading. Each buffer of N elements is eagerly read, but no more elements from the source will be read until the previous buffer is fully consumed.

Catch is a rather interesting function. It will read from one source until it either completes or it throws an exception. In the latter case it will then start reading from a second source. The second source can be either an IEnumerable or a function that will return an IEnumerable. When using the latter the logic can be restricted to a specific type of exception.

Concat merely starts enumerating a second list once the first is completed.

Defer takes a function instead of an IEnumerable. The function will be executed if and only if something tries to enumerate over it.

DistinctUntilChanged filters out consecutive duplicates. For example, the sequence [A A B A A B] would become [A B A B].

Do is a variant of ForEach. Unlike ForEach, the Do function only executes its action on elements as they are being enumerated.

DoWhile is like TakeWhile except that the predicate function doesn’t consider the item being enumerated.

The For function deals with an interesting problem. Say you have a list of authors and a matching search function that returns a list of books. The For function would execute the search function on each author in the list and then return a concatenated list of books.

Generate returns a list my mimicking a C style for-loop. It takes for parameters, the initial value, the condition function, the iterate function that changes the state, and the result selector. One could see easily this being used to represent a state machine as an IEnumerable.

The If function uses a predicate function to determine which of two lists to return. If only one list is supplied, then an empty sequence is returned for the false case.

Memoize is used to prevent enumerating a source more than once. In some ways it is like calling ToList, except that ToList will always enumerate the source only once while Memoize will enumerate the source zero or one times. If you tell Memoize how many readers to expect, it can remove items from its internal buffer as the items are consumed by all of the expected readers.

Min and Max work as advertised. MinBy and MaxBy add the option of supplying a value function so you can express things such as “select the customer with the most sales”.

OnErrorResumeNext concatenates two or more sequences with the added benefit that an error from any one sequence will not prevent it from concatenating the remaining sequences.

Repeat creates a list, finite or infinite, that simply repeats the same value over and over again. The value may be a scalar or a list.

Retry will attempt to enumerate a source until successful or an optional number of exceptions have been thrown.

Return will turn a scalar value into a list containing just that one value, eliminating the need to explicitly create arrays of length 1.

Scan is a useful feature for aggregating multiple fields. Unlike normal aggregate functions, Scan functions can be composed, this reducing the number of passes through the source. For example, source.Scan(a=> Dollars +=a.Dollars).Scan(a=> Units +=a.Units).

SkipLast and TakeLast are mirrors of the Take and Skip functions.

Throw is useful for testing, it creates an IEnumerable that will throw an exception if someone tries to enumerate over it.

That's the kind of stuff that make me love .NET

Your message is awaiting moderation. Thank you for participating in the discussion.

The well done generics plus incorporation of composable functional features have improved productivity.C# feels and performs so good being Object Oriented and almost Functional at the same time. It rocks!