Pull to refresh

Comments 12

Столько уже статей про ФП прочитал в стиле «как сложить 2+2 с помощью электронного микроскопа», а вот зачем оно нужно в реальных проектах(а оно там явно нужно, иначе люди бы не занимались этим), и когда его использовать в своих — до сих пор никто понятным языком не объяснил (
Гипотеза или (как здесь) гипотетическая возможность что-либо использовать — это скорее теория, а не практика.

Ну а теория — она всегда впереди практики, теоретические выкладки обычно выглядят не особенно нужными и требуют проверки.
Едва ли Гаусс использовал ежедневно свой метод решения СЛАУ, а Эйнштейн планировал создать ядерную бомбу или АЭС.
Но это их не остановило в своих исследованиях. Было конечно море других гипотез, теорий, методов и предположений. Не прижившихся. Но сначала изобретают, открывают, определяют, а уж потом применяют. Не наоборот.

Это я не к тому, что 1ntr0 — Эйнштейн, а лишь к тому, что без изложения теоретических возможностей практика никогда не состоится.
Вообще мне кажется оратор о другом.

Вот вам в школе сразу формулу лапиталя и теорему коши давали или сначала про связь скорости и ускорения рассказывали?
Или заставляли интегралы считать без рассказа о вычисления площади сложных фигур? Сразу давали заставляли уравнения максвелла считать или показывали опыты с магнитиками?

Так и тут дается примеры реализации паттерноов фп на delphi. Здорово, но паттерн решает задачи. А постановки задачи тут и нет.
В нашей школе и нашем институте — сначала давали решать, а уже потом, когда-нибудь изредка что-нибудь на тему того, «а нафига вообще мы это пол года решаем/считаем». Никакой привязки к реальности. И это ни есть хорошо.
А в Delphi обязательно определять алиасы для типов вида reference to function? Или пример с каррированием все-таки можно более внятно записать как
function(....): reference to function(...): reference to ...
?
reference to function (): ResultType — это не тип. Это синтаксическая конструкция для объявления типа. Соответсвенно именно так написать нельзя.
Другое дело, что можно было вместо своих алиасов использовать предопределенные TProc/TFunc
Все по делу, я только не понял, зачем было оборачивать TDictionary в TCache, ради ICache что ли?
PS Особенно понравился пример именно с Memoize, он не самый очевидный в части использования лок. переменной род кэш :-)
При вызове Memoize происходит создание экземпляра TCache
Cache := TCache<Integer, Double>.Create;

Память выделяется, но где и когда ее освобождать? Обертка в интерфейс и объявление
Cache: ICache

позволяет организовать автоматический подсчет ссылок на экземпляр и автоматическое освобождение памяти из-под него, когда счетчик достигает нуля. Это происходит, когда Memoize выходит из области видимости.
Я так и понял. А я себе сделал универсальную обертку для любого класса для случаев, когда очень хочется использовать класс в роли интерфейса (т.е. не заботясь о его уничтожении), и при этом не наследуясь от TInterfacedObject и не реализуя в каждом классе счетчик ссылок.
Собственно сам код
type
  // Интерфейсная оболочка над объектом (используется, если нужно простой объект превратить в интерфейс)
  IInterfacedContainer<T> = interface
    function InnerObject: T;
    function DetachInnerObject: T;
  end;

  TInterfacedContainer<T: class> = class(TInterfacedObject, IInterfacedContainer<T>)
  private
    FInnerObject: T;
  public
    constructor Create(const aObject: T);
    destructor Destroy; override;
    function InnerObject: T;
    function DetachInnerObject: T;
  end;

{ TInterfacedContainer<T> }

constructor TInterfacedContainer<T>.Create(const aObject: T);
begin
  inherited Create;
  FInnerObject := aObject;
end;

destructor TInterfacedContainer<T>.Destroy;
begin
  FInnerObject.Free;
  inherited;
end;

function TInterfacedContainer<T>.DetachInnerObject: T;
begin
  Result := FInnerObject;
  FInnerObject := nil;
end;

function TInterfacedContainer<T>.InnerObject: T;
begin
  Result := FInnerObject;
end;

{Пример использования}
procedure Test;
var
  vCont: IInterfacedContainer<TSomeObj>;
begin
  vCont := TInterfacedContainer<TSomeObj>.Create(TSomeObj.Create);
  with vCont.InnerObject do
    {do something with TSomeObj}
end;
{ После выхода из метода контейнер автоматически удалится вместе с объектом, который содержится внутри контейнера }


Sign up to leave a comment.

Articles