Sunday, January 25, 2015

The Either type for Delphi

In a previous post I talked about the Maybe type that similar to the Nullable type allows you to handle values or the state of having no value in a functional approach.

Today I show you another type that is common in functional programming - the Either type. It allows you to return 2 different types from one function. This could be for example the content of a web request or an error message. In our example we are using similar code as in the previous post and return the result of a division or an error message.

Here is how the function would look like:

function Divide(x, y: Integer): Either<string,Integer>;
begin
  if y = 0 then
    Result := 'Division by zero!'
  else
    Result := x div y;
end;

As you already can imagine Either is a record type with implicit operator overloading making this code look nice and clean. It allows assigning either a string or an integer value. It then sets a flag that says if it's a left or a right. In cases where you use it for returning errors of the action it is common practice to use the right for the correct result and left for some exception/error message.

There are different ways to call this  - and I am afraid I will shock quite some people - one of them involves our beloved with. I know that people went on some crusade against that thing but in this code I find it very convenient.

with Divide(42, 0) do
  case Match of
    IsRight: Writeln(Right);
    IsLeft: ShowError(Left);
  end;

// or

with Divide(42, 0) do
  if Match then
    Writeln(Right)
  else
    ShowError(Left);

// or

Divide(42, 0).Fold(
  procedure(i: integer)
  begin
    Writeln(i);
  end,
  ShowError);

Either has the members Left, Right and Match which is a Boolean. IsRight and IsLeft are just aliases for True and False to make the code clearer. The Fold method takes two anonymous methods of which it calls one depending on if it's a left or right. ShowError is just a small routine I wrote taking a string and writing it to the console to make the code shorter for this example.

Wait a second - don't we have something like that in Delphi already? Yes, its called variant records and it allows something like that. Having a flag field and a dynamic part to store values depending on the flag field. Unfortunately that only works for non nullable value types which renders it pretty useless for this approach.
So finally here is the code for the Either type:

const
  IsLeft = False;
  IsRight = True;

type
  Either<TLeft,TRight> = record
  strict private
    fMatch: Boolean;
    fRight: TRight;
    fLeft: TLeft;
    function GetRight: TRight; inline;
    function GetLeft: TLeft; inline;
  public
    constructor FromLeft(const value: TLeft);
    constructor FromRight(const value: TRight);

    procedure Fold(const right: TProc<TRight>; const left: TProc<TLeft>); overload;
    function Fold<TResult>(const right: TFunc<TRight,TResult>;
      const left: TFunc<TLeft,TResult>): TResult; overload;

    property Match: Boolean read fMatch;
    property Right: TRight read GetRight;
    property Left: TLeft read GetLeft;

    class operator Implicit(const value: TRight): Either<TLeft,TRight>;
    class operator Implicit(const value: TLeft): Either<TLeft,TRight>;
  end;

constructor Either<TLeft, TRight>.FromRight(const value: TRight);
begin
  fRight := value;
  fLeft := Default(TLeft);
  fMatch := IsRight;
end;

constructor Either<TLeft, TRight>.FromLeft(const value: TLeft);
begin
  fLeft := value;
  fRight := Default(TRight);
  fMatch := IsLeft;
end;

procedure Either<TLeft, TRight>.Fold(const right: TProc<TRight>;
  const left: TProc<TLeft>);
begin
  case Match of
    IsRight: right(fRight);
    IsLeft: left(fLeft);
  end;
end;

function Either<TLeft, TRight>.Fold<TResult>(
  const right: TFunc<TRight, TResult>;
  const left: TFunc<TLeft, TResult>): TResult;
begin
  case Match of
    IsRight: Result := right(fRight);
    IsLeft: Result := left(fLeft);
  end;
end;

function Either<TLeft, TRight>.GetRight: TRight;
begin
  case fMatch of
    IsRight: Result := fRight;
    IsLeft: raise EInvalidOpException.Create('Either type has no right value.');
  end;
end;

function Either<TLeft, TRight>.GetLeft: TLeft;
begin
  case fMatch of
    IsRight: raise EInvalidOpException.Create('Either type has no left value.');
    IsLeft: Result := fLeft;
  end;
