DEV Community

CrabPascal
CrabPascal

Posted on

Sprint 7 Review: Generics.Collections | Review Sprint 7: Generics.Collections

Bilingual post · Post bilíngue

Jump to: English · Português


English {#english}

Sprint 7 Review: Generics.Collections

Mintlify docs tour — after Sprint 4 exceptions, Sprint 7 brings the collections every Horse API and CRUD service needs.

Generic containers are not syntactic sugar in Delphi — they are how you build caches, registries, and JSON maps. Sprint 7 (v2.15.0) shipped System.Generics.Collections with working TDictionary<K,V> and TList<T>, including TryGetValue with proper var write-back.

What the review documents

From Sprint 7 Review:

  • var parametersValue::Reference, write-back in procedures/functions and TryGetValue.
  • TDictionary::Add / TryGetValue — dispatch in simulate_function_execution; direct routing for instantiated generics.
  • Parser — generic types with Integer/String in expressions (TDictionary<String,Integer>).
  • RTLrtl/sys/System.Generics.Collections.pas; semantic layer recognizes Generics.Collections.
  • Testsgenerics_collections.rs plus fixtures.

Tag v2.15.0 approved.

Dictionary pattern in production code

program DictDemo;
uses
  System.SysUtils,
  System.Generics.Collections;

var
  D: TDictionary<string, Integer>;
  V: Integer;
begin
  D := TDictionary<string, Integer>.Create;
  try
    D.Add('apples', 3);
    if D.TryGetValue('apples', V) then
      WriteLn('apples = ', V);
  finally
    D.Free;
  end;
end.
Enter fullscreen mode Exit fullscreen mode

TryGetValue only writes V when the key exists — the Delphi idiom you expect in services and controllers.

Why var was the sprint's hidden hero

Before v2.15.0, incomplete var semantics blocked realistic APIs. TryGetValue requires the callee to mutate the caller's variable through a reference. CrabPascal introduced Value::Reference and write-back in procedure dispatch specifically for this surface.

Three implementation lessons from the retrospective:

  1. D := TDictionary<...>.Create needs normalize_call_name in execute_assignment — not just in direct calls.
  2. Generic instance methods must hit intrinsics before empty VMT lookups — otherwise Add silently fails.
  3. Explicit out in parser remains debtvar covers TryGetValue for now; Sprint 11 later adds out token support.

Validation commands

cargo test --test generics_collections
crab-pascal run tests/fixtures/dict_trygetvalue_var.pas
Enter fullscreen mode Exit fullscreen mode

The fixture name tells the story: without var write-back, dictionary lookups lie.

TList quick path

var
  L: TList<string>;
begin
  L := TList<string>.Create;
  try
    L.Add('first');
    L.Add('second');
    WriteLn(L[0]);
  finally
    L.Free;
  end;
end.
Enter fullscreen mode Exit fullscreen mode

Enumerators and for..in over generics remain Sprint 15 territory — documented honestly in the technical debt backlog.

Connection to CRUD and Horse

The examples/crud/ project maps product IDs to records. Sprint 17 (currently in progress) extends this with ProdutoService.pas and JSON — but Sprint 7 laid the dictionary foundation every service layer builds on.

Docs: Mintlify Roadmap → Sprint 7 Review · Release v2.15.0. Next: Sprint 10 and Delphi strings in C codegen — where run vs build parity gets measurable.


Português {#portugus}

Review Sprint 7: Generics.Collections

Tour Mintlify — depois das exceções do Sprint 4, o Sprint 7 traz as coleções que toda API Horse e serviço CRUD precisa.

Containers genéricos não são açúcar sintático em Delphi — são como você monta caches, registros e mapas JSON. O Sprint 7 (v2.15.0) entregou System.Generics.Collections com TDictionary<K,V> e TList<T> funcionais, incluindo TryGetValue com write-back var correto.

O que o review documenta

Do Sprint 7 Review:

  • Parâmetros varValue::Reference, write-back em procedures/functions e TryGetValue.
  • TDictionary::Add / TryGetValue — dispatch em simulate_function_execution; roteamento direto para genéricos instanciados.
  • Parser — tipos genéricos com Integer/String em expressões (TDictionary<String,Integer>).
  • RTLrtl/sys/System.Generics.Collections.pas; semântica reconhece Generics.Collections.
  • Testesgenerics_collections.rs + fixtures.

Tag v2.15.0 aprovada.

Padrão dictionary em código de produção

program DictDemo;
uses
  System.SysUtils,
  System.Generics.Collections;

var
  D: TDictionary<string, Integer>;
  V: Integer;
begin
  D := TDictionary<string, Integer>.Create;
  try
    D.Add('apples', 3);
    if D.TryGetValue('apples', V) then
      WriteLn('apples = ', V);
  finally
    D.Free;
  end;
end.
Enter fullscreen mode Exit fullscreen mode

TryGetValue só escreve em V quando a chave existe — o idioma Delphi esperado em services e controllers.

Por que var foi o herói oculto do sprint

Antes do v2.15.0, semântica var incompleta bloqueava APIs realistas. TryGetValue exige que o callee mute a variável do caller por referência. O CrabPascal introduziu Value::Reference e write-back no dispatch de procedures especificamente para essa superfície.

Três lições da retrospectiva:

  1. D := TDictionary<...>.Create exige normalize_call_name em execute_assignment — não só em chamadas diretas.
  2. Métodos de instância genéricos devem ir para intrinsics antes da VMT vazia — senão Add falha silenciosamente.
  3. out explícito no parser permanece débitovar cobre TryGetValue por ora; Sprint 11 adiciona token out.

Comandos de validação

cargo test --test generics_collections
crab-pascal run tests/fixtures/dict_trygetvalue_var.pas
Enter fullscreen mode Exit fullscreen mode

O nome da fixture conta a história: sem write-back var, lookups de dictionary mentem.

Caminho rápido com TList

var
  L: TList<string>;
begin
  L := TList<string>.Create;
  try
    L.Add('first');
    L.Add('second');
    WriteLn(L[0]);
  finally
    L.Free;
  end;
end.
Enter fullscreen mode Exit fullscreen mode

Enumerators e for..in sobre genéricos ficam para o Sprint 15 — documentado honestamente no backlog de débito técnico.

Conexão com CRUD e Horse

O projeto examples/crud/ mapeia IDs de produto a records. O Sprint 17 (em andamento) estende com ProdutoService.pas e JSON — mas o Sprint 7 lançou a base de dictionary que toda camada de serviço usa.

Docs: Mintlify Roadmap → Sprint 7 Review · Release v2.15.0. Próximo: Sprint 10 e strings Delphi no codegen C — onde a paridade run vs build fica mensurável.


Published on dev.to/@crabpascal · Código em CrabPascal

Top comments (0)