Jump to content

Dalija Prasnikar

Members
  • Content Count

    1129
  • Joined

  • Last visited

  • Days Won

    102

Everything posted by Dalija Prasnikar

  1. Dalija Prasnikar

    Cross-platform messaging system

    Me, too. But complexities often come with additional features. And often simple systems do not have all the needed features, so when you need them, you can either write your own thingy that only has features you need, or you can use existing more complex one that has features you need plus some more.
  2. Dalija Prasnikar

    Cross-platform messaging system

    That is fine. Point is that System.Messaging is not thread safe. If you are writing multi-threaded application and you need to communicate using some messaging system, then System.Messaging will simply not work in such conditions. You can still use it to send messages to the main thread, but you need to synchronize messaging code, which is not always viable solution. In multithreaded applications, you will need thread safe messaging system that is also capable of posting messages to some message queue.
  3. Dalija Prasnikar

    Addendum to Martin Fowler quote

    Somebody needs to make a good compiler first...
  4. Me and my family are fine, now. Thanks!
  5. Not yet, as we have a backlog of other projects that piled up in the meantime. I had COVID and the earthquake hit the region again on December 29. None of this helped my keep my planned schedule. I do plan to release paperback eventually, but can't tell exactly when.
  6. Eh? Imagine how people who pay would feel if I start giving it away Anyway, if this would be bread and you would be hungry, I'd give you a loaf without thinking twice, but it's not. As much as I'd like to think it is, this book is not really something you can't live without, so... Sorry... And about hugs... My husband expressed his wish to have a private chat with you... you'd better lay low for a while
  7. The full list of code examples from the book Delphi Event-based and Asynchronous Programming is now available on GitHub: https://github.com/dalijap/code-delphi-async
  8. Dalija Prasnikar

    The Case of Delphi Const String Parameters

    I don't know if there is some other reason, but one reason is that with interlocked reference count you can freely use reference counted instances of any type (interfaces, dynamic arrays...) in multithreaded environment for read access if all threads have acquired their strong reference before original reference has been written to (cleared or assigned). In such case you don't need any other more costly locking protection, and you can share same string, so no copying necessary. Clearing such references when they go out of scope is thread safe, because memory deallocation will happen only in case where reference count reached 0. Also getting strong reference from strong reference (variable) held by thread is also thread safe - when I said held by thread it means that no other thread is allowed to write to that variable.
  9. Dalija Prasnikar

    The Case of Delphi Const String Parameters

    With this I agree... There is already solution for this bug - triggering reference counting mechanism for const references. Not other gimmick is necessary. I also said why this solution is not viable, because reference counting induces performance penalty. And this is exactly the reason why there is no reference counting trigger for const parameters so that developers have more control over reference counting and to speed up code execution, since in most code passing reference counting instance (regardless of the type) does not require reference counting. No reference counting is speed optimization. Yes, literal string could be initialized to some higher value. But then every time such string would trigger reference counting just like other strings do. But in this case reference counting would be triggered for string literals, and again that would introduce performance penalty for string literals that do not require memory management and reference counting. Comparing some integer value with -1 is inherently faster than increasing/decreasing reference count. Your proposal would again defeat the purpose of having -1 as speed optimization. We already have that. It is called ReferenceCount field in string header. We don't need another number, negative positive or whatever. http://docwiki.embarcadero.com/RADStudio/Sydney/en/Internal_Data_Formats_(Delphi)#Long_String_Types So your idea with negative flag would not work at all, but even if it would that would also require locking operation on reference count field and same performance penalty. It would be simpler to just trigger reference counting instead. Your idea with additional field (if I understood that correctly) would now mean we would have to do locking on two numbers instead of one. Again even more performance penalty. If we want to pay price in performance penalty, then we could just have compiler to omit all speed optimizations and be done with it. And again I think I explained well enough why this will not happen. Not everyone is willing to sacrifice speed because once in a blue moon some developers might shoot themselves in the foot.
  10. Dalija Prasnikar

    The Case of Delphi Const String Parameters

    Again, -1 is used JUST for string literals. You know when you write s := '123', then '123' is string literal and it is not dynamically allocated and its memory does not have to be managed. That is why there is optimization in RTL JUST for string literals that skips reference counting for them. -1 tells means you are dealing with string literal. You cannot use that value for any dynamically allocated data (strings).
  11. Dalija Prasnikar

    The Case of Delphi Const String Parameters

    Only nil pointer does not have any associated data. When you put some address in pointer you have associated it with some data that is not directly stored in variable itself. Since main purpose of pointer types is storing address to something, so if you treat that address as actual value, then you can say that raw pointers are value types. There is some ambiguity here, sure. In case of other reference types, you are definitely not interested in address as value, but content (value) in associated second part and that is what makes strings, interfaces, objects, dynamic arrays reference types.
  12. Dalija Prasnikar

    The Case of Delphi Const String Parameters

    Pointer is a reference type. But if you are bisecting reference types, then reference part (the immediate value stored in variable) has value type semantics. In other words when you assign one pointer to another you are creating copy of a stored value in that variable alone (reference part), just like when you are assigning one integer to another. If that pointer is not nil - then assigning one pointer to another will still point to the same data location, while pointer itself will have two distinct copies at that time. That also answers the first part of your question.
  13. Dalija Prasnikar

    The Case of Delphi Const String Parameters

    It works as expected because TFoo is record and records are value types. That means two things, first there is no additional memory management (heap) involved. s1 holds complete content of record on stack without indirections. Next because size of record does not fit into register and Value is passed as const compiler optimization kicks in and passes reference to s1 and not copy. In other words generated code is the same as it would be if you used var parameter. If you change declaration of TFoo and make it smaller, you would get different result, because Value would now contain independent copy of the data. TFoo = record X: byte; Y: byte; end; If you change declaration of Test to procedure Test(const [ref] Value: TFoo); Then regardless of TFoo size it would be always passed as reference (pointer) to the original data, and you would not have two copies.
  14. Dalija Prasnikar

    The Case of Delphi Const String Parameters

    That is because string literals don't require managing memory as they are part of the executable and are stored in data segment. Their reference count of -1 is just flag used for optimization and omitting reference counting that makes no sense for general reference counting mechanism.
  15. Dalija Prasnikar

    The Case of Delphi Const String Parameters

    I answered before thinking... so you got me But, real answer is more complicated. Technically, memory representation in Swift allows both variants depending on the size of data (content). So until you discuss actual code, there is not way of telling how will inner representation work. It may be value and it may be reference. In Swift value types and reference types in terms of Swift documentation also means all value types in Swift imply copy on assignment semantic, so for Swift developers that classification carries more weight than actual underlying representation - which again depends on the actual content. Also Swift compiler has(d) bugs around handling "value types" that are not really value types, but rather reference types in terms of Wikipedia definition, that would cause memory leaks under certain conditions (and other issues). I am saying bugs, because some of those I know about were actual bugs, I am not in position to say whether some of those bugs are just "as designed" behavior similar to Delphi const string parameter behavior. I am not that deeply involved with Swift and I am not familiar with all its internals, that also change every five minutes as Swift involves. Just like Delphi strings, Swift "fake" value types can suffer from some problems cause by the fact that they don't occupy single location in memory.
  16. Dalija Prasnikar

    The Case of Delphi Const String Parameters

    The only fact there is is that reference counting does not work like that. And it could not work with any bit flipping. Bit flipping does not solve anything. It is not a blasphemy, it is simply not a working solution. Again, I am not against discussing potential solutions to anything, nor how can something be improved, but when your initial understanding is flawed, there are just too many things that I would have to convince you about.
  17. Dalija Prasnikar

    The Case of Delphi Const String Parameters

    I know. And in Delphi all those types are reference types. In Java all those types are also reference types. Again, definition of value type and reference type does not imply which types in particular language belong to particular category. Value of the string content, not string variable. By your definition all types would be value types. I also quoted Delphi documentation that clearly states value of string variable itself is pointer to actual string data. QED.
  18. Dalija Prasnikar

    The Case of Delphi Const String Parameters

    It is called reference counting not bit flipping for a reason. There is no negative reference count. Any reference counted instance is destroyed when reference count reaches zero. Point of reference counting is that reference count is increased a points where instance (string, object, ...) gets additional reference - if you assign it to another variable, but also when you pass it as parameter. Most of the time passing parameters does not require increasing reference count, but compiler is not capable of analyzing whether this is required or not. This is why programmer must decide whether or not reference count trigger is required for some parameter or not, depending on the code within the procedure. If you want to skip unnecessary reference counting then you should mark parameter as const, if you need reference counting trigger then you don't. The only possible fix (the one Marco implied when he said that compiler will not change) would be that const parameter ALWAYS trigger reference counting. Since whole point of const when managed types are concerned is to prevent unnecessary reference counting and performance penalty, obviously that kind of fix would make no sense at all.
  19. Dalija Prasnikar

    The Case of Delphi Const String Parameters

    Programming languages share some common concepts. But it is important to distinguish things that are comparable and things that are not comparable. Definition of value and reference type does not change with language. There are various implementation details around both, but basic classification is the same. Value types are stored directly in memory associated by variable. And when you are accessing that memory you will always access valid memory as long as you can access that variable. Reference types have two parts, and variable only holds pointer to the actual data that is dynamically allocated on heap. That associated memory holding actual data, may or may not be allocated and your variable can point at invalid memory location that does not hold valid data. That crucial difference between value types and reference types also has huge impact on their behavior in any language. But the actual behavior will differ because every language has different memory management. So what happens and how memory of associated reference is handled cannot be easily compared - this is where you cannot say, Java does this... so Delphi should be able to do this too. And I said "Java has garbage collection, so you absolutely cannot compare it to what Delphi does." The fact that Delphi documentation does not specifically mentions value types and reference types that does not mean that this classification does not exist and that it does not have impact on behavior of different data types. Many things are not explicitly written in documentation, that does not mean they are not real. From http://docwiki.embarcadero.com/RADStudio/Sydney/en/Internal_Data_Formats_(Delphi) description of string type it is pretty clear that string variable holds pointer to actual data, and that is clear definition of reference type. You are confusing value of the string with value type. Value of the string is sequence of characters, but they are not directly stored in string variable, but in some other location. Value stored in the string variable itself is just pointer to that location.
  20. Dalija Prasnikar

    The Case of Delphi Const String Parameters

    Sure... yep... this is my imagination running wild... https://en.wikipedia.org/wiki/Value_type_and_reference_type There is no common sense there is clear definition what reference type is and what value type is. You can always see address stored in any reference type, including string. It just requires typecast.
  21. Dalija Prasnikar

    The Case of Delphi Const String Parameters

    Emphasis is on BEHAVE LIKE. It is not string IS value type. And simulating something is not equal to having that exact thing. string in Delphi is reference type. It is not value type. This is not a viewpoint it is a fact. If you cannot acknowledge facts, this discussion is pointless. s1 and Value are two different references to ONE memory location. When data in that memory location is destroyed because you change s1 variable that was only strong reference to that memory location, Value will point to invalid memory. I am talking about leaking abstractions (as implementation details cannot be completely hidden), not bugs. You cannot completely separate idea (concept) of a string and implementation of a string.
  22. Dalija Prasnikar

    The Case of Delphi Const String Parameters

    Copy on write is not equal to being value type. You may not like "implementation details" and "tricks" but they are more than implementation details, they achieve desired behaviors. You cannot have full value type behavior with something that is not value type. You can only simulate some parts, but that also means that implementation details of actually being a reference type and having ARC to handle its lifetime and COW leak through.
  23. Dalija Prasnikar

    The Case of Delphi Const String Parameters

    Compilers (languages) are always leaky abstractions. At some level you have to define what specific concept means and then that leads to its implementation. There is no universal concept of const parameters. There are many ways how parameters are passed and different languages greatly differ. String type is reference type, not a value type. Only short strings are value types. There is no conceptual here, at least not when Delphi is concerned. Your conceptual discussion would be discussing some completely different language.
  24. Dalija Prasnikar

    The Case of Delphi Const String Parameters

    Your posts clearly show that you have no idea how reference counting actually works, nor how compiler works. I don't mean this as insult, but merely as observation. Not knowing something is not a problem on its own, but it is hard to have meaningful discussion when other party does not have basic idea about discussed topics. I could try to explain it in more details, but I don't know from where should I start. Especially, because you seem to have wrong perception about how compiler works. I am worried that we would be running in circles. Also both topics have enough content around that covering everything from the start would require writing a book.
×