Friday, September 06, 2013

The Delphi Language is Lagging Behind

While I love the way Delphi is expanding to multiple platforms (but please, guys, stop the horses once in a while and fix some bugs!), I think the Delphi language could use a facelift. In particular, I like what Eric is doing with the DWS and I absolutely enjoy coding in Smart Mobile Studio where I could use the full power of Eric’s improvements to the language.

I absolutely love DWS’ lambda statement. Delphi’s approach to anonymous methods is so damn long-winded (even for us Pascal programmers who love to type) that lots of programmers reject it just because of the unwieldy syntax. In DWS, however, I can use

var repeater := TW3EventRepeater.Create(lambda (Sender) => MyFunction, 5000);

or

ResizeChildren(FClientArea.Height, [TAlign.Top, TAlign.Bottom],
lambda (layout) => layout.GetConfig.GetHeight,
lambda (layout, value) layout.GetConfig.Height(value) end);

Much shorter. More readable.


Also useful are properties with anonymous storage. If my property only exposes a field and doesn’t use getter or setter, I can shorten the code by 50% by not defining the field at all. Instead of

type
TMyClass = class
private
FData: integer;
public
property Data: integer read FData write FData;
end;

I can write

type
TMyClass = class
public
property Data: integer;
end;

Another nice feature are property expressions – a way to write anonymous getters and setters.

type
TToDoListTemplate=class(TW3form)
public
property Task: string read (W3lblTask.Caption) write (W3lblTask.Caption);
property Detail: string read (W3lblDet.Caption) write (W3lblDet.Caption);
end;

These are incredible time saver. If I redo this the Delphi way, I end up with a much longer code.

type
TToDoListTemplate=class(TW3form)
private
function GetDetail: string;
function GetTask: string;
procedure SetDetail(value: string);
procedure SetTask(value: string);
public
property Task: string read GetTask write SetTask;
property Detail: string read GetDetail write SetDetail;
end;






function TToDoListTemplate.GetDetail: string;
begin
Result := W3lblDet.Caption;
end;


function TToDoListTemplate.GetTask: string;
begin
Result := W3lblTask.Caption;
end;


procedure TToDoListTemplate.SetDetail(value: string);
begin
W3lblDet.Caption := value;
end;


procedure TToDoListTemplate.SetTask(value: string);
begin
W3lblTask.Caption := value;
end;

I also love type inference and in-line variable declaration which allow me to write code like this:


var item := ActionList.Items[ActionList.Add] as TLBItem;
item.Header := header;
item.Text := text;


or


for var item in ActionList.Items do


When I have to write a multiline string constant, multiline strings come handy.


