Jump to content

Stefan Glienke

Members
  • Content Count

    1430
  • Joined

  • Last visited

  • Days Won

    142

Everything posted by Stefan Glienke

  1. Keep in mind this was addressed at Uwes comment that he did not publish something similar because he did not make the effort to make it work not only for his but as a general purpose thing. I cannot speak for others but for me it was reading a lof of collection library code (not only Delphi) - the Delphi specific things (can/cannot use System.Move and such) comes from general core runtime (RTL) knowledge. And sometimes after years it dawns on you that naive usage of generics in large OOP architectures is not the greatest thing and you start refactoring stuff.
  2. Simple: pointers stored in the weakref table in System don't match those after using Move
  3. I disagree - if this implementation were done totally naive it would have actually worked for any T yet in a non optimized way - but the author tried to be clever by using Move 😉 Leave implementing generic collections to people experienced with it (which I in no way claim to have monopoly on) P.S. Since the XE7 refactoring disaster of System.Generics.Collections which still has existing bugs as aftermath I am very sensitive regarding this topic.
  4. I admit - it's not common but good luck storing something like this in your list then: type TMyRecord = record [weak] something: IWhatever; end; I am not bashing any code here but when something is published as general purpose use (which an unconstrained generic collection class is) then I expect it to work for any T. If you don't handle this in your private code because you don't have such use case you of course don't need to care. As for TRingBuffer<T> - it leaks strings for example: var b: TRingbuffer<string>; begin b := TRingbuffer<string>.Create(8); b.Add('one'); b.Delete(1); b.Add(['two', 'three']); b.Free; end;
  5. Read System.Collections.Generics. Particularly the places where it checks for HasWeakRef(T) What weak references are and how they are handled and why you cannot simply System.Move them refer to System.pas (start with RegisterWeakRef)
  6. No, yes For managed types you can System.Move them in the internal array - however it also does it when peeking x items into the result array. For types containing weak reference System.Move does not work even for the internal array.
  7. Spring4d 2.0 already has this: https://bitbucket.org/sglienke/spring4d/src/c336b8dd39bfc30cbcf2fa1f6d8323e663bdcc05/Source/Base/Collections/Spring.Collections.Base.pas#lines-473 It is an abstract base class (you don't simply use that one) implemented by several different ready to use collections such as queue, deque, boundedqueue (does not grow like queue does), evictingqueue (drops the oldest element when full) TRingbuffer<T> unfortunately has several defects, mostly around simply using Move regardless the type of T (managed, containing weak reference)
  8. What you refer to is called forking and in fact GitHub is able to track what repositories are a fork and where they originate from. The problem is a different one and that is that often forks are more active than the original one which at some point might be completely inactive. If I were someone actively working on a fork while the original project might be dead I'd reach out to the original maintainer/author and try to work something out.
  9. Yes it is - optimizer does not reorder. If it would short-circuit evaluation would be broken. FWIW setting Result to False and or'ing it with A is unnecessary - x or False = x
  10. That code does not compile, method references cannot be declared as consts. What you probably meant was this: const Funcs: array[0..2] of function: Boolean = (A, B, C); And yes, that only works if they are parameterless otherwise you would have to declare that differently - but again only works if they are have homogeneous signatures. Talking about possibly overengineering: https://en.wikipedia.org/wiki/Specification_pattern
  11. Conditionals probably but certainly not switches.
  12. And what exactly is wrong or not understandable in a week with using {B+} and a simple one liner?
  13. Stefan Glienke

    System.GetMemory returning NIL

    They do by possibly specifying a capacity when creating one. Should I depending on that number either call SetLength which uses GetMem or allocate the dynamic array memory buffer myself? I would rather like to avoid that because that might get quite complicated when we are talking about resizing. That is what I was aiming at - making claims of how x is bad and y is better is all good and sound but what are the concequences for developers that want to benefit from these potential benefits - or does it not matter at all.
  14. Stefan Glienke

    August 2020 GM Blog post

    The alternative to Italic... scnr
  15. Stefan Glienke

    System.GetMemory returning NIL

    As a library developer I have this question after reading all this: how does this affect me. For example collections are an essential part of spring4d and they can be of any capacity from just a few items which fit into a small block up to collections that hold thousands of elements and where SetLength causes the used GetMem to use large blocks. So if anyone claims that the way the MM does it is not good the solution for many places that allocate variable size of memory is not to put if size < x then getmem else virtualalloc but to solve this properly inside of GetMem/the memory manager. Especially since GetMem is indirectly called by many things such as SetLength - if you directly allocate memory for your own sure you can choose one or the other.
  16. Stefan Glienke

    System.GetMemory returning NIL

    Yes some are written to disk but usually not commonly used memory - especially not when there is plenty of RAM available. The article even says:
  17. Stefan Glienke

    System.GetMemory returning NIL

    Look into the implementation of System._GetMem and compare that with System.GetMemory and you know the answer.
  18. Not sure you missed or ignored it but I'll throw this in here for completeness and because it's free: Git Extensions.
  19. Stefan Glienke

    IDE plugin to remove Explicit* from .dfm files

    You either keep wondering or you simply google it and find this for example: https://stackoverflow.com/a/2477026/587106
  20. Stefan Glienke

    IDE plugin to remove Explicit* from .dfm files

    Ask him nicely how you can help him get it out for 10.4 and maybe he'll do.
  21. Stefan Glienke

    IDE plugin to remove Explicit* from .dfm files

    DDevExtensions does it indeed.
  22. Oh gosh... As for what temporal coupling means - use google before I spend my time explaining it to you - someone else probably already did a better job anyway. P.S. Your use of "class field" and "class method" is wrong - what you are referring to are instance fields and methods. type TFoo = class fName: string; // instance field or just field - because every instance has its own class var fCount: Integer; // class field because there is just one - basically like a global variable but only visible inside of TFoo procedure Bar; // instance method or just method - can access instance members (like fName) but also class members (like fCount) - Self refers to the instance of TFoo class procedure SomeStuff; // class method - can access class members (like fCount) but not instance members - Self refers to the class itself - here TFoo - many other languages don't have something like this class procedure MoreStuff; static; // static class method - can also access class members but has no Self end;
  23. Stefan Glienke

    Delphi 10.4 compiler going senile

    I wish when they did (most of all that .NET API inspired copies happened years ago) they actually did not mindlessly copy it: - Monitor... I think C# at that time already had the lock keyword which does all that underneath to avoid boilerplate, - generics and mostly type constraints - understanding that class in C# is a constraint on reference types and not only on classes and that struct is a constraint for value types. Porting that properly to Delphi which has kind of hybrid types such as string or dynamic array. - System.IEnumerable and IEnumerable<T> and that in Delphi without a rooted type system it does not make a bloody sense to inherit the generic one from the non generic one - System.IOUtils - plagued with ton's of bugs and a rather terrible API and performance I think there are more examples. .NET is not perfect but I am amazed how much effort goes into it - how APIs are being improved (and yes mostly without breaking them - the issue with inventing and dropping things is mostly in the eco system that builds upon it). Damn they even care about binary size for their guard code! (see the comment in https://github.com/dotnet/runtime/blob/master/src/libraries/System.Private.CoreLib/src/System/ThrowHelper.cs) Recently they refactored many APIs to use Span<T> to avoid unnecessary allocations - while in Delphi we still allocate strings all over the place when using the stringhelper methods for example and only the people that care for performance then do all that ugly mess with PChar.
  24. My first impulse was pure function! as well but that depends on how SearchByFieldName is implemented - ultimately this looks like it mutates internal state. However you should avoid temporal coupling as it leads to hard to maintain code.
  25. Stefan Glienke

    ANN: TMS Web Core for Visual Studio Code - Public Beta

    Sure but as it stands and even with LSP support in 10.4 Visual Studio Code with OmniPascal (not sure what you offer for code tooling in your package) even with its glitches runs circles around what you can do in RAD Studio coding and code navigation wise. So doing all form stuff and debugging in RAD Studio while doing the pure coding in Visual Studio Code (yes some people don't just slap components on forms and implement event handlers!) is often the superior experience.
×