end;

class operator Either<TLeft, TRight>.Implicit(
  const value: TRight): Either<TLeft, TRight>;
begin
  Result.fRight := value;
  Result.fLeft := Default(TLeft);
  Result.fMatch := IsRight;
end;

class operator Either<TLeft, TRight>.Implicit(
  const value: TLeft): Either<TLeft, TRight>;
begin
  Result.fLeft := value;
  Result.fRight := Default(TRight);
  Result.fMatch := IsLeft;
end;

And finally here is a little teaser of something else I am working on:

Writeln(Divide(42, 3).Fold<string>(
  'Result: ' + i.ToString,
  'Error: ' + s));

Wednesday, January 21, 2015

Never return nil? Maybe!

I admit - such headlines are getting old - at least for those that know a bit about functional programming. But for those of you not familiar with the term monad it might be new. But don't be scared though by all that functional programming gibberish in that Wikipedia article.

Today after Nick's heretical post about avoiding nil we had quite some discussion in the Spring4D team. Because given you must not use nil - how do you deal with the state of none in your code? The business logic might define that a valid result is zero or one item. This often is represented as nil or an assigned instance. But then all your code will have to do nil checks whenever you want to perform operations on that item.

So after some research and reading several articles I found this article and I smacked my head because I did not see that obvious solution. Of course having 0 or 1 element is a special case of a collection. So what would be better suited for that than an enumerable?

I looked around a bit more about and found some more articles with example code making use of that idea.

In fact implementing it in a very similar way in Delphi is not that hard.

program MaybeMonad;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
  Maybe<T> = record
  strict private
    fValue: T;
    fHasValue: string;
    type
      TEnumerator = record
      private
        fValue: T;
        fHasValue: string;
      public
        function MoveNext: Boolean;
        property Current: T read fValue;
      end;
  public
    constructor Create(const value: T);
    function GetEnumerator: TEnumerator;

    function Any: Boolean; inline;
    function GetValueOrDefault(const default: T): T;

    class operator Implicit(const value: T): Maybe<T>;
  end;

constructor Maybe<T>.Create(const value: T);
begin
 case GetTypeKind(T) of
    tkClass, tkInterface, tkClassRef, tkPointer, tkProcedure:
    if (PPointer(@value)^ = nil) then
      Exit;
  end;
  fValue := value;
  fHasValue := '@';
end;

function Maybe<T>.Any: Boolean;
begin
  Result := fHasValue <> '';
end;

function Maybe<T>.GetValueOrDefault(const default: T): T;
begin
  if Any then
    Exit(fValue);
  Result := default;
end;

function Maybe<T>.GetEnumerator: TEnumerator;
begin
  Result.fHasValue := fHasValue;
  Result.fValue := fValue;
end;

class operator Maybe<T>.Implicit(const value: T): Maybe<T>;
begin
  Result := Maybe<T>.Create(value);
end;

function Maybe<T>.TEnumerator.MoveNext: Boolean;
begin
  Result := fHasValue <> '';
  if Result then
    fHasValue := '';
end;

function Divide(const x, y: Integer): Maybe<Integer>;
begin
  if y <> 0 then
    Result := x div y;
end;

function DoSomeDivision(denominator: Integer): Maybe<Integer>;
var
  a, b: Integer;
begin
  for a in Divide(42, denominator) do
    for b in Divide(a, 2) do
      Result := b;
end;

var
  a: string;
  b: Integer;
  c: TDateTime;
  result: Maybe<string>;
begin
  try
    for a in TArray<string>.Create('Hello World!') do
      for b in DoSomeDivision(0) do
        for c in TArray<TDateTime>.Create(EncodeDate(2010, 1, 14)) do
          result := a + ' ' + IntToStr(b) + ' ' + DateTimeToStr(c);
    Writeln(result.GetValueOrDefault('Nothing'));
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.


Now there are a few things in that code I should explain. The record is pretty straight forward. It holds a value and a flag if its empty or not depending on what gets passed to the constructor. For XE7 we can use the new intrinsic function GetTypeKind that makes it possible for the compiler to remove the case code path in this particular code because we have a type kind of tkInteger in our example. But if you had an object or interface this code would run and check for nil.

