Skip to content

Instantly share code, notes, and snippets.

View GregRos's full-sized avatar

Greg Ros GregRos

View GitHub Profile
@GregRos
GregRos / InlineTraits.md
Last active August 29, 2015 14:17
Write-up for a feature idea for F#.

Inline Traits

This is a short description of a feature suggestion for F# called inline traits.

An inline trait is similar to an interface, in that it establishes a set of criteria for a type. However, unlike an interface, an inline trait isn’t actually a type in itself. Values do not have a trait type; they can only have a generic type which conforms to an inline trait. It is important to note that, as the inline keyword implies, traits are not part of the CLI type system and everything about them is implemented using code generation, similarly to other inline constructs, and may only be used in the scope of inline members.

Inline traits are defined like this:

inline trait VectorLike<^elem> of ^this =
	abstract Add : ^elem -> ^this

abstract Length : int

@GregRos
GregRos / FakeInheritance.fs
Created March 17, 2015 00:05
Faking module inheritance/generic modules
module Hidden =
///Parent class of module types.
[<AbstractClass>]
type ModuleType() =
inherit obj()
//Obsolete because we don't want them visible.
[<Obsolete("This is a module type.")>]
override x.Equals o = base.Equals o
[<Obsolete("This is a module type.")>]
override x.GetHashCode() = base.GetHashCode()
@GregRos
GregRos / Self-identifiers.md
Created March 20, 2015 06:47
Type self-identifiers in interfaces

Type Self-identifiers in Interfaces

Feature proposal for F#.

In F#, you often deal with immutable objects that can return an object of the same type as themselves. However, object-oriented syntax isn't well-equipped to deal with this kind of constraint, because its primary method of constraining types (inheritance and polymorphism) are all about hiding the actual type of an object.

For example, to define an interface of a generic immutable collection that supports addition, you would have to write one of the following:

type ICollection<'t> =
	abstract Add : 't -> ICollection<'t>
@GregRos
GregRos / ExampleComments.md
Created March 22, 2015 18:59
Revolutionary comment syntax
# Usage: 
	This method is *great*. 
	You can use it to do all kinds of things.
	1. Make you a sandwich.
	2. Bake a delicious raspberry pie.
	3. End world hunger
	4. Find a cure for virus
# Parameters:
	1. This parameter is useful.
  1. Not as useful as this one!
//Say you have types Type1, Type2, Type3, then pattern matching can be:
match x with
| :? Type1 as t -> //t is Type1
| :? Type2 as t -> //t is Type2
| :? Type3 as t -> //t is Type3
//Another example is like an advanced switch statement:
match n with
match (arg) {
case 1:
....
case 2:
....
case n when n < 6:
....
default:
....
}

The set and map collections in this library support custom equality and comparison semantics (by accepting an IComparer<T> or IEqualityComparer<T>). This isn't as trivial as it sounds. Remember that these collections support specialized implementations of operations such as Intersect and Union, but these specialized implementations only make sense when both collections use the same equality/comparison semantics. Otherwise, the result will be corrupted.

Now, there are several general ways to handle this issue:

  1. Prohibit custom comparison handlers altogether. This is what F# does with its collections.
  2. Don't support specialized implementations at all. This is what Microsoft's BCL collections do.
  3. Err on the side of recklessness. Perform the specialized operations on the specified collections, without knowing whether their comparison handlers are identical. This inevitably results in data structure corruption if the comparison handlers don't match.
  4. Err on the side of caution. Try to determine
@GregRos
GregRos / fingertree
Created April 3, 2015 18:30
finger tree!
using Funq.Collections.Common;
using System;
namespace Funq.Collections.Implementation {
static partial class FingerTree<TValue> {
abstract partial class FTree<TChild> {
internal sealed partial class Digit {
public override TExpected Apply<TExpected, TValue2>(int nesting, Func<TValue, TValue2> selector, Lineage lin) {
switch (nesting) {
case 0:
return (TExpected)(object)ApplyTo<Leaf<TValue2>, TValue2>(nesting, selector, lin);
using System;
using System.Diagnostics;
using System.Threading;
using System.Runtime.CompilerServices;
using System.Linq;
namespace Tests
{
internal class Bench {
public int Drops = 5;
public int Runs = 10;