writeln("Hello
World");


Even better – DWS will ignore leading common indentation if string is introduced with #” (or #’).


writeln(#"
    Hello
    World");


And last (but definitely not least), DWS implements a true conditional operator.


s := if a = 0 then 0 else 1/a;

80 comments:

  1. Peter VonĨa11:04

    {$SARCASM ON}
    If and When such features are available in Delphi it will probably be apart of an ADD-ON pack with the price tag of 500$, with key advertisement note :"Programming with Delphi in the 21st century";
    {$SARCASM OFF}

    ReplyDelete
    Replies
    1. The only problem is that it will be the 22nd century by then. ;-)

      Delete
  2. Anonymous11:21

    Coming from C++ and Java, I'm still new to Delphi. I don't really see your guys problem. Perhaps it's not obvious enough for me.
    What's the problem with anonymous methods? They are, by no way, not long-winded. Stuff like your "ResizeChildren" costs like two lines more in Delphi. It probably boils down to personal taste, but I also don't find it more readable either.
    I also don't understand the motivation for stuff like anonymous property storage. It's just a glorified normal variable. I don't really see what I earn by making my class declaration a few lines shorter. If comparing or discussing class hierarchies and architectures, you're not going to use pure source code either way.

    The "lack" of in-line variable declarations is one of the things I have quickly learnt to LOVE after switching to delphi. I don't see how declaring local variables somewhere within a method is going to make my life easier.

    It's just like ... my opinion. I still have less than a year experience with Delphi, but from what I've seen so far, the language itself is fantastic.

    ReplyDelete
    Replies
    1. The problem with Delphi anonymous methods is that you have to write the signature although the compiler could infer it from the left part you assigning it to. The only thing it needs to know are the argument names as I am using them in the body.

      I have to write: function(x: Integer): Boolean begin Result := Odd(x) end;
      where I could simply write: x => Odd(x)

      Delete
    2. Jeepers, you are SO not going to fit in round here with a positive attitude like that.


      Delete
    3. Inline variable declarations have one advantage, if implemented properly: They limit the scope to the code block they are intended for. In particular I'd love to have them in for loops:

      for var i: integer := 5 to 10 do begin
      // i is available here
      end;
      // i is no longer available

      That way, If I have multiple (non nested) for loops in one procedure, I can always use the same variable name but still be sure this variable won't be (ab-)used anywhere else in that procedure.

      Delete
    4. >Coming from C++ and Java, I'm still new to Delphi. I don't really see your guys
      >problem. Perhaps it's not obvious enough for me.
      >What's the problem with anonymous methods? They are, by no way, not
      >long-winded.

      I think the explanation for the disconnect is that you come from Java, a language even more verbose than the legendary COBOL. ANYTHING must seem less verbose than Java. ;-)


      > Stuff like your "ResizeChildren" costs like two lines more in Delphi. It >probably boils down to personal taste, but I also don't find it more readable
      >either.

      Not more readable? Let's look at some of Delphi's wonderful anonymous methods.

      Sorting:

      x.Sort(
      TMyComparer.Construct(
      function (const L, R: TPair): integer
      begin
      result := SysUtils.CompareStr(L.Key,R.Key);
      end ) );

      That's not exactly readable, and it certainly isn't pretty. Honestly I'd consider it an unholy abomination. :-) Anonymous methods are simply not readable nested within a function call, period. Python, arguably the most readable language in existence (they're positively obsessed with readability) won't allow anonymous methods other than lambdas for exactly this reason, being ugly within a function call.

      Warren P. gave an example of a hypothetical, duck-typed lambda syntax to replace this example which was something like this:

      x.Sort( lambda( [L,R], [ SysUtils.CompareStr(L.Key,R.Key) ] ) )


      If it wasn't off-topic I'd talk about the whole approach to sorting via custom comparator functions is flawed and how much better it would be with a key method + lambdas instead.


      >I also don't understand the motivation for stuff like anonymous property
      >storage. It's just a glorified normal variable. I don't really see what I earn
      >by making my class declaration a few lines shorter.

      1. Readabilty.
      2. T*I*M*E.

      >If comparing or discussing class hierarchies and architectures, you're not
      >going to use pure source code either way.

      If you have a readable language, you will.

      >The "lack" of in-line variable declarations is one of the things I have quickly
      >learnt to LOVE after switching to delphi.

      I'm still trying to wrap my mind about someone switching TO Delphi.

      >I don't see how declaring local variables somewhere within a method is going to
      >make my life easier.

      Oh, I need a variable.. page-up, page-up, page-up... declare variable, write the type because Delphi users are human precompilers... page-down, page-down, page-down. I need a for-loop, so I need another variable... page-up, page-up, page-up... etc.

      >It's just like ... my opinion. I still have less than a year experience with
      >Delphi, but from what I've seen so far, the language itself is fantastic.

      I'll debate that with you anywhere, any time. It's been ignored for way too long by its owners and some parts haven't been visited since Turbo Pascal days. I'll give you a paragraph-long list of modern features it's missing, and antiquated "features" it maintains. If I were in charge an entire release cycle would be spent on overhauling the language and another on re-factoring the RTL to bring existing functions in line with new features/syntax and to remove the accumulated cruft that should have been deprecated years ago (such as the SIX methods we now have for reading and writing files!).

      Delete
    5. > Oh, I need a variable.. page-up, page-up, page-up... declare variable,
      > write the type because Delphi users are human precompilers...
      > page-down, page-down, page-down. I need a for-loop, so I need another variable...
      > page-up, page-up, page-up... etc.

      Or you simply press Ctrl + Shift + V to declare a local variable or Ctrl + Shift + D to declare a field...
      That is standard stuff in the refactoring the Delphi IDE offers...

      And if you have to use page-up so many times, you should complain less about Delphi, but about your code. If methods are so long that you have to scroll so much it is ugly code.

      Delete
    6. I don't really use or find useful most of the shortcuts you refer to. There are times when I wish I could declare variables in a method, like I can in C#/C++/C, but it isn't exactly always best that way.

      For example, if you copy/paste two sections of code, you might end up rescoping a variable you didn't intend to, and that's an error that is often only found at runtime. Runtime errors cost more time to find and fix than things that can be caught by a compiler, that's why I kinda don't like any kind of inferring going on in my compiler. I'd rather type something twice and validate what it is that I'm doing (sorta like when a website asks you to type your password twice to confirm it).

      Regardless, I'm not trying to be overly defensive of Delphi. It has it's problems. BIG ONES. I told the Delphi Sales people that Delphi needed to at least be able to compile on multiple platforms and they were rude to me and more or less laughed in my face. Smugly more-or-less saying that they knew their customers better than I did and they'd decide what Delphi needed. The thing is, what customers today need isn't what they'll need 5-10 years from now and a world-class company excels at predicting the future... look at Delphi now... they entered the market YEARS behind on the 64-bit race and YEARS behind on the mobile race.

      But I'm getting off topic here... I apologise. The real thing I wanted to say was that I think that your priorities in terms of language evolution are short-sighted. What Delphi is REALLY REALLY missing, in my opinion is:

      1) A Complete Robust Type System that allows for intelligent definitions of all types. I was, kinda-sorta able to reintroduce the ansistring type to iOS using "records"... but I really had to bend the rules to the limit. I want to be able to define new types that act like "string". I want to inherit from the "record" type. I also want to operator overload Classes, Multiple-inheritance for classes. I want Interface support that isn't tied to COM Bull***t. I want to be able to forward declare records (seriously WTF.. you can't forward declare records!?) And I want a robust language design that does NOT require "ARC", but maybe allows for ARC to be optional. Much of the work I do involves audio engines and sound mixing... and sound threads cannot block under any circumstance... period... if you want low-latency audio. C# has the "Unsafe" directive which basically takes C# and turns it into C... which is quite great and useful actually.

      2) I want COMPLETE headers, robust, validated by the community. CoreMidi is missing from iOS. Direct3D 10-11 missing. Windows Media Foundation missing.

      3) I want complete solutions for just about every popular integration I might want. Facebook and Twitter components are important to just about everyone on the planet, and should maybe just be included as part of the libraries.

      4) I'm tired of dealing with database connectivity BS. It took me 3-DAYS to figure out the right combination of DBX dlls, vendor libs, and MySQL database versions that would yield a successful connection. Delphi doesn't work with the latest MySQL as far as I can tell. I had to drop back to some silly older version. It only works with a very narrow range of MySQL versions. What's worse is that every year I get a NEW Delphi XE, XE2, XE3... I got through this same exercise all over again.. spending DAYS trying to get MySQL connectivity working. Some versions of Delphi required me to buy a 3rd party lib just to get DB access (MicroOLAP). I'm really sick of it. I asked my intern (my friggen intern) to connect to MySQL over C# and she got it done in 45 minutes.

      Okay... I'm done.


      Delete
  3. Fantastic post, I absolutely agree with it's content. DWS has a modern and beautiful sintax.

    You can also consider another element in the sintax which delphi lacks and it is open data initializers. It could be nice to write:

    TMyClass = class
    Value1 : integer default 1;
    Value2 : string default 'Value';
    end;

    Or open initializers (not explicit) in the constructors which override the default values like:

    MyObject := TMyClass.create(Value2 := 'Hello');
    or
    MyObject := TMyClass.create(Value1 := 2, Value2 := 'Bye');

    ReplyDelete
    Replies
    1. You can already declare default field values with

      TMyClass = class
      Value1 : integer := 1;
      Value2 : string := 'Value';
      end;

      or with type inference, the following is enough

      TMyClass = class
      Value1 := 1;
      Value2 := 'Value';
      end;

      Delete
    2. >> MyObject := TMyClass.create(Value2 := 'Hello');
      What does it mean?
      If
      MyObject := TMyClass.create;
      MyObject.Value2 := 'Hello';
      (like C#)
      then it's very dangerous syntax in delphi. If setter SetValue2 raises exeption, we get mem leak.

      Delete
    3. kmorwath13:06

      Value1 := 1; Which type is this? 1 bit? 8 bit? 16 bit? 32 bit? 64 bit? Signed? Unsigned?
      Value2 := 'Value"; Which type is this? 8 bit ANSI string? 8 bit MCBS string? UTF-8? UTF-16?
      Type inference is good for scripting langauges using just a few datatypes, not for compiled languages with many datatypes needed to interact with many different kind of APIs or hardware systems.

      Delete
    4. Its type is the smallest type capable of holding every value the variable is assigned during program execution.

      >not for compiled languages with many datatypes needed to interact with many different kind
      >of APIs or hardware systems.

      And yet every single statically typed language that's been created during the past 15 years has implemented it and several older languages are working on adding it (even C++, I believe). It's more valuable in the type of programs you described because it isn't going to make mistakes, unlike the developer, and if you originally needed 32bit and then later end up needing 64bit there's no code to change.

      Delete
  4. I agree partially (while I sometimes would enjoy the possibility of inline variable declaration I am not sure that it belongs into Delphi according to its history and philosophy)

    There are many more features that would increase productivity in Delphi like the ability to access membernames at compiletime (see http://msdn.microsoft.com/en-us/library/hh534540.aspx)
    or compiler integrated property changed notification (see http://wiki.oxygenelanguage.com/en/Notify_(keyword))

    ReplyDelete
  5. And I on the contrary would like to have current language without bugs in the compiler and IDE. Optimized for speed... probably never happen.

    ReplyDelete
    Replies
    1. KMorwath15:02

      If Delphi is not optimized for speed also with a state-of-the-art RTL it becomes a useless language. Why you should choose a language compiled to processor native code if it isn't optimized? I really don't care about some syntactic sugar when the RTL and other framework libraries are poorly implemented. Who cares to save a few seconds writing code when your executable is slowerd than competition. Here it looks many developers are just envy of the written code, not of the running application. I care about the running application, and if writing it is a little more complex who cares!

      Delete
    2. You need to care because code is read much more often than written. You have to care because you can buy a bigger processor, but not a faster human. Computer time is cheap; human time is expensive.

      >Who cares to save a few seconds writing code

      A few seconds? The most productive languages tend to have 1/5 to 1/10 the lines of code of C++ or Java. Delphi used to be a tool for developing things *quickly*. Now we're far behind in that area.

      >executable is slowerd than competition.

      In how many areas does this even matter anymore? Even entry-level CPUs run "fast enough" for most applications.

      >I care about the running application, and if writing it is a little more
      >complex who cares!

      If I'm paying you by the hour, I care. If I have to maintain the code you wrote, I care. If a team using a more modern language can deliver the product faster and hence cheaper, I care. If I'm competing against a group of Indian developers who can afford to throw two or three developers onto a project for the same cost as my one, I certainly care about any productivity advantage I can get.

      Delete
    3. Fabricio21:06

      >>Who cares to save a few seconds writing code

      >A few seconds? The most productive languages tend to have 1/5 to 1/10 the
      >lines of code of C++ or Java. Delphi used to be a tool for developing things >*quickly*. Now we're far behind in that area.

      I program in Object Pascal(Delphi and Lazarus), TSQL stored procedures and triggers(I'm DBA too), C# (.NET4/.NET3.5) and VB.Net(ditto C#) EVERY DAY of the week in the last 3 years. C# are less readable (but more expressive) than VB (which is less expressive than C#) and Object Pascal is still the most balanced language between readability and expressiveness.

      I really doesn't like Anonimous methods/lambda expressions and use it sparely on all of them (except TSQL, of course) and if some lambda is used more than once is promoted to a full function on spot. LINQ is most used with query syntax. Anonymous methods syntax in Object Pascal is very akin to VB.Net lambdas.

      Inline local variable declaration demands more discipline than var section.
      Step clause on for..do would be nice. Autoimplemented properties like in VB and DWS (yes, the syntax is almost the same) is cool.

      All that, except Step clause on for..do, is just cherry over the cake.


      >>executable is slowerd than competition.

      >In how many areas does this even matter anymore? Even entry-level CPUs run
      >"fast enough" for most applications.

      That's why I feel, from an user perspective, the overall quality of development is decaying. And the symptom: programs use insane amount of computing resources for doing the same things.

      >>I care about the running application, and if writing it is a little more
      >>complex who cares!

      >If I'm paying you by the hour, I care. If I have to maintain the code you
      >wrote, I care. If a team using a more modern language can deliver the
      >product faster and hence cheaper, I care.

      If you develop to code faster, you contradict mantainability.
      If I have to mantain code, verboseness is better than terseness.

      Delete
    4. >>In how many areas does this even matter anymore? Even entry-level CPUs run
      >>"fast enough" for most applications.

      > That's why I feel, from an user perspective, the overall quality of development is
      >decaying. And the symptom: programs use insane amount of computing resources for
      >doing the same things.

      This was the same message that assembler programmers were preaching in the 1980s: there was no way a compiler could generate better code than they could, it was going to be too slow, and it would result in a generation of stupid programmers who didn't know anything about computers. None of that came to pass, and we're hearing the same thing today from certain quarters about managed code. Even Niklaus Wirth in his Google Talk said that when he developed Pascal mainframe memory was in kilobytes and today we lack for no resources except developers, good developers. And that's why productivity is so important today.
      >If I'm paying you by the hour, I care. If I have to maintain the code you
      >wrote, I care. If a team using a more modern language can deliver the
      >product faster and hence cheaper, I care.

      > If you develop to code faster, you contradict mantainability.

      You're saying that if you're more productive, your code is hard to maintain? There's no logical correlation between those two things. I can code faster in Delphi than I code in assembler, but that doesn't make assembler easier to maintain. Remember Delphi's original market was RAD, or Rapid Application Development.

      > If I have to mantain code, verboseness is better than terseness.

      That also doesn't make sense. What that says is that it's easier to maintain more code than it is less code! Maintaining a million line program is not easier than a 100K line program.

      It's not easier to maintain this:

      WriteLn('1');
      WriteLn('2');
      WriteLn('3');
      Writeln('4');
      WriteLn('5');
      WriteLn('6');
      Writeln('7');
      WriteLn('8');
      Writeln('9');
      Writeln('10);

      than this:

      For x := 1 To 10 Do
      WriteLn(x);

      There's also less potential for mistakes and it's simpler to find the error.

      Delete
  6. And one more thing. Java even does not have anonymous methods and people live without it and write real world applications. Really, this feature madness must stop... EMB needs to make two steps back, fix what is broken and then move forward. Otherwise we have bugs build on top of other bugs.

    ReplyDelete
    Replies
    1. You are right!

      Delete
    2. Anonymous14:40

      Agreed!

      Delete
    3. Anonymous15:03

      And I thought I'm the only one who thinks so. If we were still missing stuff like generics, then yes. But the way the Delphi language is now: There are more important things to worry about ... in my opinion

      Delete
    4. Actually the Delphi implementation of anonymous methods is very similar to anonymous classes in Java (i.e. how they are used for events). So yes, Java has that feature and actually the syntax is even more verbose than the Delphi one (you should know that if you ever had a Java application with many event handlers)

      Delete
    5. Anonymous15:21

      @Soul Intruder: I absolutely agree! Stop this "with this syntax sugar Delphi would look more modern" nonsense.
      While I like inline variable declaration in some specific cases, there is nothing in your post that you can't do in current Delphi compiler. Maybe you will have to write more code, but there is nothing new, only syntax change.
      EMB should focus in fix what doesn't work today, and ADD new *real* features, things that will let us do what we can't do today, not syntax changes to save you a few keystrokes.
      IMHO, programming is not "who is able to create the shortest source code" contest.

      Delete
    6. I am not saying they should introduce more broken features that cause compiler errors or wrong code gen - no PLEASE fix those! But also focus on implementing things on the language/compiler level instead of throwing half baked frameworks that are brittle and super slow ontop of the existing language/compiler (LiveBindings anyone?)

      And no, it's not (only) about saving keystrokes (btw, why didn't you write "Embarcadero" and "in my honest opinion" but used abbreviations, it only saved you a few keystokes).

      Source code is more often read than written. And having to read less boilerplate code and get straight to the point of what is done actually saves time and money.

      So instead of reading a property with a setter and getter and having to navigate there or reading 4 lines (assuming you format an anonymous method like a regular one) just to see that it returns if a number is odd or not you just have to read what is necessary.

      Delete
    7. Anonymous18:21

      Totally agree! Missing language features are the least of Delphi's problems at the moment.

      Delete
    8. Unless we appeal to people younger than 40 we're going to die off. We can't continue to be so reactionary. The state of computer science has moved on from the 1970's and single pass compilers with obsessive static typing. If Delphi wants to be *relevant* it needs to address modern needs and concerns. Coming from a modern language into Delphi is like being asked to churn your own butter. From my end, looking out from Delphi to modern languages recently has been like leaving the cave and finding a world of flying cars and jet packs. ;-)

      >And one more thing. Java even does not have anonymous methods and people live
      >without it and write real world applications.

      Slowly. Incredibly slowly. And verbosely. The Spring platform was created to try to simplify the burgeoning verbosity of Java. Now people are saying Spring itself has become too verbose and unwieldy and are working on a framework on top of that framework to try to make it usable again. :-(

      I've written applications in COBOL (although I try to block that out of my mind). Steve Gibson used to write (and possibly still does) Windows GUI applications in pure assembly language (!!!). But if you do these things today, your output is going to be abysmal and you're going to be last to market and fail. The focus today is on making things easier and speeding development time/improving productivity.

      > Maybe you will have to write more code,

      Why do so many Delphi developers not care about writing more code? I know we got used to it with function overloading :-( and interface/implementation separation :-(, but how does that go over so easily today? If you write more code, you're slower than everyone else. Today it's far less important to be fast (almost everything is fast on today's hardware) than it is to be first. You're competing against dev teams in India that can afford to throw on three developers to your one. Any ability to code faster is a strategic advantage. We don't have the luxury of writing more code in today's modern, fast-paced world. As one article I was reading recently mentioned, "We could code this in a low-level language like C++ or Java, but who has time for that anymore?"

      >IMHO, programming is not "who is able to create the shortest source code"
      >contest.

      It is a who can code the quickest contest.
      From a brochure I was reading:

      >In the race for customers, the pole position belongs to those who
      >get to market faster than their competitors. Better and more creative
      >solutions combined with the ability to respond instantly to new
      >challenges drive the race. Writing secure and reliable programs in
      >a fraction of the time normally required gets you first across the
      >finish line.
      >Agility is the hallmark of our times....


      >Source code is more often read than written. And having to read less
      >boilerplate code and get straight to the point of what is done actually saves
      >time and money.

      I've been learning Python recently and tried re-writing some Delphi code of a dictionary with a custom object for the key from a Stack Overflow answer. Same logic, but it took only 1/4 (!!!) the non-whitespace characters to do it. Scale that up to a full project (and I've found the larger the test, the bigger the difference) and that translates to a HUGE time savings.



      Delete
    9. Anonymous15:07

      You won't appeal to younger people with just some syntactic tricks. Delphi is slowly dying because it became an inferior tool with a slow compiler (executable speed), few optimizations, slow IDE, bugs everywhere. Native applications are not fashionable now (but on some mobile devices), thereby do not expect Delphi will return to its glory days - ever - especially just adding some new ways to perform the same tasks, especially without understanding the whole implications in a compiled, low-level, language like Delphi.
      You can make it a Python look-alike, and people will keep on using Python and not Delphi, believe me. Delphi can be saved just being turned into a powerful and fast native compiler, not a script language wannabe.

      Delete
    10. >You won't appeal to younger people with just some syntactic tricks.

      That's just the thing. When we refer to the state of the art in computer science as "syntactic tricks", we sound like grandpa yelling at the kids to stay off his lawn. These "syntactic tricks" are expected in languages nowdays, just like power windows and air conditioning have become standard features on cars. If you don't have it, you're going to seem outdated.

      >Delphi is slowly dying because it became an inferior tool with a slow compiler
      >(executable speed),

      You're serious? Have you ever compiled C++ with GCC? Delphi's one of the fastest compilers out there.

      >few optimizations, slow IDE, bugs everywhere.

      Certainly the quality drives away the existing users, but it can't be what keeps people from trying it in the first place (they don't know about these things).

      > Native applications are not fashionable now (but on some mobile devices),
      >thereby do not expect Delphi will return to its glory days - ever -

      I think that relates back to the "syntactic tricks" - managed code has been able to add a lot of productivity-enhancing features. Just as assembly programmers ranted about compiled languages being inferior but we eventually moved to applications written in compiled languages and "stepping down" to assembler only for targeted optimizations, as hardware continues to become more powerful we'll probably see a move to very high level managed/interpreted languages with JIT and global static analysis and only step down to a compiled language to speed up small portions of the code if/where speed is critical. I don't think it's the fashion, I think it's the future.

      >You can make it a Python look-alike, and people will keep on using Python and
      >not Delphi, believe me. Delphi can be saved just being turned into a powerful
      >and fast native compiler, not a script language wannabe.

      And what will it have to offer over C++ or over new languages like Go or D, which are both compiled and filled with modern language constructs?

      Delete
  7. To everybody with the "you can do it in current Delphi" attitude I have only this to say - you can also do it in assembler.

    Programming languages are progressing so that we can focus on problem solving and not on typing and debugging.

    ReplyDelete
    Replies
    1. i am all for advancing the language, but as someone already pointed out, adding features which may be built on defective code is not exactly what I would call progress.

      Nick Hodges' comment about the footprint of the defect decreasing over time is basically a strategy for ignoring defects until users stop complaining about them. The reduced complaints doesn't mean the defect is of lower importance, only that a) we've learned how to work around it, or b) have moved to a different tool.

      Delete
  8. "anonymous storage": The clear distinction when you access a property and when you access its "local storage" is IMHO very important. Accessing a property may have side effects, and when looking at complex class hierarchies it's better to understand what is accessed and why.
    "inline variable": syntactioc sugar, maybe usuful to type sometimes faster, not so useful IMHO. And type inference is a good way to introduce obscure bugs.

    ReplyDelete
    Replies
    1. >"anonymous storage": The clear distinction when you access a property and when
      >you access its "local storage" is IMHO very important.

      There shouldn't even be a distinction. As some modern languages say, "getters and setters are evil" and shouldn't be used unless necessary. It falls under the "you're not going to need it" principle. You should just access the variable unless there's a reason to do otherwise. Being required to divide things up into variables and getters/setters is a waste of time and resources.

      >Accessing a property may have side effects, and when looking at complex class
      >hierarchies it's better to understand what is accessed and why.

      Being unnecessarily verbose won't improve clarity.

      >And type inference is a good way to introduce obscure bugs.

      Absolutely untrue. Type inference is completely deterministic and uses the Hindley-Milner algorithm which has been around since the 1980s. It embarrasses me when I see Delphi users rail against type inference (and you're not the only one). If a type can be inferred, it is. If it can't be, it's reported. There are no bugs from type inference and every statically typed language created this side of the 21st century mark that I've been able to find has incorporated it. Older languages are beginning to add it too. Other than being curmudgeonly, we have no reason not to embrace it.

      Delete
    2. kmorwath08:46

      Getter and setters are not evil at all and they are a powerful feature - you complain Delphi is lagging behind and then wish to remove powerful features it has? This mindset "other languages are always better" it's a very stupid attitude IMHO. There is a clear distinction between a property and a field, and Delphi does the right thing to show it to the developer.
      Type inference is deterministic, but the developer may be not. If you mistype something, type inference will work, your application may not. As other said, code is written once and read several times - all this "time savers" looks good for lazy developers who don't care much about the quality of their code, and just want to type at maximum speed. I don't care if I have to declare a variable of an exact type and size because I need it to be that, and nothing else. Because a mistake could be much more expensive than spending five more seconds to declare it.

      Delete
    3. >Getter and setters are not evil at all

      They are seldom necessary and sap productivity. Requiring everything to have getters and setters even when there's no custom processing of the value is just busywork.

      >Getters and setters are evil. Evil, evil, I say! ... Do not write getters and
      >setters. … And do not take that to mean that you should write getters and
      >setters, and then wrap them in 'property'. That means that until you prove that
      >you need anything more than a simple attribute access, don't write getters and
      >setters. They are a waste of CPU time, but more important, they are a waste of
      >programmer time. Not just for the people writing the code and tests, but for
      >the people who have to read and understand them as well.
      >
      >In Java, you have to use getters and setters because using public fields gives
      >you no opportunity to go back and change your mind later to using getters and
      >setters. So in Java, you might as well get the chore out of the way up front.
      >In Python, this is silly, because you can start with a normal attribute and
      >change your mind at any time, without affecting any clients of the class.
      -author Philip J. Eby

      > and they are a powerful feature - you complain Delphi is lagging behind and
      >then wish to remove powerful features it has?

      I wish to remove the silly requirement that they need to be used.

      >This mindset "other languages are always better" it's a very stupid attitude
      >IMHO.

      How about - languages that have kept up with the times and continue to grow are better? Or are more widely used and deployed? Nothing gets better by standing still. It's the attitude that old stuff was perfect and everything that came after was just fads and foibles that's harmful.

      >There is a clear distinction between a property and a field, and Delphi does
      >the right thing to show it to the developer.

      Not from the point of the user of the object.

      book.title - there's no distinction here. Delphi's requiring you to have a getter/setter for everything even when they're not doing anything; empty functions.

      >Type inference is deterministic, but the developer may be not. If you mistype
      >something, type inference will work, your application may not.

      Type inference chooses the simplest type that guarantees the variable can contain all of its values. If type inference is working how could something have been mistyped?

      >all this "time
      >savers" looks good for lazy developers who don't care much about the quality of
      >their code, and just want to type at maximum speed.

      Lazy people drive productivity gains. :-) You're essentially saying you don't care about productivity. You don't care that one language can do in 100K lines of code what another may take 1M lines of code to do.

      In a stack overflow problem that involved finding the min, max and avg of values in a TStringList, the Delphi implementation needed code like

      temps := TList.Create;

      For tempStr in temperatures Do
      temps.Add(StrToFloat(tempStr));

      minTemp := temps[0];
      maxTemp := temps[0];
      sumTemps := 0;

      For temp in temps Do
      Begin
      minTemp := Min(minTemp, temp);
      maxTemp := Max(maxTemp, temp);
      sumTemps := sumTemps + temp;
      End;

      avgTemp := sumTemps / numTemps;


      in Python, it would have been as easy as

      temps = [float(temp) for temp in temperatures]

      min_temp = min(temps)
      max_temp = max(temps)
      avg_temp = sum(temps)/len(temps)

      One didn't need to step down one's thinking into the realm of "algorithm". One was able to code exactly *what* one wanted without needing to change gears into thinking *how* it should be done. And it's that that not only makes modern languages more productive, it's what makes developers *happy* and to call certain languages *beautiful*.

      Delete
    4. >book.title - there's no distinction here. Delphi's requiring you to have a getter/setter for everything even when they're not doing anything; empty functions.

      Umm... what in the world are you talking about? Delphi does *not* require you to use getters and setters; you declare "title" as a property, which can be backed by the field (without methods to get or set the value) or by getters an setters if necessary.

      Also, your Delphi/Python comparison is invalid, because they aren't doing the same thing. The Delphi code iterates the list once; the Python code iterates four times! You claim that CPU time isn't expensive anymore, which is very self-serving for someone advocating inherently slower code, but the simple fact of the matter is that CPUs still have limits, and if your code runs slowly, your customers will complain about it. I know; I deal with such complaints on a regular basis, because our codebase wasn't originally written with the sort of scale in mind that it's being run against now!

      If you're only dealing with 5 or 10 temperatures, there won't be any noticeable difference, but if you have a million items, doing things four times more slowly is a serious concern, and if you were to write it to do all these computations in a single pass, it wouldn't end up significantly shorter than the Delphi code because it would have to be done pretty much the same way.

      And that's the dirty little secret of these cutesy "Python is less verbose than Delphi" comparisons: it really isn't. It's not doing the same work, and it's mostly just sweeping the complexity under the rug by moving stuff off into library functions, whereas Delphi coders prefer to have information about what's going on actually available.

      Delete
    5. >Also, your Delphi/Python comparison is invalid, because they aren't doing the same
      >thing.

      I wrote both programs; I'm fairly certain they're doing the same thing. :-)

      >The Delphi code iterates the list once; the Python code iterates four times!

      Actually the Delphi code iterates twice (once to convert the strings to a list of real numbers, the next to compute the statistics). But that's a difference in implementation; the programs are still doing the same thing. From the perspective of the person writing the code, I never needed to explicitly iterate the list at all.

      And how does any of this make the comparison "invalid"? The comparison was that it was simple and straightforward to write one, while I had to create an algorithm for the other because the same level of functionality wasn't present in its list collection object. That point still stands.

      >You claim that CPU time isn't expensive anymore, which is very self-serving for someone
      >advocating inherently slower code, but the simple fact of the matter is that CPUs still
      >have limits, and if your code runs slowly, your customers will complain about it.

      The question is always, does it run *fast enough*.

      >If you're only dealing with 5 or 10 temperatures, there won't be any noticeable difference,
      >but if you have a million items, doing things four times more slowly is a serious concern,
      >and if you were to write it to do all these computations in a single pass, it wouldn't end
      >up significantly shorter than the Delphi code because it would have to be done pretty
      >much the same way.

      1. Anything may need to be changed at sufficiently large a scale.
      2. There are lots of options that could be used, including sorting the list and using the first and last item. Another interesting idea would involve a magic method that is called when a variable of an object is set (and everything's an object in python). Add two properties to store the min and max, then override the set magic method. If the value to be added is greater than the max or less than the min, set the new properties accordingly, then call the original method. Now, instead of using the min or max functions, simply access the min and max properties on the list, and you won't have to iterate the list at all to get the values! :-)

      >And that's the dirty little secret of these cutesy "Python is less verbose than Delphi"
      >comparisons: it really isn't.

      You keep claiming this all over the internet, but then you never actually show code that proves your point.

      >It's not doing the same work,

      Come on. You're smarter than that. It takes the same values and gives the same answers. To claim anything different is to try to engage in semantic trickery.

      >and it's mostly just sweeping the complexity under the rug

      Sigh. Mason, that's what every framework in existence and every language outside of machine code does - takes burden off of the developer. No one says programming in Delphi isn't any shorter than programming in assembly because it's just "sweeping the complexity under the rug".

      > by moving stuff off into library functions, whereas Delphi coders prefer to have
      >information about what's going on actually available.

      1. Delphi is a proprietary language. We don't have more information about what's going on than any open source language.
      2. Delphi developers don't prefer to do more work. If we did, we wouldn't be using a RAD tool with the original selling point of being easier to develop Windows programs than C++ and MFC because it abstracted away Win32 with VCL. This argument of yours simply isn't credible.

      Delete
  9. Anonymous16:34

    @Gabr: When you use this kind of "you can also do it in assembler" (BTW, the language is named assembly, not assembler http://en.wikipedia.org/wiki/Assembly_language), you start to loose your argument.
    What defines productivity in programming is not how many keystrokes are required to write a program, but include a huge number of factors.
    I'm not less productive because of 5-10% more chars in my source code. As someone have pointed, the same source code is written only ONCE and probably will be read/debugged HUNDREDS of times during its production cycle. Sometimes, a more verbose source code is easier to read and understand, and then, you may be MORE productive, not less. The idea "less code" == "get straight to the point" == "more productivity" is just absurd. If so, I may present you a superb, very well written C program, right?

    #define _ -F<00||--F-OO--;
    int F=00,OO=00;main(){F_OO();printf("%1.3f\n",4.*-F/OO/OO);}F_OO()
    {

    EMB guys should use their time to create NEW things allowing us to do things we could NEVER do before, not even using 1 zillion keystrokes.

    ReplyDelete
    Replies
    1. Long lambdas are anyway a debugging nightmare. Just wrong use for them, IMHO.

      Lambdas rock when they are oneliners. Even if they are just bridges, just calling some named procedure.

      However for those atomic lambdas the boilerplate is not "5-10% more chars" but "100%-200% more chars" and in that situation that makes them HARDER to read, not easier.

      Delete
    2. Anonymous18:13

      5-10% more chars in the final source code of the WHOLE program, at most, being very pessimistic. I doubt that even implementing all the suggested features in this blog post, one can decrease more than 1-2% in the final source code size.
      Or 100% of your source code is based on lambdas? If so, I'm very sorry for you! ;-)

      Delete
    3. >@Gabr: When you use this kind of "you can also do it in assembler" you start
      >to loose your argument.

      It seemed like a checkmate me to counter an invalid rebuttal.

      >What defines productivity in programming is not how many keystrokes are
      >required to write a program, but include a huge number of factors.

      With a strong correlation with keystrokes. The "scripting" languages don't excel at productivity by being more verbose than Java.

      >I'm not less productive because of 5-10% more chars in my source code.

      Yes, you're 5%-10% less productive minimum.

      > As someone have pointed, the same source code is written only ONCE and
      >probably will be read/debugged HUNDREDS of times during its production cycle.
      >Sometimes, a more verbose source code is easier to read and understand,

      Only if the other source code is terse to the point of obscurity like regex or really bad PERL (which are often the same thing). Outside of that extreme, clarity comes from simplicity of expression, not from the Begins and Ends and duplication of class procedure and function headers and pedantic listing of types that categorize Delphi today. It's boilerplate that masks the clear intent of the code.

      > and then, you may be MORE productive, not less.

      Given that none of the languages considered the most productive are the most verbose, this argument is based on hypotheticals that have no bearing on reality.

      >The idea "less code" == "get straight to the point" == "more productivity" is
      >just absurd.

      Tell that to Python, with its nickname of "executable pseudocode" and one of the most productive languages in existence today. The "absurdity" you claim is part of the CORE DESIGN PRINCIPLES of Python. They've codified those principles into the "Zen Of Python":

      The Zen of Python, by Tim Peters

      Beautiful is better than ugly.
      Explicit is better than implicit.
      Simple is better than complex.
      Complex is better than complicated.
      Flat is better than nested.
      Sparse is better than dense.
      Readability counts.
      Special cases aren't special enough to break the rules.
      Although practicality beats purity.
      Errors should never pass silently.
      Unless explicitly silenced.
      In the face of ambiguity, refuse the temptation to guess.
      There should be one-- and preferably only one --obvious way to do it.
      Although that way may not be obvious at first unless you're Dutch.
      Now is better than never.
      Although never is often better than *right* now.
      If the implementation is hard to explain, it's a bad idea.
      If the implementation is easy to explain, it may be a good idea.
      Namespaces are one honking great idea -- let's do more of those!

      > If so, I may present you a superb, very well written C program, right?

      >#define _ -F<00||--F-OO--;
      >int F=00,OO=00;main(){F_OO();printf("%1.3f\n",4.*-F/OO/OO);}F_OO()

      Do you want me to share 21-line Delphi programs rewritten in 5 lines of Python?


      >EMB guys should use their time to create NEW things allowing us to do things we
      >could NEVER do before,

      Let's be honest. Delphi lost its leading edge status many, many years ago. Let's be more honest: while the VCL was state-of-the-art, nothing in the Delphi language was _ever_ considered cutting edge and borrowed by other languages. The people who can create things we've never seen before are not going to work for Embarcadero. They're going to work at Google or Microsoft or Apple or academia or contribute to open source for fame and glory. EMBT is down to a small handful of developers responsible for the language, the IDE, and TWO frameworks across multiple platforms. Interbase is supposed to be down to one developer! We're just not going to see cutting edge stuff from them because they don't have enough people to adequately accomplish what's on their roadmap now (think FM1). Digia has almost ten times the people just working on Qt than EMBT has working on all of Delphi!

      Delete
    4. John Jacobson19:53

      "Yes, you're 5%-10% less productive minimum."

      Definitely false. Increasing the number of characters you type by 5-10% has no appreciable effect on developer productivity. None.

      The reason for this is that typing speed is not a significant part of coding efficiency, and coding efficiency is hardly significant as a component of software development efficiency. Efficiency in the production of software depends mostly on things like the availability of QA resources, the methodology chosen, how much distraction exists in the cubical farm, what people already know versus what they have to learn from scratch, the size of the team, the quality of the communication, the 10-100 times difference in individual programmer productivity, and so on. The speed with which a dev can type code is nothing compared to all this. Nothing.

      Delete
    5. >Definitely false. Increasing the number of characters you type by 5-10% has no
      >appreciable effect on developer productivity. None.

      We're not just talking character increase like larger variable names. These character increases are coming about from extra steps involved. They come about when things can't be done at a high level and one needs to drop to a lower, algorithmic level. This involves a transition in thinking that interrupts the train of thought.

      >The speed with which a dev can type code is nothing compared to all this.
      >Nothing.

      It's not typing speed; it's what's being typed. Extra boilerplate code is more work which slows down and complicates development and maintenance.

      Bruce Eckel, author of the bestselling Thinking in Java and Thinking in C++, caused a stir when he declared that "I love Python!". From an interview....

      ----
      Bill Venners: In your "Why I Love Python" keynote, you gave ten reasons you love Python. Number three was: "I don't have to type so much." To what extent do you think the productivity gain you get with Python, which you said was 5 to 10 times over Java, is just from reduced finger typing?

      Bruce Eckel: I don't think the productivity comes from the finger typing so much, although that is certainly part of it. The main sources of productivity are that I am able to look at more lines of code on the screen, put more meaning into fewer lines of code, read and understand code more easily, and deal with higher level concepts. Also, Python comes with "batteries included," which means a large quantity of library functions come with the standard Python download.

      Finger typing is clearly oversimplifying all that, but nevertheless, finger typing is the root of it all. In Python I can type fewer words to express my meaning. The reduced typing has something to do with the productivity increase I see when using Python, but more productivity probably comes because I have to think less hard to do what I'm doing.

      ....

      Bruce Eckel: They say you can hold seven plus or minus two pieces of information in your mind. I can't remember how to open files in Java. I've written chapters on it. I've done it a bunch of times, but it's too many steps. And when I actually analyze it, I realize these are just silly design decisions that they made.... Because we open files all the time, but nobody can remember how. It is too much information to hold in your mind.

      The other issue is the effect of an interruption. If you are really deep into doing something and you have an interruption, it's quite a number of minutes before you can get back into that deeply focused state. With programming, imagine you're flowing along. You're thinking, "I know this, and I know this, and I know this," and you are putting things together. And then all of a sudden you run into something like, "I have to open a file and read in the lines." All the clutter in the code you have to write to do that in Java can interrupt the flow of your work.

      Another number that used to be bandied about is that programmers can produce an average of ten working lines of code per day. Say I open up a file and read in all the lines. In Java, I've probably already used up my ten working lines of code for that day.....

      Delete
  10. C++ lambda has a choice which variables to capture and which not.
    http://www.cprogramming.com/c++11/c++11-lambda-closures.html

    Does SMS pascal offer this choice or it captures every used var that is non-parameter?

    PS: while generally i dislike C++, their lambda syntax rocks.
    I even tried to argue for it on FPC list, but the guys seemed to only implement generics syntax for Delphi compatibility and do not care for anything else. They seem to prefer templates to generics...

    ReplyDelete
    Replies
    1. DWScript either captures everything or nothing.

      Those will all compile:

      // TMouseClickEvent = procedure(Sender: TObject);
      W3Button1.OnClick := lambda end;
      W3Button1.OnClick := lambda(Sender) end;

      // TMouseEvent = procedure(Sender: TObject; Shift: TShiftState; X, Y: Integer);
      W3Button1.OnMouseMove := lambda end;
      W3Button1.OnMouseMove := lambda(Sender, Shift, X, Y) end;

      Those, however, will not:

      W3Button1.OnMouseMove := lambda(Sender) end;
      W3Button1.OnMouseMove := lambda(Sender, Shift) end;

      Delete
  11. "true conditional operator" Could as well be made a generic inline function IfThen - if only Delphi had working type inference...

    ReplyDelete
    Replies
    1. No, because a function would be required to eval both the "then" and the "else" parameters every time, unless you also introduce lazy parameters (which DWScript support btw).

      Delete
  12. John Jacobson18:15

    Yawn. I see nothing worth bothering about in that syntactic candy.

    First of all, if you really don't like typing property accessor code, get a third-party tool like ModelMaker's CodeExplorer that does it for you. That's a lot faster than learning yet another syntax.

    Second, I find that notation for lambda expressions unreadable. That is because I come from Java and C++ and Delphi. If I was maintaining code that had that notation in it, I would have to do a full stop to what I was doing and read up on it. Time lost, not saved.

    Third, we don't need this kind of useless syntactic crap. It is a waste of time. More time spent learning it than it would save in use. If you want to talk about useful syntax changes, talk about ones that will make multi-threaded code easier to write and more robust, and will propagate exceptions across thread boundaries, for example. Or syntax that will let me easily do things that are necessary but hard, like stream any object across process and geographical boundaries. And so on.

    The last thing this world needs is more syntactic variations on the same old themes.

    ReplyDelete
    Replies
    1. > get a
      >third-party tool like ModelMaker's CodeExplorer that does it for you. That's a
      >lot faster than learning yet another syntax.

      That's not going to make the code more readable, only cut down on the typing. Java IDEs insert a lot of the boilerplate getter/setter code for them, but that does nothing to streamline the code itself.

      >Second, I find that notation for lambda expressions unreadable.... If I was
      >maintaining code that had that
      >notation in it, I would have to do a full stop to what I was doing and read up on
      >it.

      Um, if you were coding in the language, you should already have read up on it. I don't follow this argument at all. And what's there to read up on? It's in line with other languages' lambda syntax. I've never seen this before and I knew exactly what it was. The left side is what's passed in, the right side's what's returned.

      >Third, we don't need this kind of useless syntactic crap.

      "We" is shrinking by the day. If we want the language to continue to exist after we all retire or die off, we have to represent the state of the art in computer science, not the 1970s.

      >It is a waste of time. More time spent learning it than it would save in use.

      And yet it's present in almost every modern language today, including the ones much more popular than Delphi. Do you think that's likely... that almost every single other language somehow missed the fact that this construct doesn't help, yet one lone Delphi developer has realized that we're better off without it? Is that the most likely explanation or the least likely explanation?

      >If you want to talk about useful syntax changes, talk about ones that will make
      >multi-threaded code easier to write and more robust, and will propagate
      >exceptions across thread boundaries, for example. Or syntax that will let me
      >easily do things that are necessary but hard, like stream any object across
      >process and geographical boundaries. And so on.

      If we can't even get lambdas, present in most other languages, we're never going to get those, which are still hard to do in many languages.

      >The last thing this world needs is more syntactic variations on the same old
      >themes.

      Let's say we have an object that includes the properties "name" and "age". Then let's assume we have a list of such objects and now I want that list sorted in alphabetical order. This is all I have to do in Python thanks to 1) Key sorting like SQL rather than custom comparator sorting like Delphi, and 2) the lambdas you believe are just syntactic variations.

      Here's how to do sort the list (called people):

      new_list = sorted(people, key=lambda person: person.name)

      That's it! The key will be applied to each element in the list. The lambda then takes one of our objects, assigned to "person", and returns the name in that object. The sorted routine then uses the regular comparison capabilities of that return type to do the sorting, no custom comparator needed (being simpler and shorter 99/100 times). A lot quicker, easier, and simpler than writing a full-on Delphi-style anonymous method, right?

      The min and max functions also take an optional key parameter. Want the youngest person?

      youngest = min(people, key=lambda person: person.age)

      I believe you're very mistaken about lambdas being unnecessary, or not saving time. Perhaps part of the problem is because since Delphi doesn't have them, it's standard library isn't designed to take advantage of them. If they were added and the incredibly unlikely event happened that the standard library were refactored to take advantage of lambdas (and optional parameters and generics and all the other things it doesn't use now) you'd see a lot of time savings. Python has spent a lot of time refactoring its libary after adding lambdas, iteration and such and the results really show.

      Delete
    2. John Jacobson19:58

      "I believe you're very mistaken about lambdas being unnecessary, or not saving time."

      I never said lambdas aren't useful. Not sure where you got THAT idea. I find lambdas very useful in multi-threading background tasks. What I said was that the difference in notation did not do much.

      Delete
  13. Peter VonĨa19:27

    I agree with Gabr, the code functionalities listed in this blog post are good examples of how code programming in Delphi should continue evolving.

    In my humble opinion,
    anyone who is against adding such functionalities is clearly living under a large rock. Programming languages are constantly evolving to increase developers productivity as well as efficiency.

    People who are against such improvements to the Delphi language should take solace in the fact that even if such functionalities are ever added you will not be forced to use them, in fact I'm quite positive that despite any progress that Delphi makes you'll still be able to gut your time inefficiently the same way you have done up to now.







    ReplyDelete
    Replies
    1. Anonymous20:19

      @Peter: You are confusing "against it" with "give it little priority". I'm not against new or extended syntax for Delphi object pascal dialect, but given limited resources, this is BELOW LOW priority in my book.
      Do you think that Allen Bauer and his team should spend their *limited* time adding syntax sugar to the language? I think not. In my list, I can think of at least one dozen things that should be done first: Bug fixing, better/faster RTL core routines, better multithreading, fix web services support, fix DataSnap issues, etc. etc. etc.
      I really would not like to know that EMB is putting new lambda syntax above bug fixing in their priority list. That's it, and I really don't believe that one of you may think the contrary.

      Delete
    2. John Jacobson01:10

      "People who are against such improvements to the Delphi language should take solace in the fact that even if such functionalities are ever added you will not be forced to use them"

      Utter nonsense. If I made my living off Delphi, I would eventually have to support and maintain code written by some code monkey who thought these things were the greatest thing since sliced bread, were they added to the language. So of course I would have to use them.


      In fact, I have to wonder how any professional non-hobbyist could even say such a thing with a straight face. Don't you ever maintain code written by someone else? How much control did you have over those predecessors?

      Delete
    3. John Jacobson01:31

      "Do you think that Allen Bauer and his team should spend their *limited* time adding syntax sugar to the language? I think not."

      That's the wisest thing I've seen in this whole thread. Ultimately, "efficiency" in coding is nearly irrelevant to the economics of software development. To have any appreciable effect on the financial bottom line, a change in coding efficiency would have to be several orders of magnitude. I haven't seen anything that effective since the invention of the integrated debugger, and in any event the syntactic sugar discussed in this thread isn't going to produce such a change.

      I'm pretty sure that if you were to poll Delphi developers and prospective Delphi developers, they would have a long list of things they would rather have done with Embarcadero's limited resources than these language changes. I, for one, would like to see Linux support added. And as many have pointed out, bug fixing would be great. It doesn't fill me with a warm fuzzy feeling that if I double-click on a newly dropped component on an FMX form that I get an error saying it can not find the method it is supposed to be adding in the first place.

      Delete
    4. >. I'm not against new or extended syntax for Delphi object pascal dialect, but
      >given limited resources, this is BELOW LOW priority in my book.

      It's actually the second-most important thing after quality improvement in mine. The simple reality is that no one cares about Delphi who isn't already a Delphi programmer. It's fading into irrelevancy. All this hype about cross-platform and if they get users to try Delphi it's going to feel like they're stepping back in time. It'll feel "weird" to them (like braces feel to many of us) and they'll look for something more familiar.

      >Do you think that Allen Bauer and his team should spend their *limited* time
      >adding syntax sugar to the language?

      I think they should spend time cleaning house from top to bottom, modernizing the language and completely house-cleaning the RTL (some areas of which have not been touched since Turbo Pascal).

      >Bug fixing,

      Management doesn't believe this earns them money so it won't happen.

      >better/faster RTL core routines,

      I think we have to get off of "faster".

      >better multithreading, fix web services support, fix DataSnap issues, etc. etc.

      No one uses Datasnap (or shouldn't be) and Delphi is a dead-end for web services. It's never going to catch up to C#/ASP.NET or Ruby/Rails or Python/Jango or PHP/whatever.

      >I really would not like to know that EMB is putting new lambda syntax above bug
      >fixing in their priority list.

      I think everything is above bug fixing in their priority list. :-( PYTHON beats Delphi in Regex parsing(!!!), a bug was filed, the forum found the cause and even submitted the fix. One year later, bug is still open.


      Delete
    5. >Ultimately, "efficiency" in coding is nearly irrelevant to the economics of
      >software development.

      Seriously? If one team takes six months to code a project and another takes three, that's a huge cost savings. Sometimes I don't understand Delphi developers... and I've been one for quite some time. :-)

      Honestly I think we have "sour grapes" at anything we can't do (or do better), and over the years that's become quite a lot of things and we start to sound silly after a while in our defense.

      >To have any appreciable effect on the financial bottom line, a change in coding
      >efficiency would have to be several orders of magnitude.

      I'd love to see you put some hard numbers to that claim. I used to work at the HQ of a billion-dollar U.S. retailer with lots of "B"s in its name. One project involved developing changes to the store restocking system. If department A was ordering on day 1 and B on day 2 yet one company sold both items (happening a lot with consolidation) that would mean two shipments instead of one. By analyzing our data and figuring out which orders to consolidate and when, we determined it would save more than one million dollars a year. Essentially, for every week it took to make the changes, that was over $20K in unnecessary expenses. $4000 every additional business day. With most business problems, speed is not only a factor, but the overriding one.

      >I haven't seen anything that effective since the invention of the integrated
      >debugger,

      I have and you should have too. It's called "Python", and thats its whole selling point, being several times more efficient than C++ and in some cases ten(!!!) times more productive than Java. I'd add that dynamic typing alone in controlled computer science studies has been shown to lead to 50% faster development times in experiments with no change in accuracy (in one experiment dynamic typing had the speed gain and subjects also spent less time debugging!).

      >and in any event the syntactic sugar discussed in this thread isn't going to
      >produce such a change.

      It's NOT just the keystrokes. Every single time your mind has to drop out of big picture mode and step down to the algorithm mode, that's a loss as it takes the human mind several minutes to shift gears. It also adds to testing woes ("every line of code not written is guaranteed to be 100% correct"). There's a lot of literature about this very subject.

      >I'm pretty sure that if you were to poll Delphi developers

      A large subset of Delphi developers are stuck in their ways and don't want anything to change. Some on the forums brag about using PChar instead of String!!!

      > and prospective Delphi developers

      This poll effectively exists - the degree to which Delphi has become unknown. That people aren't interested in it speaks volumes. People want to actually ENJOY their language, to find BEAUTY in it... to be HAPPY. Ugly long-winded code does not win hearts even if it wins minds, and happy programmers are more productive.

      >I, for one, would like to see Linux support added.

      As I'm writing this on Linux right now, trust me I sympathize. But the big picture is that unless the language starts appealing to new blood, it's doomed. That's got to be job one.

      Delete
    6. John Jacobson20:11

      "I have and you should have too. It's called "Python", and thats its whole selling point, being several times more efficient than C++ and in some cases ten(!!!) times more productive than Java."

      You say, with a straight face, that a product that took a software development firm 10 months to do in Java is going to get done in one if they use Python? All the planning and design meetings are going to instantly shrink from 60 minutes to 6? All the SCRUM stand-ups are going to shrink from 10 minutes to one? All the discussion between developers about how to find the domain knowledge they need to know will shrink from 15 minutes to 1.5 minutes? All the reading of Wiki how-to documents about setting up the servers will shrink from a 30 minute effort to a 3 minute effort? All the logging of progress in tracking tools like Rally, all the email reading, etc. will suddenly take less time? Wow, Python must be violating the laws of physics to get all this done.

      Delete
    7. >You say, with a straight face, that a product that took a software development
      >firm 10 months to do in Java is going to get done in one if they use Python?

      The cases of this are numerous and well-documented, and when I researched the state of programming languages for start-ups I had the opportunity to interview some of the people behind them, so yes, very straight face.

      >All the planning and design meetings are going to instantly shrink from 60
      >minutes to 6?

      Honestly you're simply not going to need all those planning and design meetings in the first place given the language's focus on productivity removes a lot of the complications that lead to the need for those meetings in the first place.

      >All the logging of progress in tracking tools like Rally, all the email
      >reading, etc. will suddenly take less time?

      If one developer is as productive as ten, then all that e-mail goes away too.

      >Wow, Python must be violating the laws of physics to get all this done.

      No, it's just designed, I am sad to say, much, much better than Delphi and has had the same chief architect behind it for 22 years. For example, Delphi's up to six different ways to open a file (much more if you count the reading and writing variants of streams as separate methods). Python still has one function, "open", after 22 years, capable of doing everything all those Delphi methods do.

      Here's a good quote from Thanos Vassilakis, then a programmer for NYSE


      -----
      On the New York Stock Exchange we use three languages in production to deliver serious trading services to the Specialists: c, C++, Python.

      Perl, tcl/tk, Java are used but for scripting, tools, and minor services where performance and memory foot print are not an issue. Yes, used correctly Python meets our performance, security and reliability requirements.

      We have had Java projects and launched Java services, they have all failed. We have many in the pipeline (thanks Big Blue) but NYSE's only serious internet based service is written in Python, and was launched in 1998. It is still up in it's sixth version, with no down time! The fifth version was rewritten in Java, 6 months overdue, failed, and replaced by python ( which took two weeks).

      Here at SIAC and NYSE Python is recognized by management to give results that other languages just can't achieve.

      For performance we have extended Python with our own specialized c objects, and we have used swig extensively to integrate to our legacy code, and middleware.

      Thanks Python, you let me get home to my kids.
      ------

      Plenty more where that came from too. If you're missing out on what the modern crop of productivity-enhanced languages can do for you (or spending more time in meetings than coding) you owe it to yourself to check them out.

      "Python is fast enough for our site and allows us to produce maintainable features in record times, with a minimum of developers," said Cuong Do, Software Architect, YouTube.com.


      Delete
    8. @Peter VonĨa - no Peter we are not living under the rock. Most of us are aware and\or coding in other languages. We know what other languages have to offer. However we also know what we want from Delphi. We prefer speed, stability and usefulness over new so called "features".

      Delete
    9. Peter VonĨa10:25

      @ Soul Intruder, I never said that I would prefer EMBR to work on such features over improvements made to the IDE speed,stability etc... If you came to that conclusion then I'm sorry to hear that.

      Delete
  14. Anonymous20:53

    I agree with John Jacobson, you have the same functionality, which you dont even need to type because the Editor will do it for you, you are also saving very few lines of code which. All that is time I will prefer being spend on fixing some bugs and getting more new features.

    For example, LiveBindings, it is an amazing thing, and I'm glad we finally got it. It needs to be improved but just like everything, the next version will get it better.

    I will not get more money by saying that I have an easier way to code a lambda expression, but I will definitely do if I can present to my customer a client on Android.

    ReplyDelete
  15. John Jacobson01:14

    "I'm quite positive that despite any progress that Delphi makes you'll still be able to gut your time inefficiently the same way you have done up to now."

    If you are inefficient right now when using Delphi, because it doesn't have these features, then you are doing it wrong.

    In fact, if you are inefficient using Java or C++, without these features, you are doing those wrong too.

    ReplyDelete
    Replies
    1. I don't follow. In a scientific test of non-trivial test problems, those using "scripting" languages were able to complete the problems in half the time of those using non-scripting (C++, Java) languages with no statistically significant difference in error rate. However, the performance results for some languages were very telling. Python has as one of its tenets "There should be one - and preferably only one - obviously way in which to do it". The Python programs had results that were very bunched together with little difference in performance. You could say it's hard to write a bad program in Python. C++ on the other hand had both the best and worst performing final programs with the remaining results spread fairly evenly all across the board. This speaks to C++'s use of many ways to do the same thing and especially its myriad exceptions to rules.

      Don't try to put language efficiency on good/poor programmers. Language design and philosophy contributes mightily to language efficiency, and Delphi lacks a lot of what computer science has decided is efficient.

      I took the best-of-class answer for a sorting problem in Delphi from Stack Overflow (21 lines) and re-wrote it in 5 or 6 lines of Python without ever actually even having read a book about Python. The Delphi programmer was doing it "right". The language simply lacked the constructs I used (particularly advanced slice notation and key-based sorting) to do it more efficiently. In fact, part of the reason the Delphi answer was as long as it was was because after 18 years, Delphi *still lacks a step function for its for loop*. Given the sorting problem needed to interweave results, e.g. [6, 1, 5, 2, 4, 3] the inability to step by two was a killer to algorithm efficiency and simplicity. With advanced slice notation I was able to write the algorithm **with no for loop at all**, even as a python neophyte.

      Most languages today are Turing-complete. What separates the slow and inefficient from the fast and efficient are indeed these design decisions and features which you're dismissing. If it was just about doing it right vs. wrong, we could all be coding in assembly with the productivity of Ruby or Python.

      Delete
    2. John - further your earlier comment:

      "if I double-click on a newly dropped component on an FMX form that I get an error saying it can not find the method it is supposed to be adding in the first place."

      I had a similar issue, and found it was actually caused by ModelMaker Code Explorer, and you need to turn off the Alternative Win 32 Object Inspector Method Property Editor. Not sure if you're an MMX User, but worth a try if so...

      Richard

      Delete
    3. John Jacobson20:22

      alcalde, you keep missing the point. In the grand overall sphere of complete software development, the "efficiency" of the language used by devs is such a small percentage of the total time (I estimate roughly 5% or less) used to produce a software product that it is basically irrelevant. Your example of devs in a "scientific test" using different languages to solve specific problems is not even remotely related to the real world of actual software development, where servers must be set up, dev environments get munged, domain knowledge must be located and assimilated, etc.

      Delete
    4. kmorwath09:00

      I don't understand why you don't ditch Delphi and switch to Python then, instead of trying to turn Delphi into Python.
      Anyway writing a real-world application is very different from writing some test. BTW those test reminds me of those published about Java almost twenty years ago. Java was the best and would have taken the world, Java OS, Java chips, whatever. Java didn't go that far, and now it's almost "legacy". In a few year Python & C. will be the same (Ruby is already, no more hype as a few years ago), while there will be some new kid on the block that will get all the headlines. Meanwhile C/C++ will be still used to write operating systems and high-end applications...

      Delete
    5. Anonymous12:58

      Given that Mr. Alcade here is the most active reader and contributor of that Delphi hater blog nothing he writes here surprises me... ;-)

      Delete
    6. Anonymous01:59

      @Alcade: Interesting. Multi-threading in Python is a JOKE compared to anything native - including Delphi, or even Java. Global interpreter lock? You must be kidding me! Indentation instead of some {} or begin/end is stupid! Most Python users complain about it. Python performance is a far behind many many other languages. So... I guess you may have LOTS of experience interviewing Python pseudo-users but no real programming experience. Unless you have only used Python in your whole life, so you have no base for comparison!

      Delete
    7. >I don't understand why you don't ditch Delphi and switch to Python then, instead
      >of trying to turn Delphi into Python.

      A lot of the world already did... although a lot more switched to C#. C# has Anders, and one of the inspirations for the formation of Python was Niklaus Wirth's writings on developing Modula-2. If we want the language to continue to exist, it needs to compete in a world where almost every language is non-proprietary and often free. Delphi's going to need to turn into something. As is there's zero info on EMBT's website comparing Delphi to any other product. Unlike in 1995, we don't have any "killer features" anymore. BASIC didn't say "don't turn us into Pascal" when the GOTO wars were over. Structured programming won, BASIC dropped its line numbers and embraced subroutines, and because of that it survived to this day. If it kept the line numbers it would be dead. We're going to have to do the same thing with variable declaration and several other areas if want to be relevant.

      >...and now [Java's] almost "legacy"

      What planet is this where Java isn't a mighty force, from Enterprise servers to Android apps?

      >In a few year Python & C. will be the same

      Python dominates in science, dominates in data analysis/financial applications/etc., is a big force in web development and is EVERYWHERE in embedded scripting. Both of the major cloud service platforms are written in Python. It continues to grow and evolve, necessary to maintain relevancy. DARPA just awarded a $3 million dollar grant to improve the major scientific and data processing third party libraries of Python because they believe it's their best choice going forward for analyzing vast amounts of sensor and satellite data. In two years PyCon went from 1100 attendees to 2000 and this year sold out six weeks early at 2500, a new PyData conference was started, and there are many more conferences (SciPy, EuroPyCon, etc.) There are a great deal of books about Python (Amazon shows 7 books directly related to Python published in just the last 30 days!). The Raspberry Pi chose Python as their official language and it's the language for MIT's intro to conputer science. Everyone from Amazon, Google, YouTube, HP, Dropbox and Microsoft to Lucasfilm and Disney Studios sponsored PyCon 2013. PyVideo.org, which acts as a central search for videos of Python presentations, currently indexes 1824 videos since 2010 (!) and the Python Package Index has over 34,000 open source libraries available. There's no reason to believe that Python is going to disappear in a few years.

      C - people are looking for the new C. "Go" has a shot at this, with the idea being "what would C look like if we were designing it today". That makes my case - Delphi ought to be "what would Delphi look like if we were designing it today" before some other language does so. C or Delphi, people want modern, relevant features.

      > (Ruby is already, no more hype as a few years ago),

      Ruby wasn't very popular until Rails appeared. Now there's still not much use of Ruby outside of web development, and Python was able to beat it to the punch with scientific and mathematic libraries and win over those fields.

      >Meanwhile C/C++ will be still used to write operating systems and high-end
      >applications...

      C++ never won hearts even if it won over managers. It doesn't have a "fan base"/community (nor does C). "D", with its motto "C++ done right" has a chance at becoming the new C++ if it can get its act together with its standard library. C++ has become so unwieldy that we get book titles now like "C++ - The Good Parts" and organizations mandating that only a subset of C++'s features be used. The Enterprise is starting to realize both C++ and Java are becoming unwieldy.

      Delete
    8. >Given that Mr. Alcade here is the most active reader and contributor of that
      >Delphi hater blog nothing he writes here surprises me... ;-)

      I've never contributed anything to The Delphi Haters website. I have commented on it. Since most posts seem to get 0-3 comments total, I think that's not a very accurate metric to use to label me "the most active reader".

      When I did a major review of programming languages for two startups in 2012 to choose their software stacks, I was very disappointed to see that the language I used so successfully at a startup from 1995-2003 had fallen so far behind. Then I got mad that so much potential had been squandered and the language was in the shape it was in. Don't blame the messenger; I'd hoped the truth would have been something different. As Bruce Eckel said,

      >I feel Python was designed for the person who is actually doing the
      >programming, to maximize their productivity. And that just makes me feel warm
      >and fuzzy all over. I feel nobody is going to be telling me, "Oh yeah, you have
      >to jump through all these hoops for one reason or another." When you have the
      >experience of really being able to be as productive as possible, then you start
      >to get pissed off at other languages. You think, "Gee, I've been wasting my
      >time with these other languages."

      Once upon a time Delphi was the tool to use to get to market fast and first and it ran circles around C++/MFC on the one hand and VB or Access on the other (I called Delphi and Crystal Reports my "Access Killer"). Now Delphi is far less productive than some other languages (but not as bad as C++ or heaven help me Java) and that's a real shame. And it hurts to see that people want to defend its lapses or faults rather than loving it enough to want to improve them and make it better. :-(


      >Alcade: Interesting. Multi-threading in Python is a JOKE compared to anything
      >native -

      This came out of nowhere. Who was talking about multi-threading? If you want to have that discussion, pick another venue for us than this Delphi blog as that has nothing to do with Delphi.

      >Global interpreter lock? You must be kidding me!

      Mason Wheeler tried that on EMBT forums and it did not turn out well for him.

      >Indentation instead of some {} or begin/end is stupid!

      That's telling me! ;-) Really the sour grapes are getting silly. Oh, and making it impossible for indentation to lie to you is not silly. C has to be run through a "prettifier" before checking for just that reason.

      >Python performance is a far behind many many other languages.

      What matters is if performance is good enough (remember premature optimization) and massive productivity gains and of course, using the right tool for the right job. Python isn't running real-time code, but then it is running Reddit, the Eve Online MMORPG (the Stackless interpreter removes the GIL), and code at Google, Amazon, Lucasfilm, Disney Studios, HP, NASA shuttle operations, at one time all of YouTube, and was used at CERN in the hunt for the Higgs Boson. That sounds like a very useful product to me.

      > So... I guess you may have LOTS of experience interviewing Python pseudo-users
      >but no real programming experience. Unless you have only used Python in your
      >whole life, so you have no base for comparison!

      See above. Almost all of my programming experience is in Delphi and Turbo Pascal (along with more DSL tools like SQL dialects and report generator languages). I was the CTO for a startup and chose Delphi from 1995-2003. I'd give you a multi-page comparison between the two languages if you want, but not here as it's not my blog.

      Delete
    9. Anonymous12:49

      Yes, I know what you mean. In universities Python may have a nice position. Most teachers doing research inside universities just don't care about performance. They have all the time of the world. Believe me, I know that kind very well ;-). Just out of curiosity, lets take some performance comparisons. I've just picked the first benchmark randomly in http://benchmarksgame.alioth.debian.org/:

      Calculate an eigenvalue using the power method
      - C (gcc): 1.92 s
      - Free Pascal: 15.72 s
      - Python 3: 13 minuntes! (yes, you read it correctly! 13 minutes!)

      Among all the languages/compilers tested, Python 3 was the second slowest!!!

      Is it or isn't a joke? ;-)

      You want to create software "fast" but the software itself is slower than a paraplegic turtle? Be my guest!

      Delete
    10. These benchmarks implement the same algorithm across all languages, even if that algorithm isn't efficient in that language. They don't use additional libraries, they don't allow inlining of assembler, etc. Python has a host of JIT compilers, tools that translate the code to C or C++, libraries that allow one to inline C code, functional styles that avoid interpreted loops, a C++-based vector library to replace loops with vectors and matrices where possible, etc. Also by default its using arbitrary precision arithmetic, which is slower.

      As documented on the EMBT forum, a simple benchmark was implemented in Delphi and Free Pascal and I tried Python. I had 32bit Windows and 64bit Linux, but my times were just about the same as others' so that didn't make much difference. 32bit Delphi took 6.055 seconds, 64bit FPC took 1.6 seconds (others got almost the same times using 64bit Delphi). Python originally took 111 seconds! I used the PyPy JIT compiler and the execution time dropped to 10.5 seconds! I then used Cython, which only needed me to explicitly specify the types of the variables in the benchmark loop, then it converted the function to C and compiled it and made a Python wrapper for it (no need for me to write any C code). New time: 2.7 seconds, better than double Delphi's time! Cranking up the GCC optimization to O3 and adding one other optimization to turn off checking for something that couldn't happen in this code and the time dropped to 1.63 seconds! That was a virtual tie with FreePascal and better than 3X Delphi's score!

      You know how you code the majority of your program in Delphi, then if things are too slow you profile and rewrite small bits in assembler? Same with Python, except you're finished much faster, profile if necessary, then replace small bits with C or C++ or something else if necessary - and in most cases you don't need to even write the C or C++! You can also try a JIT compiler and not need to do anything extra at all.

      So no, in the real world, Python rules the roost in math and science (SAGE, which combines almost 100 open source math libraries into one awesome mathematics program, uses Python as its one language to bind them all). It's not a "paraplegic turtle" at all. That doesn't mean you'd use it for where you should be using C or Fortran. Delphi's no different in that respect. In its case, there are a lot of places where it's fast enough to execute but too slow for development, but no one wants to admit that. People want to attack those who try to suggest ways to improve development time in the language, which is sad. Python people don't pretend it's fast out of the box; they're the ones building the JITs and code translators and optimized libraries instead.

      Delete
  16. david b18:55

    Maybe out of topic, syntax improvements are great (unless your code needs to compile with older Delphi compilers), but what would be better I think is much more design-time improvements, to avoid typing code completely. More helper editor dialogs to hide the complexities of many properties, and more usage of linking components to add no-code features to your apps.

    ReplyDelete
    Replies
    1. kmorwath08:54

      This is CASE. It failed several years ago. It wasn't flexible enough and didn't match developers needs but for simple applications.

      Delete
    2. IDE helpers are more for write-once read-never code, as the more code that is autogenerated, the harder it is to maintain en refactor (manually) later on.

      At some point that approach ends up introducing meta-languages and meta-descriptions (or models), so that you don't have to maintain the auto-generated code yourself, but IMHO that's just a demonstration that the original language was insufficiently practical for the task.

      Delete
  17. I think 10% of Delphi Community wants to Pythonize Delphi.
    I don´t think that being shorter is allways being more readable.
    One of the things a Compiler should do is to compare your intention with what you in fact have done.I hate duck typing.
    Reading a program should be natural even for someone that does not know the language,I program in Delphi I can read C# programs and say what they´re going to do,But I don´t realy have a clue whats a Python program does.And I don´t think that a Python programmer stays 7 years in comma,and when he wakes he´ll be able to read his own stuff.The compiler does not have to infer anything ,he should be a little smarter like killing objects After I left the scope,but for the rest I´m really satisfied with Object Pascal. See how many stupidy things one can do with Pyton,imagine it in a bad hand,I mean a newbie. https://www.quora.com/Why-does-Python-get-so-much-hate

    ReplyDelete
  18. Just returned to Delphi the last couple of months because of FMX, but must say the lack of evolution in the language is disappointing. Apart from verbosity, missing key features, some things are just wrong - like COM-related interfaces, no record destructors, can't express relationships between types without having to fabricate abstract base classes/COM interfaces to avoid circular unit references (nope not a design mistake) etc.

    All that aside, I've just realized what is bothering me about it: it's not fluid, it feels brittle, dead.

    Modern languages support constructs that allow you to express yourself clearly, concisely, with flexibility, and the code feels like it flows. Delphi really reflects the structured focus of Pascal, it hasn't evolved well.

    Some of the ideas in your article are great to address the problem, as are these ones:

    https://www.finalbuilder.com/resources/blogs/postid/750/delphi-language-enhancements

    I think some of the work the RemObjects team has done with Oxygene is great too.

    Not sure why Embarcadero are lagging on this, no point having FMX if the language is a relic. I used to love Delphi, but coming back to it after working for years in C#/Ruby/Elixir/Kotlin, Delphi is too verbose and brittle to be fluid, it feels like it is dying and Embarcadero is doing nothing about it.

    This is just my opinion, and I hope I am wrong, because FMX looks amazing. I'd be very grateful if anyone could point out the mistakes in my comment/understanding.

    ReplyDelete