Chapter122:FunctionalProgramming

No Comments

Section122.1:FuncandAction

Funcprovidesaholderforparameterisedanonymousfunctions.Theleadingtypesaretheinputsandthelasttype is always the return value.

//squareanumber.

Func<double,double>square=(x)=>{returnx*x;};

//getthesquareroot.

//notehowthesignaturematchesthebuiltinmethod.

Func<double,double>squareroot=Math.Sqrt;

//provideyourworkings.

Func<double,double,string>workings=(x,y)=>string.Format(“Thesqua

reof{0}is{1}.”,x,square(y))

Actionobjectsarelikevoidmethodssotheyonlyhaveaninputtype.Noresultisplacedontheevaluationstack.

//right-angledtriangle.

classTriangle

{

public doublea;

public doubleb;

publicdoubleh;

}

//Pythagoreantheorem.

Action<Triangle>pythagoras=(x)=>

x.h=squareroot(square(x.a)+square(x.b));

Triangle t=newTriangle{a=3,b=4}; pythagoras(t);

Console.WriteLine(t.h);//5.

Section122.2:Higher-OrderFunctions

A higher-order function is one that takes another function as an argument or returns a function (or both). This is commonly done with lambdas, for example when passing a predicate to a LINQ Where clause:

varresults=data.Where(p=>p.Items==0);

TheWhere()clausecouldreceivemanydifferentpredicateswhichgivesitconsiderableflexibility.

Passing a method into another method is also seen when implementing the Strategy design pattern. For example, various sorting methods could be chosen from and passed into a Sort method on an object depending on the requirements at run-time.

Section122.3:AvoidNull References

C# developers get a lot of null reference exceptions to deal with. F# developers don’t because they have the Option type. An Option<> type (some prefer Maybe<> as a name) provides a Some and a None return type. It makes it explicit that a method may be about to return a null record.

Forinstance,youcan’treadthefollowingandknowifyouwillhavetodealwithanullvalue.

varuser=_repository.GetUser(id);

Ifyoudoknowaboutthepossiblenullyoucanintroducesomeboilerplatecodetodealwithit.

varusername=user!=null?user.Name:string.Empty;

Whatifwe haveanOption<> returnedinstead?

Option<User>maybeUser=_repository.GetUser(id);

ThecodenowmakesitexplicitthatwemayhaveaNonerecordreturnedandtheboilerplatecodetocheckfor Some or None is required:

varusername=maybeUser.HasValue?maybeUser.Value.Name:string.Empty;

ThefollowingmethodshowshowtoreturnanOption<>

publicOption<User>GetUser(intid)

{

varusers=newList<User>

{

newUser{Id=1,Name=”JoeBloggs”},

newUser{Id=2,Name=”JohnSmith”}

};

varuser=users.FirstOrDefault(user=>user.Id==id);

returnuser!=null?newOption<User>(user):newOption<User>();

}

HereisaminimalimplementationofOption<>.

publicstructOption<T>

{

privatereadonlyT_value;

publicTValue

{

get

{

if(!HasValue)

thrownewInvalidOperationException();

return_value;

}

}

publicboolHasValue

{

get{return_value!=null;}

}

publicOption(Tvalue)

{

_value=value;

}

publicstaticimplicitoperatorOption<T>(Tvalue)

{

returnnewOption<T>(value);

}

}

TodemonstratetheaboveavoidNull.csxcanberunwiththeC# REPL.

Asstated,thisisaminimalimplementation.Asearchfor”Maybe”NuGetpackageswillturnupanumberofgood libraries.

Section122.4:Immutability

Immutabilityiscommoninfunctionalprogrammingandrareinobjectorientedprogramming. Create,forexample,anaddresstypewithmutablestate:

publicclassAddress()

{

public stringLine1{get;set;}

public stringLine2{get;set;}

publicstringCity{get;set;}

}

Any piece of code could alter any property in the above object.Now create the immutable address type:

publicclassAddress()

{

public readonly stringLine1;

public readonly stringLine2;

publicreadonlystringCity;

publicAddress(stringline1,stringline2,stringcity)

{

Line1=line1;

Line2=line2;

City=city;

}

}

Bear in mind that having read-only collections does not respect immutability. For example,

publicclassClassroom

{

publicreadonlyList<Student>Students;

publicClassroom(List<Student>students)

{

Students=students;

}

}

is not immutable, as the user of the object can alter the collection (add or remove elements from it). In order to make it immutable, one has either to use an interface like IEnumerable, which does not expose methods to add, or to make it a ReadOnlyCollection.

publicclassClassroom

{

publicreadonlyReadOnlyCollection<Student>Students;

publicClassroom(ReadOnlyCollection<Student>students)

{

Students=students;

}

}

List<Students>list=newList<Student>();

//addstudents

Classroomc=newClassroom(list.AsReadOnly());

Withtheimmutableobjectwehavethefollowingbenefits:

  • Itwillbeinaknownstate(othercodecan’tchangeit).
  • It is thread safe.
  • The constructor offers a single place for validation.
  • Knowing that the object cannot be altered makes the code easier to understand.

Section122.5:Immutablecollections

TheSystem.Collections.ImmutableNuGetpackageprovidesimmutablecollectionclasses.

varstack=ImmutableStack.Create<int>();

varstack2=stack.Push(1);//stackisstillempty,stack2contains1

varstack3=stack.Push(2);//stack2stillcontainsonlyone,stack3has2,1

Creatingandaddingitems

Creatingusingthebuilder

CertainimmutablecollectionshaveaBuilderinnerclassthatcanbeusedtocheaplybuildlargeimmutable instances:

varbuilder=ImmutableList.CreateBuilder<int>();//returnsImmutableList.Builder

builder.Add(1);

builder.Add(2);

varlist=builder.ToImmutable();

CreatingfromanexistingIEnumerable

varnumbers=Enumerable.Range(1,5);

varlist=ImmutableList.CreateRange<int>(numbers);

Listofallimmutablecollectiontypes:

  • System.Collections.Immutable.ImmutableArray<T>System.Collections.Immutable.ImmutableDictionar
  • y<TKey,TValue>System.Collections.Immutable.ImmutableHashSet<T>System.Collections.Immutable.I
  • mmutableList<T>System.Collections.Immutable.ImmutableQueue<T>System.Collections.Immutable.I
  • mmutableSortedDictionary<TKey,TValue>System.Collections.Immutable.ImmutableSortedSet<T>Syste
  • m.Collections.Immutable.ImmutabeStack<T>

About us and this blog

We are a digital marketing company with a focus on helping our customers achieve great results across several key areas.

Request a free quote

We offer professional SEO services that help websites increase their organic search score drastically in order to compete for the highest rankings even when it comes to highly competitive keywords.

Subscribe to our newsletter!

More from our blog

See all posts

Leave a Comment