Jump to content

Stefan Glienke

Members
  • Content Count

    1497
  • Joined

  • Last visited

  • Days Won

    152

Posts posted by Stefan Glienke


  1. I would really appreciate the possibility to not having already read posts that I did subscribe or comment on to pop up again whenever there is a new comment.

     

    I know this is how forum software usually works however it gets very distracting if content that I decided is uninteresting to me keeps popping up again.

    • Like 1

  2. If this thread is only a small foreshadowing of how the community (or rather individuals) would react and respond to an open source project and how things are getting discussed I have to say that I would not want to be part of it.

    Yes, everyone is permitted to his own opinions but the how is important - and I can see in other communities like for example the C# compiler or .Net Core projects that developers don't want to deal with bs and toxic waste but communicate in a civilized manner.

     

    ... and that coming from me known as someone who can voice his opinions in a strong way garnished with cursing often enough ...

    • Like 5

  3. 14 hours ago, David Schwartz said:

    you can do dependency injection just as easily without interfaces.

    Yes, you can do - however using DI with interfaces has a unique benefit in Delphi - you don't need to care for who is responsible for cleaning up.

    Leaving aside circular references and assuming a topdown object graph you can simply pass down dependencies even to more than one consumer and stuff gets cleaned up properly in the end.

    Without that you need to track who is the one owning a dependency and responsible for destroying it - possible but more complicated.

     

    In GC languages however having only one implementation for an interface (which you might want to do in Delphi because of the aforementioned reason) is considered a code smell by some - see https://blog.ploeh.dk/2010/12/02/Interfacesarenotabstractions/


  4. This was implemented 10.3 via inline variables. It however is not possible to declare the variable in the old way plus initialize it - you have to declare it inline:

    procedure DoSomething;
    begin
      var MyVar: Integer = 23;
      //
    end;

    You can even omit the type there and it will automatically be Integer:

    procedure DoSomething;
    begin
      var MyVar = 23;
      //
    end;

    See http://blog.marcocantu.com/blog/2018-october-inline-variables-delphi.html

    • Thanks 1

  5. 22 hours ago, edwinyzh said:

    he describes the idea of 'composition over inheritance' much better than me:

    The problem is that historically Delphi did not know about interfaces and many of the concepts he describes and even though Delphi now knows about interfaces the RTL/VCL and most of other basic frameworks don't use them. So most of the RTL/VCL code is still inheriting from more or less not really abstract classes in some long inheritance chains (remember those posters that came with older versions of Delphi?) - now try to teach a Delphi developer that only knows this example different...


  6. 1 hour ago, A.M. Hoornweg said:

    Anyway; the Publisher publishes the Event to all Subscribers, but of course a subscriber may decide to unsubscribe() during this notification,  thus causing the element to be deleted from the list that was being enumerated during the Publish().   But since this is happening synchronously (single-threaded) and just for one subscriber at a time, it should be 100% safe to simply iterate the list backward and allow it to happen.  And if during the Publish() a new subscriber gets appended to the end of the list, he'll simply miss the notification, which is also perfectly correct behavior (a subscriber shouldn't receive a notification that predates his subscription).  So I think that a backward enumerator will do perfectly for my purpose.

    I predict that any time in the future the publisher does not want to block until all subscribers have processed their events and thus you will need to do that asynchronously which requires a less naive approach to iterate the subscribers.

    I know from my multicast events that this can cause a major headache trying to keep performance (not locking all the time) and still being able to detach subscribers in the middle of handling a publish without running into an off by one.


  7. 5 minutes ago, A.M. Hoornweg said:

    The reason why I'm experimenting with backward iterators is that it is intended for a list in which elements may get deleted during the enumeration.

    For .. in is simply much more legible than For .. downto IMHO and also less error-prone .

    That is why in my lists (inspired by the behavior of .NET) it causes an exception when the source changes during enumeration causing the enumerator to be possible invalid.

    I also have a Remove method where I can pass a delegate that determines what elements to remove. IME much more robust than handwriting loops and keeping track of such things.

    • Like 1

  8. TList<T>.GetEnumerator does not call DoGetEnumerator but directly creates its TEnumerator - so overriding it is pointless.

     

    Considering the design in TEnumerable<T>.GetEnumerator to use the virtual DoGetEnumerator I would call this a defect that TList<T> does not stick to this pattern but has its own GetEnumerator.

     

    Anyhow why make a new list class just to enumerate stuff in reverse order?

    • Like 1

  9. 18 minutes ago, Rollo62 said:

    Thinking about Roslyn,  it seems the hell had frozen already.

    No, it was a logical consequence of people not only thinking up to the next fiscal quarter and realizing that not rewriting the compiler would end in a dead end rather sooner than later.

    That combined with a company that has enough resources to put quite some people on a project for years. But we are getting dangerously close to becoming political 😉


  10. FastMM4 FullDebug in a debug build of our application - LeakCheck in unit and integration tests

     

    If any third party leak analysis tool claims that FastMM has a memory leak it probably will tell you the call stack of where it comes from and you will be able to find it.

    Also are you aware that there is RegisterExpectedMemoryLeak function that the third party tool might not be aware of and has a false positive?

     

    As for Deleaker - I think that tool and me won't become friends. UI is irritating and if its burning 100% of my CPU for minutes while triggering a million werfault.exe processes that it supresses until I press cancel to find some memory allocation leaks from that simple program I can't imagine what it will do when I let it run for a real application. "Sorry, but's a no from me"

    • Like 1

  11. The problem is not any 3rd party MM but the fact that some pieces in the RTL are deallocated within System.pas finalization which takes place after detaching/finalizing any 3rd party MM (if that one does something in its finalization block as posted in the previous post). And then it tries to give back memory to the system that it orginally had from the already unloaded/detached 3rd party MM.

     

    There are various fixes in the RTL (I don't remember which version they did that in) that use SysGetMem/SysFreeMem to bypass the pluggable memory manager API. It can very well be the case they missed something or you are using a version that does not have them yet.

    • Like 1

  12. 15 minutes ago, Uwe Raabe said:

    I wonder how the debugger could figure out that the fields FItems, FCount and FTypeInfo have to be merged into something like TArray<T>.

    Write a visualizer for TListHelper that does not simply show all its fields the standard way but as array. Or simply call its FListObj.ToArray as evaluated expression instead (which would be the dumb version as that causes allocation every time).


  13. 6 minutes ago, Hallvard Vassbotn said:

    I think FastMM4 uses a different pattern (all $80, IIRC)

    Correct - it seems to be EurekaLog (see point 3. "When memory is released": https://www.eurekalog.com/help/eurekalog/index.php?memory_leaks_page.php)

     

    I would say its that a destroyed TFieldValue was not removed from the list inside the TGridSet - so locate where those are destroyed and check if they are properly removed from that list when in it.

    • Like 2
×