Thursday, January 29, 2015

New dynamic array type in Spring4D 1.2

Today I want to talk about dynamic arrays. Often you might prefer them over a full blown generic list because it avoids creating an instance just to store a couple of elements (which are backed by a dynamic array inside the list anyway - at least for a regular TList<T> regardless if you use those from the RTL or the Spring4D ones).

But they are tedious to use even with the additional syntax support in Delphi XE7. There are other implementations that improve dynamic array usage that work even for older versions.

Spring4D will introduce the new DynamicArray<T> type which is a record type with several methods and operator overloads (take a look at it in our develop branch on Bitbucket where we are busy implementing a lot of awesome things for Spring4D 1.2 release this spring).

Let's take a quick look at some of the code you can write using the new DynamicArray<T>.

var
  arr, arr2: DynamicArray<Integer>;
  i: Integer;
begin
{$IFDEF DELPHIXE7_UP}
  arr := [1, 2, 3];
  arr := arr + arr;
  arr := arr + [4, 5];
{$ELSE}
  arr.Assign([1, 2, 3]);
  arr.Add(arr);
  arr.Add([4, 5]);
{$ENDIF}
  for i in arr do
    Write(i, ' '); // 1 2 3 1 2 3 4 5
  Writeln;

  arr2.Assign([2, 4]);
  if arr2 in arr then
  begin
    arr := arr - arr2;
    for i in arr do
      Write(i, ' '); // 1 3 1 2 3 5
    Writeln;
  end;

  arr.Assign([1, 2, 3, 4, 5, 6]);
  arr2 := arr.Splice(2, 2, [7, 8, 9]);
  for i in arr2 do
    Write(i, ' '); // 3 4
  Writeln;
  for i in arr do
    Write(i, ' '); // 1 2 7 8 9 5 6
  Writeln;

It will be available in all versions supported (Delphi 2010 and higher) - only the new syntax to initialize a dynamic array (with the square brackets) is limited to XE7 and higher. But DynamicArray<T> has the add operator and even some more that you don't have with native XE7 dynamic arrays. All methods are continuously optimized for performance as far as possible using pure pascal. DynamicArray<T> does not perform any worse than using the native operations - in some situations even better. Of course it is assignment compatible to TArray<T> by implicit operator overload and will run on all platforms.

Until next time with more about Spring4D 1.2 or something different but not any less interesting!

Edit (01.02.2015): renamed TDynArray to DynamicArray<T>

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: IShared<TStrings>;
begin
  s := Shared<TStringList>.New;
  DoSomething(s);
end;

or:

var
  s: Shared<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: IShared<PMyRecord>;
begin
  s := Shared<PMyRecord>.New;
  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.

Edit: Updated for Spring4D 1.2.1 syntax.