The class operator makes assigning to a Maybe<T> possible. That's why we could write Result := x div y in the Divide function.

To enumerate our value we just need to implement the GetEnumerator method that returns an instance with the MoveNext method and a Current property.

Now for the fun part. "You are missing an assignment in the else part in Divide!" you might say. Well, that is OK because the field in Maybe<T> marking if we have a value is a string which is a managed type and thus gets initialized by the compiler generated code - you might know that trick already from the Spring.Nullable<T> (which is in fact very similar to the Maybe<T>). In case of y being 0 our result will contain an empty string in the fHasValue field - exactly what we want (please don't argue that a division by zero should raise an exception and not return nothing - I did not invent that example - I was just too lazy to come up with my own). ;)

DoSomeDivision and the 3 nested loops in the main now might look weird at first but if we keep in mind that a Maybe<T> is an enumerable that contains zero or one item it should be clear that these loops won't continue if we have an empty Maybe<T>. And that's the entire trick here. Not checking if there is an item or not. Just perform the operation on a data structure that fits our needs. In this case one that can deal with the state of having or not having an item.

Of course we could avoid all that Mumbo jumbo and use a dynamic array directly that contains no or one item. But even then our code would still contain any kind of checks (and we could not make sure there are not more than one element in that array). With using our Maybe<T> type we can easily use GetValueOrDefault or Any to perform the check if we have an item or not at the very end of our processing when we evaluate the result but not in the middle of the processing.

Of course if you are into functional programming you might argue that this is not what makes a monad and that is true but for this particular use case of dealing with zero or one item it does the job very well. Probably more about functional programming approaches in Delphi or other interesting things in the next post.

Edit: Here is another example which deals with objects:

type
  Maybe = record
    class function Just<T>(const value: T): Maybe<T>; static;
  end;

class function Maybe.Just<T>(const value: T): Maybe<T>;
begin
  Result := Maybe<T>.Create(value);
end;

var
  window: TForm;
  control: TControl;
  activeControlName: Maybe<string>;
begin
  for window in Maybe.Just(screen.ActiveForm) do
    for control in Maybe.Just(window.ActiveControl) do
      activeControlName := control.Name;

  activeControlName.ForAny(ShowMessage);
end;

Same effect here: the loop will not execute if the Maybe returned by the Just call contains nil.

Thursday, January 8, 2015

Smart pointers in Delphi

Yes, I know - I am way too late to that party.

But this is yet another thing that the language itself is missing but can be done with some tricks as the posts showed. However I felt in all these implementations something was missing. Barry's first implementations were record based which had the disadvantage of always having to write .Value when accessing the actual instance. I prefer his latest approach using an anonymous method type. The approach shown in the ADUG blog uses the constructor constraint to be able to create the instance inside the TSmartPointer<T> which is also appealing.

However all these were missing something that could be done with a smart pointer as well. Allocate space for a typed pointer and manage that.

So Spring4D 1.2 (release date tba) will - among many other cool new things - contain a smart pointer implementation.

Code that looked like this until now:

var
  s: TStrings;
begin
  s := TStringList.Create;
  try
    DoSomething(s);
  finally
    s.Free;
  end;
end;

Will look like this:

var
  s: ISmartPointer<TStrings>;
begin
  s := TSmartPointer<TStringList>.Create();
  DoSomething(s);
end;

or:

var
  s: SmartPointer<TStrings>;
begin
  s := TStringList.Create;
  DoSomething(s);
end;

The first is using the interface based (anonymous method to be more precise) smart pointer where you don't need to write .Value when accessing the instance.

The second code is using the record based type where you have to write .Value to access the actual instance but it supports implicit casting from and to the actual type. That is why you can directly assign the TStringList to it and also pass it to the routine.

Here is another example of how to manage some typed pointer:

var
  s: ISmartPointer<PMyRecord>;
begin
  s := TSmartPointer<PMyRecord>.Create();
  s.num := 42;
  s.text := 'Hello world';
end;

In this code the smart pointer will allocate memory for the record and properly finalize and free the memory when it goes out of scope.

Now it would be cool if on a record type you could specify a property as default so it does member lifting in order to get rid of having to type .Value when accessing the underlying value. Especially when the record does not have any other members anyway. That would indeed make records even more powerful as they are already.

Wednesday, October 29, 2014

The real power of generics

I just watched the "Effectively Using Generics in Object Pascal" Code Rage 9 session by Ray Konopka, where he showed a great introduction to generics which is mostly about putting things into lists, dictionaries or other data structures. So basically container types what generics are great for.

When someone asked how you can find out the type of T inside your generic type Ray responded that if you need to do that you may be doing something wrong and why that might be necessary because generic types should be type agnostic.

It might be correct if you only think of collection types when you think about generics. And this is what many people do, hence the discussion I have seen in several places why other pascal languages would need generics because they have powerful array support or other excuses.

But this is limited thinking very much. Generics are way more than a tool to build collection types.
You can do things like the multicast events in Spring4D where of course the generic type needs to find out the exact type info of the T in Event<T> to execute the correct code depending on how you are dealing with a event type or an anonymous method type.
Or think about using generics when using the Spring4D dependency injection container. How could we use TContainer.RegisterType<T> or TContainer.Resolve<T> without finding out the exact type. In fact in that API you mostly don't even pass a variable of that type but just use the generic methods as replacement for something like TContainer.RegisterType(TypeInfo(...)).

Want more examples? Sure!
Think of something like Mock<T> where T is then the type you want to create a mock for. You of course need to find out the type info to pass that into the code that does all the rtti magic beneath (like TVirtualInterface). Think of fluent APIs that return T and provide some typesafe way to use that API (which is what the container registration API and mocks do). Hey, even TComparer<T> from System.Generics.Defaults internally looks up what type the T is to call the correct comparison routine depending on the TTypeKind of the type.

I hope that showed some of the examples where generics give you great power beyond that overused "list of something" example. I am sure you can think of more possibilities!

Oh, by the way the answer to the question asked is: you can use TypeInfo(T) or some of the new intrinsic functions to get information of your generic type parameter.

Thursday, October 9, 2014

Generics and variance

When working with generic collections there is often the question: "Why can't I just assign my TList<TPerson> to a variable of TList<TEntity>? TPerson inherits from TEntity!"

There is something called covariance and contravariance - but the bad news are: Delphi does not support variance. But we are trying to understand what this is all about anyway, shall we?

Let's take a look at our TList<TPerson> again and find out why it is invariant as the Wikipedia article says. Invariant means it's not compatible with either TList<TEntity> nor TList<TCustomer> (TCustomer inherits from TPerson). Let's assume we would hardcast it to TList<TEntity> and continue working with it. It seems correct since every TPerson is a TEntity so a TList<TEntity> is a TList<TPerson> as well, no? No! And that is because data goes out and in. Just iterating over the list and taking the items and printing their name would work. But someone could also try to add a TOrder (it inherits from TEntity) into that list. This will work because at that point we have a TList<TEntity> but at a later point this might horribly crash since some other code still uses the list as TList<TPerson> that suddenly contains a TOrder which clearly does not belong there.

Now let's take a look at a TEnumerable<TPerson> that you might hardcast to a TEnumerable<TEntity>. This will work because you can only retrieve things from TEnumerable<T> but not add any. That is also why C# choses the out keyword for marking a generic type as covariant. And that is also why IReadOnlyList<T> is covariant. You can only retrieve items from it but not add any - even if you could remove items it would be covariant but not if you could add some.

Example: Imagine a box of apples. You can treat it as a box of fruits as long as you just take out some or count them. But you are not allowed to add oranges to it.

Now that we understood what covariance is we might understand easier what contravariance is. As its name implies its the opposite of covariance. And indeed it works the other way around. The Wikipedia articles says the subtyping is reversed. Think of an argument of TProc<TCustomer> that is passed somewhere. So for every TCustomer in a list it does something with that instance and what exactly is done is specified in the anonymous method that is getting passed. The code in that method gets a TCustomer and can access anything a TCustomer has. So now if we had contravariance this would apply here and we could actually pass a TProc<TEntity> because we only want access to the properties of a TEntity which is the base type of TCustomer. Now you see that the C# keyword in makes sense for a contravariant generic type.

If we had a labeler at hand it would be covariant because we can label not only apples but all kinds of fruits.

So how to deal with that kind of dilemma in Delphi?
Well there are several approaches to this. One is carefully(!) using hard-casts making sure that nobody does evil things (like adding oranges into the apple box). When using Spring4D collections you can make use of the ElementType property that every interfaced collection type has to make sure you are not adding wrong things to your list. And you can use the IObjectList interface when dealing with lists that contain class types. This is especially useful when connecting lists to GUI elements because they just have to know about IObjectList. It's almost the same as IList<TObject> but with a different guid and QueryInterface only succeeds for a list that contains objects. But most importantly take the correct type for what you are doing. If you just want to iterate things without manipulating then take IEnumerable<T> or IReadOnlyList<T> instead of IList<T> (see encapsulation).

But there is even more about variance and one is very interesting that not even C# does support - but Java and C++ do: return type covariance.

Imagine a TVehicleFactory with a virtual method CreateNew method that returns a TVehicle. Now you inherit a TCarFactory from it which overrides the CreateNew method. It still has TVehicle as result but it really makes more sense to let it return TCar. If that would work we had return type covariance.

I hope this article shed a bit more light on generics and variance and why certain things don't work the way one might expect.

Friday, October 3, 2014

New language feature in XE7

Nope, not the dynamic array enhancement that everyone talked about already.

In fact I am going to show you something that I haven't seen anyone talking about yet.
It wasn't even mentioned on the official XE7 shows and the reason probably is because it is not been finished completely as in used in generics in the RTL that would benefit from that.

While it is not the desired compiler/linker support for reducing generics code bloat it certainly is something that can help reducing it when used properly.

There are new compiler intrinsic routines called

function IsManagedType(T: TypeIdentifier): Boolean;
function HasWeakRef(T: TypeIdentifier): Boolean;
function GetTypeKind(T: TypeIdentifier): TTypeKind;

These functions when used are evaluated at compiletime and can be used in if and case statements.
Since the expressions of these statements are constant the compiler can eliminate the unused code paths.

Oh, and by the way TTypeKind has been moved to System.pas so no need to include TypInfo for that anymore, yay!

Sounds complicated? Let's see some code:

type
  TFoo<T> = class
    procedure Bar;
  end;

procedure TFoo<T>.Bar;
begin
  case GetTypeKind(T) of
    tkInteger: Writeln('int');
  else
    Writeln('not int');
  end;
end;

begin
  TFoo<Integer>.Bar;
  Readln;
end.

Ok you say, before XE7 we had to write this:

class procedure TFoo<T>.Bar;
begin
  case PTypeInfo(TypeInfo(T)).Kind of
    tkInteger: Writeln('int');
  else
    Writeln('not int');
  end;
end;

So what's the difference? This basically works similar to a compiler directive that we don't have.

When you compile the code using GetTypeKind in XE7 you can see that there is only a blue dot in the line with the Writeln('int') but not in the other one. That indicates only this line can be executed. It would be different when using the other version because that expression is not evaluated to a constant expression at compile time. Hence the compiler cannot remove any part of the case statement.

What does that mean? Well you can write generic types as thin wrappers around code that is written explicitly for the different types without blowing up your binary in the end.

I guess in XE8 we will see that been used in Generics.Collections to reduce the size of the resulting binary. However it cannot remove all duplicated binary code since regardless how thin the generic class is it gets compiled for every instantiation (any different type put in for the T) even if the code is exactly the same. So we will see what other ideas they come up with to solve that problem.

I am also investigating this further to find out if that might be any useful in Spring4D.

Oh, btw compiler guys - while you are adding compiler magic, can you please add the NameOf function aswell? Especially when dealing with databinding and things that are currently referenced as magic strings in the source code this could prevent breaking code by typos or refactorings. Thanks!

Saturday, September 13, 2014

Spring4D 1.1 release and roadmap

Today I am happy to officially announce the release of version 1.1. And also it is the 5th anniversary of Spring4D (at least according to the commit history).

Thanks Paul who started the project and all the others that made Spring4D what it is today:
A modern RTL extension and the most powerful dependency injection container written in Delphi that can compete with those in other languages easily.

For the 1.1 release we have fixed many bugs, refactored and cleaned up the internals of the container and implemented many neat new things. And of course added support for Delphi XE7.

After 5 years and finally getting past version 1.0 we felt it was time to get some official logo for Spring4D to be recognizable and here it is - thanks to Chris Wagner for his help!


New feature - automatic factories

There is one particular feature I am very proud of - and thanks to Philipp Schäfer who had brought me to this idea: automatic factories.

When you are dealing with dependency injection you often have the case that you cannot create everything upfront. Mostly because some information is missing that the user enters during the use of the application. That is when factories and lazy initialization come into play. You obviously created factory classes in the past and registered them into the container so they could be injected into other classes that used them.

You don't have to do that anymore because the container now can create these factories for you!

Let's look at some example:

type
  IMyService = interface
    ['{9C0B02FE-5A69-4409-ACA6-C702CE4D9B44}']
    procedure DoSomething(const msg: string);
  end;

  IDialogService = interface
    ['{A65920CC-E729-4E3B-BD3C-20A9BBDFE753}']
    procedure ShowDialog;
  end;

  TMyService = class(TInterfacedObject, IMyService)
  private
    fAnotherServiceFactory: IFactory<string, IDialogService>;
  public
    constructor Create(const anotherServiceFactory: IFactory<string, IDialogService>);
    procedure DoSomething(const msg: string);
  end;

  TDialogService = class(TInterfacedObject, IDialogService)
  private
    fMsg: string;
  public
    constructor Create(const msg: string);
    procedure ShowDialog;
  end;

constructor TMyService.Create(
  const anotherServiceFactory: IFactory<string, IDialogService>);
begin
  fAnotherServiceFactory := anotherServiceFactory;
end;

procedure TMyService.DoSomething(const msg: string);
begin
  fAnotherServiceFactory(msg).ShowDialog;
end;

constructor TDialogService.Create(const msg: string);
begin
  fMsg := msg;
end;

procedure TDialogService.ShowDialog;
begin
  ShowMessage(fMsg);
end;

Some pretty straightforward code with only one thing that might look unfamilar: IFactory is a new type that can be resolved by the container automatically and comes from the unit Spring.Container.Common and is similar to TFunc but with $M+ which is required for the container to automatically resolve this type using TVirtualInterface.

So how does the registration code look like?

  container.RegisterType<TMyService>;
  container.RegisterType<TDialogService>;
  container.RegisterType<IFactory<string, IDialogService>>.AsFactory;
  container.Build;

  myService := container.Resolve<IMyService>;
  myService.DoSomething('Spring4D rocks!');

The new method AsFactory tells the container to treat this interface or delegate type (if it has method typeinfo on) as factory and it automatically creates the implementation. Any arguments passed are then passed to the container as arguments for the resolution process. That means in this example the string getting passed to the DoSomething method and into the factory is then passed to the container to be injected to the constructor of TDialogService.

What's coming next?

There are several things we want to do in the next couple of months.
  • As you might have seen we have something new in development that is known to some as marshmallow: an ORM that Linas Naginionis contributed to Spring4D. He and Cesar Romero are new on the team and are currently working on the migration and integration into the library.
  • Honza has been working on a better logging solution that will be used internally by the container and can be used in your applications and will have several backends (for CodeSite, SmartInspect or for simple text or console logs). It also can be easily extended to your needs.
  • I have been working on an easy to use interception (AOP) library that can be integrated into the container or used as standalone to do some nice things - those of you attending the EKON 18 in November in cologne will probably see more of it shown by Nick and me.
Along with these new features we also want to write more documentation and how-to articles introducing you to all the features in Spring4D and show advanced dependency injection techniques.

We are eager for your feedback!

As always your feedback is welcome. Are you using Spring4D in your software? Please let us know! You have ideas how to improve the library or want to contribute? Don't hesitate to contact us.