Jump to content

Dalija Prasnikar

Members
  • Content Count

    1061
  • Joined

  • Last visited

  • Days Won

    91

Everything posted by Dalija Prasnikar

  1. Dalija Prasnikar

    Why empty dynamic arrays = NIL?

    If you need that distinction you can always wrap it up in nullable type. Delphi implementation of strings and dynamic arrays is fine as it is. Adding that distinction into array or string itself would only complicate working with strings and arrays with no benefits in most of the code. What would be default value of the array or string? nil or empty? If it is nil, welcome to nil nightmare, if it is empty, you need nullable again, or you would just want the ability to nil after it is initialized to empty. This is the fastest road to hell.
  2. No. I am using Xcode and Android Studio. I am also keeping my eye on Delphi side, but I am not using it for anything beyond some test projects. This is a long story, and originally when Delphi added Android support I couldn't use it because it didn't supported all devices I needed to support so I had to use Android Studio. Also Delphi was less interesting for some projects because it removed 8-bit string support and it was crucial for my codebase because I am using UTF-8 based strings for processing since Delphi 7. For those project(s) it was eventually simpler and cheaper to use Windows tablets than switching to Android. Using Delphi definitely makes sense if you have plenty of common business code. Since unification of memory management and bringing 8-bit strings back, that is now even more viable. It all depends on particular situation. It is hard to give general advice. Of course, switching tools is never easy and once you have significant investment in any toolset it is much harder to justify moving to something else - even if it means using same language and UI for all.
  3. You are overly focusing on Ansi. I am more talking about differences between processing in UTF-8, UTF-16 and UTF-32. Depending on what you are doing you might want to use particular string type to avoid unnecessary conversions. For instance on Linux UTF-8 is most commonly used encoding, it makes sense to load data stored in UTF-8 and process it in UTF-8 before storing it back or sending it to client in UTF-8 encoding. Using UTF-16 string type there is utmost waste or resources. On Windows where Windows API-s use UTF-16 that is much less important and you could use regular string type and don't care. But even on Windows you could have situation where you are not interested in UTF-16 representation and where you will do all processing in UTF-8. So all those types very much make sense.
  4. Don't get me started with Swift... (besides the fact you can use other string types there like NSString and NSMutable string) Original Swift string representation storage was UTF16. Swift string, just like with current Delphi string wastes memory and loading and storing (UTF8 is most common storage encoding) performs conversion. Recently Swift string was optimized and UTF16 was replaced with UTF8- This reduced memory consumption and also increased performance. But that is something that had to be done in compiler. Before that you would either have to live with worse performance or you had to fiddle with C++ strings. And working with Swift strings is often #$%&@! because you cannot do simple things in simple way, because you have to got through Unicode consistency layer. Now it is probably simpler to have single string type (if it is well optimized) but that requires completely different string handling and compiler support. Changing that would have immeasurable impact on existing code. Starting new language fresh and designing it with single string type is possible, but old language that has been built on 50 years old roots cannot change its internals that easily.
  5. Delphi string types not only differ in bitness, but in memory management. I don't know how Python shows data to the APIs, but as I previously said that part usually requires converting data back and forth. Ability to work with particular representation directly enables you to write faster code, to avoid unnecessary conversions. Python does not work on such low level Delphi can. That is why half of libraries that do stuff are written in C or C++
  6. I think that family has too many outliers. It is just bunch of languages grouped together because they share few syntactical elements - but they are not roots, they are just letters of the alphabet.
  7. Some syntactical elements, yes and the fact both have GC. But C# also shares plenty of language concepts with Delphi that don't exist in Java. For instance, properties, records, But my comment was partially a joke, so I am not going to argue about this. Certainly C# and Java share some common ground, way, way more than they both share with C.
  8. AnsiString as such makes sense only on Windows, but I don't think removing it is necessary. More problematic are plethora of "compatibility" functions named AnsiXXX that work on string and not on AnsiString. Not really, because LOGI expects pointer to a string not TBytes. So that code does not compile. Not everything can be squeezed in TBytes and not everything makes sense to be bytes. LOGD logs text messages, the fact there is conversion to UTF8 involved is just example. You might as well have API that would directly use UTF-16 encoded string, or you may already work with UTF8 encoded strings.
  9. I always though Delphi is the root ancestor to C# The only commonality C# has with C are braces.
  10. Delphi is much more low level than C# or Java or JS. It has all those string types for a reason and for interacting with particular OS and other APIs. When you need to handle such low level things in Java or any other language the whole thing usually ends up being a memory and performance hog, just like it happened in initial mobile compilers, because you cannot deal directly with particular string representation and you have to juggle data back and forth. And handling encoding and other issues is never easy there, too. Some features can be implemented through helpers, but you cannot accomplish everything in satisfactory manner. For instance getting pointer to UTF8 string to use with OS API you needed additional TMarshaller variable. And not only you need the variable, but the code behind it is slower. Without 8-bit string compiler support procedure Output(const aMsg: string); var M: TMarshaller; begin LOGD(M.AsUtf8(aMsg).ToPointer); end; With 8-bit string compiler support procedure Output(const aMsg: string); begin LOGD(PUtf8Char(Utf8String(aMsg))); end; As far as new users are concerned, they only need to know and use generic string type. If and when they get in touch with other string types, it is pretty simple to explain what is purpose of each type and how is is used. We have different integer types, we have different string types.
  11. I don't remember anyone complaining The though process was a bit different. Mobile compilers were supposed to attract new generation of developers. To do that it needed to have some competing features. One was automatic memory management (hence ARC), another one was streamlining string and array indexing - hence zero-based strings. Short strings store length at index zero, so they were completely incompatible with that goal. AnsiStrings with ANSI encoding are not something that exists on mobile platforms, so they were deemed as unnecessary, too. So 8-bit strings were removed. Unfortunately, what they didn't take into account is impact on existing codebases. The same ones that were supposed to run on all other platforms (yes, you couldn't reuse GUI), but there is not reason to throw away non-GUI code. Zero based strings wreak havoc in string handling, causing subtle bugs all over the place. Most people after they learned about it would just turn the damn thing off. Removing all other 8-bit strings was also a mistake, because 8-bit strings make a whole a lot of sense in cross-platform, especially on Linux where UTF-8 encoding rules. So while throwing out AnsiString as such made sense, the rest did not. This is also why 8-bit strings were reintroduced, even before ARC was removed - which happened for completely different and unrelated reasons. And the last, but not the least. TBytes are completely different beast from strings. It is not that just that handling functions were missing. TBytes don't have COW, and also debugger support is extremely limited and you cannot easily inspect textual data stored within. And we all know how many new customers they attracted to Delphi because it was suddenly cross-platform.
  12. Dalija Prasnikar

    IOS 15 suppoort

    For iOS 15 you need Xcode 13. You can find direct download links here https://developer.apple.com/download/all/
  13. Dalija Prasnikar

    IOS 15 suppoort

    There seems to be more general problem with updating Xcode. Just few days ago I spent 6 hours installing Xcode 12.5.1 It managed to finish only after I deleted old Xcode from applications folder and cleared the trash.
  14. Use Supports function var LTheme: ITheme; begin if Supports(Obj, ITheme, LTheme) then LTheme.UpdateTheme; end;
  15. Dalija Prasnikar

    RAD Studio 11 Alexandria is now available

    We have no idea. New roadmap hasn't been published yet.
  16. No. Because you need type for as operator. (intf_1 as IMyInterface).C; But you also need to add GUID to your interface declaration because without it it cannot be identified.
  17. Dalija Prasnikar

    Delphi 11 first look issues

    Try changing more settings. At some point they will be persisted. Another option is to import 10.4.2 settings or change problematic options directly in registry, before you start IDE
  18. Dalija Prasnikar

    Delphi 11 first look issues

    This sounds like same issue: [REGRESSION] Editor Font setting is not persisted. https://quality.embarcadero.com/browse/RSP-34854
  19. Dalija Prasnikar

    RAD Studio 11 Alexandria is now available

    No, because there are none.
  20. Dalija Prasnikar

    RAD Studio 11 Alexandria is now available

    Borland is dead.
  21. Dalija Prasnikar

    RAD Studio 11 Alexandria is now available

    Africa, Egypt. There was the largest library in ancient world.
  22. Not really. https://jlericson.com/2021/08/24/git_rewrite_1.html https://jlericson.com/2021/09/06/git_rewrite_2.html
  23. Yes. Usually in separate repository, but sometimes in the same as the project which is using them. Anything I can lay my hands on... my book manuscripts, documentation, illustrations and images, 3rd party source code, my own source code or all kinds, recipes, to do lists, basically all kinds of documents that can (or cannot) change with time.
  24. Yes, it can. But the problem is not in hiding your constructor. Every class in Delphi descends from base TObject class, whether you explicitly state that in class declaration or not TSingleton = class TSingleton = class(TObject) And TObject has public constructor Create. That means its every descendant and consequently every other class in Delphi has public constructor Create. Since it is public it is accessible and you cannot prevent people using it. So, even if you hide constructor in descendant class, someone can write TSingleton.Create and this will not call your hidden constructor, but TObject default constructor. The only way to hide that TObject constructor is to add public constructor with same name in your class, like in example I posted. But then you again have problem with having publicly accessible constructor and people can instantiate more than single object instance. If that public constructor raises exception, then at least code will fail at runtime showing that this constructor shouldn't be used.
  25. There is another way to prevent instance creation - or at least misuse - having public constructor that raises exception. TSingleton = class private class var FInstance: TSingleton; constructor CreateSingleton; class destructor ClassDestroy; public constructor Create; class function Instance: TSingleton; static; end; class destructor TSingleton.ClassDestroy; begin FInstance.Free; end; constructor TSingleton.Create; begin raise Exception.Create('Singleton instance cannot be directly constructed'); end; constructor TSingleton.CreateSingleton; begin // actual constructor end; class function TSingleton.Instance: TSingleton; begin if not Assigned(FInstance) then FInstance := TSingleton.CreateSingleton; Result := FInstance; end;
×