Jump to content

Dalija Prasnikar

Members
  • Content Count

    1137
  • Joined

  • Last visited

  • Days Won

    105

Posts posted by Dalija Prasnikar


  1. 1 hour ago, David Heffernan said:

    Not sure I agree. It can be useful to distinguish between null and length 0 array. It can be useful to have these as different conceptual things. 

    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.

    • Like 1

  2. 1 hour ago, David Champion said:

    @Dalija Prasnikar.  I'm curious. Do you use Delphi to write your mobile apps, XCode or both? What is your current thinking?

    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.

    • Like 1
    • Thanks 1

  3. 23 minutes ago, Fr0sT.Brutal said:

    Well... if you have a pointer to memory, you can't deal with it as with string or array. Direct Ansi processing IMHO goes into history and I won't miss it. So one anyway has to copy data to a string or even convert from buffer to something convenient. So what's the sense in those types.

    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.  

    4 hours ago, Joseph MItzen said:

    C#, Javascript, Python, Ruby, Swift, Go, R, PHP (but still no native Unicode support!), Kotlin... you'd think if 29 string types were useful, more languages would have at least two...

    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.

    • Like 2

  5. 4 hours ago, Joseph MItzen said:

    D has three types - string is UTF-8, wstring is UTF-16, and dstring is UTF-32. Rust has two types - string, and a type that is a slice into a string (it considers this to count as a second string type in the documentation). It still remains that Delphi is the only language to feel the need for so many different types. Heck, Python is the ultimate "glue" language to shove data around between OSes and APIs, and it has one string type and one bytes type and this is sufficient to interface with everything, deal with Windows and COM, wrap C code, etc.

     

     

    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.

     

    4 hours ago, Joseph MItzen said:

    Don't get me started on that too! 😉 No complex number type, no fraction type, no arbitrary precision library, but so many integer types.... At least when I learned Turbo Pascal in Catholic high school I could declare all my types Cardinal.... :classic_biggrin:

     

    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++ :classic_biggrin:

    • Like 2

  6. 4 hours ago, Bill Meyer said:

    And yet, it is considered a member of the C family. And probably for no better reason than the use of those braces. And the braces are probably my least favorite aspect of that language.

    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.

    • Like 1

  7. 3 hours ago, David Heffernan said:

    It's Java. Very early on many C# programs were also valid Java programs.

    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. 3 hours ago, Fr0sT.Brutal said:

    As old-school Delphier I understand why all these string types exist but honestly I'd cut some of them down. Ansistrings with codepages could be removed - RawBytes and Utf8 seems sufficient. Even Utf8 as string type could be avoided in some cases.

    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.

    3 hours ago, Fr0sT.Brutal said:

    Your example :

    
    Without 8-bit string compiler support
    
    procedure Output(const aMsg: string);
    begin
      LOGD(TUTF8Encoding.ToBytes(aMsg));
    end;

     

    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. 12 minutes ago, Bill Meyer said:

    Moreover, C# came along in 2000, and as a .NET language, arguably had no prior existence in any form. Delphi built on the tradition of Turbo Pascal, which appeared in 1983. And C, the root ancestor to C#, had no string type at all.

    I always though Delphi is the root ancestor to C# :classic_biggrin: The only commonality C# has with C are braces.

    • Like 2

  10. 18 minutes ago, Fr0sT.Brutal said:

    I've seen some articles with yells like "why Shortstring, Ansistring, Rawbytestring, WideString, Unicodestring, Utf8string, Whateverstring when you only need one Unicode string?!"

    Indeed, AFAIK C# only has one string type and so does JS. OTOH, any Tbytes/Buffer representation lacks ability of clean operations ("if bytes = 'foo'" etc). However, most of string features could be implemented as helpers, overloaded operators and custom IDE viewers. If only Emba introduced all that stuff together with removing string types, probably this change was accepted more gladly.

    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.

    • Like 3

  11. 3 minutes ago, Fr0sT.Brutal said:

    Many people complained "Why so many string types and what are all these for??" so Emb decided to cut them off in favor of Tbytes but they didn't provide convenient string features at that time (Pos, concat, inline init etc) so much more people started complaining they absolutely need all of that string types so Emb had to bring them back 🙂

    I don't remember anyone complaining :classic_biggrin:

     

    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. 

    • Like 7

  12. 3 hours ago, Dave Nottage said:

    The link to the released version of Xcode 13 seems to have disappeared from that link at the moment - hopefully it will re-appear. Anyway, I made a backup of Xcode 12.5.1 in my /Applications folder first, and after downloading Xcode 13, opened a command-line window and executed this:

    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. 

    • Sad 1

  13. On 9/11/2021 at 1:45 PM, Bernard said:

    2 things I was looking forward to were..

     

    1) Delphi Language Extensions for increasingly powerfull coding

    2) Math performance improvements to increase your application speed

     

    Do these come in the form of later updates...

    We have no idea. New roadmap hasn't been published yet.


  14. 6 minutes ago, rudy999 said:

    Once Delphi is started again -back to initial installation settings.

    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


  15. 14 minutes ago, Mike Torrettinni said:

    Do you also put 3rd party source code under source control? I rarely change anything, but I do have some patches I apply to some components on new install.

    Yes. Usually in separate repository, but sometimes in the same as the project which is using them.

     

    14 minutes ago, Mike Torrettinni said:

    What do you guys have under source control?

    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.

    • Like 2
    • Thanks 1

  16. 12 minutes ago, DPStano said:

    can ctor be private?

    
    strict private
      constructor Create;
    end;

     

    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.


  17. 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;

     

     

    • Like 7
×