I absolutely love the Spring4D libraries and have used them for years. But I am realising I have only scratched the surface. So I thought I would post some of my favourite but less well known features.
I was today years old when I discovered the TBuffer type - it’s part of the cryptography code - but it’s immensely useful
Assignable to/from TBytes
ToHexSting method
Load from/save to TStream
ToString method
Access to the underlying memory via Memory property (pointer).
Size property
Bitwise And/Or/Xor operations.
It’s just an incredibly well thought out type. It’s basically what TBytes should have been!
I only discovered it today when I needed to do some hashing - the spring4d crpytography code is pretty neat too, with support for MD5, SHA1,SHA256, SHA384 and SHA512.
The whole of Spring4D is a gem. I too have only scratched the surface (we primarily use the core features in Collections, Services, Container). I haven’t looked at new features or changes for the last couple of years (note to self - to review).
One hidden gem that we use is Spring.SystemUtils.TEnum that provides convenient ways to convert between enums and strings and integers (e.g. persistence).
I love DelphiPraxis but it sucks for notifications - any post into the Google group directly goes to my emails (well when Google does not mess it up and leaves it closed for ages due to a false positive on some malicious content filter)
The same is the case for StackOverflow - once a week or so I check the spring4d tag.
I use RSS - I have a “bot” (at the moment, a service on a Windows machine) that checks feeds, and posts new entries to related channels in my Slack workspace, e.g. #forum-posts for DP and SO, and #qp for Quality Portal
unit U_unique_count;
interface
procedure unique_count_main;
implementation
uses
System.SysUtils, Spring, Spring.Collections, U_Gen_Data;
const
N = 20000;
crlf = #13#10;
function uniq_spring_set : string;
begin
var s := TCollections.CreateSet(data);
exit('Spring Set : ' + s.Count.ToString + crlf);
end;
function uniq_spring_list : string;
begin
var l := TCollections.CreateList(data);
exit('Spring List : ' + l.Distinct.Count.ToString + crlf);
end;
function uniq_spring_sortedlist : string;
begin
var l := TCollections.CreateSortedList(data);
exit('Spring SortedList : ' + l.Distinct.Count.ToString + crlf);
end;
function uniq_spring_enum : string;
begin
exit('Spring Enumerable : ' + TEnumerable.From(data)
.Distinct
.Count
.ToString + crlf);
end;
function uniq_array_int : string;
begin
var last:= -1;
var cnt := 0;
TArray.Sort<integer>(data);
for var i in data do
if i<>last then begin
inc(cnt); last := i;
end;
exit('TArray : ' + cnt.ToString + crlf);
end;
procedure unique_count_main;
begin
generate_uniq_data(N);
writeln(uniq_spring_set);
writeln(uniq_spring_list);
writeln(uniq_spring_sortedlist);
writeln(uniq_spring_enum);
writeln(uniq_array_int);
end;
end.
I missed that there was a call away outside this section (of course there is).
Quite a bit goes on there, there is an interface behind the scenes … so forget my claim here.
Did you end up implementing pubgrub? I remember you lookin at it.
I did actually implement it last week (with the help of claude code) - needs some refining to plug it into dpm (like caching) - but it works amazingly well and gives much better resolution conflict messages than the current solver (which is a simplistic solver at best).
Claude and I are having a bash at it yesterday and today. If nothing else, I am learning about using Claude Code.
I’ve been working on DPM.Core.Tests, and the current sticking point is trying to create equality comparison tests between the previous dependency manager and the pubgrub one.
It doesn’t help that I only half know what I’m doing.
FWIW, I just started a major refactoring of DPM - the decision to use a package file per compiler-platform (TargetPlatform in dpm) has made it next to impossible to handle loadinding design time components. So I am redoing it to use a single package file per compiler - that way I can install the design time stuff no matter which platform a project uses.
It’s quite a big change - especially for directory based repositories - using the filename to find package for a platform quickly is no longer possible, with the current scheme
e.g VSoft.YAML-12.0-Win64-1.1.2.dpkg
It’s pretty easy to find a package based on name, compiler and platform (using regex). Now that package files will include all the platforms they support, I can’t just use regex - so I’m trying to come up with a file naming scheme easy to filter.
The best I have come up with so far is using a bit field with a bit per platform - which is pretty ugly and not really human readable - but at least I can create a filter regex for it.
VSoft.YAML-12.0-10011-1.1.2.dpkg
Not particularly happy with that but it might work - I can at least create a regex to find a package.
Interesting how similar but different mine and yours are - makes me wonder if the work I do with claude on this impacts on someone else doing the same task - do LLM’s learn on the fly from the work they do? I had to spend a lot of time correcting it - it often wanted to diverge from the actual algorithm - I would remind it to stick to the algorithm an it would try again. Spent a day sorting out an infinite loop!
I didn’t bother with starting to integrate it into dpm - I just wanted a cleam implementation of the algorithm first.
I guess we’re going off-topic, in the spirit of the old email list.
I assume it takes weeks and/or months to update the LLM itself .. so I guess it’s getting inspiration from existing implementations in other languages.
My effort started here … recorded because I’m pretty new using Claude Code (in WSL)
It is interesting that after a couple hours, and I guess running out of context window, the AI kinda acts like a tired person might … taking shortcuts, wanting to delete code it just put in, etc.
It should already be there. I added it a while back - just need to update the build process and installer. I’ll try and gfet an update out soon.
FWIW, I am currently reworking the design of DPM
going down the path of 1 package file per compiler-platform actually runs us into a brick wall when it comes to installing design time packages - so my current plan is to re design it to use a single package file per compilerversion with all platforms included - that way installing design time will be simple. It’s quite a big change so I need to think through what needs to change.