www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Blaming the D language

reply "Domingo Alvarez Duarte" <mingodad gmail.com> writes:
Hello !

I'll start here a place to blame the D language with the intent 
of register here the dark sides of the language and it's 
libraries with the hope that it will drive efforts to fix then.

First a bit of my experience with the D language, I hear about it 
some years ago and it was an interesting language but it gave me 
the impression of immaturity like a bit more than a toy language, 
most recently I gave it another look and it seems that it 
progressed a lot since then.

I started searching the net for interesting opensource projects 
using D language to test then and compare with C/C++ in terms of 
performance.

Here are my folder with what I found interesting:

ae            dmd-script            harmonia-dad
arsd          DMDScript             harmonia-dad.tgz          
tango-trunk
bcd.gen       dmd-script-1          HarmoniaDemo              
Tiny-Redis
               dmd-script-2          Higgs
bindings      dranges               languagemachine-0.2.5     
ubjsond
Croc          dstep                 ldc2-0.13.0-linux-x86_64  
userman
ctags-d       D-templates-tutorial  libasync                  uv.d
d2sqlite3     d-tui                 LuaD                      
vibe.d
decimal       d-tut-master                                    
vibed.org
deimos        dwt                   minwin
dmd1                                monodHello                
vibelog
dmd2          GDC                                             
vibenotes
dmd-c++       goldie                Pegged
dmd-newmagic  harmonia

Then I started compiling then to test, most of then do not 
compile with the latest dmd compiler, I tried to fix then and on 
some of then after fixing several things I end up finding bugs on 
DMD compiler that I submit and some of then god fixed but then 
one dark side of the D language came to light:

There is no backport/bug fix for the stable releases like gcc or 
other well know software, gcc has at least the latest 3 stable 
version maintained, when a bug is found it's fixed on all of the 
maintained versions that suffer from it. The D language should 
take note/learn from gcc here. Another interesting example is 
Freepascal when a new compiler version is released they also 
release a guide that highlight the major changes and how old code 
will be affected by the changes and examples on how to change the 
code to work with the new compiler version.
I would like to see the dub packages to declare the minimal dmd 
compiler version that they guarantee it'll work, and before any 
new release of dmd use the whole dub packages as a test bed and 
for every project that do not compile write a how to on how to 
convert the code to compile or somehow modify the compiler to 
recognize old constructions and through warnings or other way 
compile then.

It's so sad to see interesting projects using the D language 
abandoned tired of code breakage with any dmd compiler evolution.

Let's talk about libraries now, there is some silly things like 
associative array not having a "clear/lenght=0" way to reset it, 
and people sugest create templates that does:

foreach(string key; aa.keys) aa.remove(key);

If we are on a memory pressure to liberate memory we need to 
allocate more memory for big associative arrays that's insane and 
generate more garbage to be collected (this is a small/silly 
insane dark side).

Now let's see std.str I expect some functions that are widely 
available on other languages to be present there but some of then 
are std.algorithm, std.array, std.container, std.format and even 
on std.str it's crazy for a new developer to find things on 
phobos.

And then the massive/crazy attributes/properties and its 
combinations that makes even harder to understand why some code 
do not compile and give error messages miles away from our actual 
offending code (thanks for templates everywhere).

Well I'll update time to time this post and encourage others to 
do the same hopping that this will drive positive changes to the 
D language.

Cheers !
Oct 21 2014
next sibling parent reply "thedeemon" <dlang thedeemon.com> writes:
On Wednesday, 22 October 2014 at 05:17:54 UTC, Domingo Alvarez 
Duarte wrote:

 There is no backport/bug fix for the stable releases
I understand now for each release 2.0XX there can be some bugfix releases like 2.0XX.Y. For example, 2.066.1 is a bugfix release for 2.066.
 Let's talk about libraries now, there is some silly things like 
 associative array not having a "clear/lenght=0" way to reset 
 it, and people sugest create templates that does:

 foreach(string key; aa.keys) aa.remove(key);
Yep, that one bugged me too. Then I realized this clearance just makes key-value pairs become garbage, so there is a simpler and more effective equivalent: A[B] freshCleanAA; aa = freshCleanAA; (where A[B] denotes the type of aa) That's it!
Oct 21 2014
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 10/21/2014 11:06 PM, thedeemon wrote:

      A[B] freshCleanAA;
      aa = freshCleanAA;

 (where A[B] denotes the type of aa)
 That's it!
Alternative: A[B] aa; aa = aa.init; Ali
Oct 21 2014
parent reply "Jakob Ovrum" <jakobovrum gmail.com> writes:
On Wednesday, 22 October 2014 at 06:42:06 UTC, Ali Çehreli wrote:
 On 10/21/2014 11:06 PM, thedeemon wrote:

     A[B] freshCleanAA;
     aa = freshCleanAA;

 (where A[B] denotes the type of aa)
 That's it!
Alternative: A[B] aa; aa = aa.init; Ali
`aa.init` is just `null`, which illustrates the problem better: int[string] aa = ["foo": 42]; int[string] aaAlias = aa; aa = null; assert("foo" !in aa); // Ostensibly cleared... assert(aaAlias["foo"] == 42); // Until aliasing is introduced.
Oct 21 2014
parent reply Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Wednesday, October 22, 2014 06:59:02 Jakob Ovrum via Digitalmars-d wrote:
 On Wednesday, 22 October 2014 at 06:42:06 UTC, Ali Çehreli wrote:
 On 10/21/2014 11:06 PM, thedeemon wrote:
     A[B] freshCleanAA;
     aa = freshCleanAA;

 (where A[B] denotes the type of aa)
 That's it!
Alternative: A[B] aa; aa = aa.init; Ali
`aa.init` is just `null`, which illustrates the problem better: int[string] aa = ["foo": 42]; int[string] aaAlias = aa; aa = null; assert("foo" !in aa); // Ostensibly cleared... assert(aaAlias["foo"] == 42); // Until aliasing is introduced.
Well, the reality of the matter is that you can't truly clear it safely, though we could definitely get closer. The in operator gives pointer access to the internals, and the byKey and byValue may do the same (not to mention, opApply), and they could be in progress when you try and clear out the AA, so if you cleared it out, all of those would still have to work (or maybe throw an Error in the cases where iteration is going on). To some extent at least, the internals would still have to be accessible or risk nasty, potentially system things happening (though obviously, if nothing has references to them, then they're prime for garbage collection). So, I don't know how much of an AA you can truly clear out, and even once you do, it's going to be need to be left to the GC to collect it all. But it should certainly be possible to make it so that further calls to byKey, byValue, the in operater, etc. treat the AA as empty, even if previous calls which have data in use will need to still have access to that data. So, I'm sure that the situation could be improved, but I don't know if it can be fixed completely. The AA implementation needs a _lot_ of work regardless though. - Jonathan M Davis
Oct 22 2014
parent reply "Jakob Ovrum" <jakobovrum gmail.com> writes:
On Wednesday, 22 October 2014 at 07:42:22 UTC, Jonathan M Davis 
via Digitalmars-d wrote:
 Well, the reality of the matter is that you can't truly clear 
 it safely,
 though we could definitely get closer. The in operator gives 
 pointer access to
 the internals, and the byKey and byValue may do the same (not 
 to mention,
 opApply), and they could be in progress when you try and clear 
 out the AA, so
 if you cleared it out, all of those would still have to work 
 (or maybe throw
 an Error in the cases where iteration is going on).
This is already the case because of .remove(). Adding a clear method wouldn't introduce any *new* problems.
Oct 24 2014
parent Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Friday, October 24, 2014 11:03:11 Jakob Ovrum via Digitalmars-d wrote:
 On Wednesday, 22 October 2014 at 07:42:22 UTC, Jonathan M Davis

 via Digitalmars-d wrote:
 Well, the reality of the matter is that you can't truly clear
 it safely,
 though we could definitely get closer. The in operator gives
 pointer access to
 the internals, and the byKey and byValue may do the same (not
 to mention,
 opApply), and they could be in progress when you try and clear
 out the AA, so
 if you cleared it out, all of those would still have to work
 (or maybe throw
 an Error in the cases where iteration is going on).
This is already the case because of .remove(). Adding a clear method wouldn't introduce any *new* problems.
True. And I'm certainly not against adding a clear function (quite the opposite in fact). I was just pointingout that it won't work for it to just free all of the memory at that point (that will still be left up to the GC), so it's not like it would magically solve all of the complaints (and the inability to explicitly free the memory seems to be one of the complaints that sparked this thread in the first place). What it _will_ do, however, is make it so that it's possible to affect all references to an AA whereas nulling a reference doesn't do that. As a side note, it _is_ quite possible to clear out an AA right now; it's just a royal pain and not particularly efficient. All you have to do is use keys() to get an array of the keys, and then iterate over them, removing each one from the AA in turn. And voila, it's been cleared. But it's a pretty ridiculous way to have to go about it. There really should just be a clear function that does it for you (and more efficently, since it probably won't need to allocate an array of the keys to do it and could likely take advantage of internal implementation details to clear it out more efficiently than sequential calls to remove will). - Jonathan M Davis
Oct 24 2014
prev sibling next sibling parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
 There is no backport/bug fix for the stable releases like gcc 
 or other well know software, gcc has at least the latest 3 
 stable version maintained, when a bug is found it's fixed on 
 all of the maintained versions that suffer from it.
Yes, I agree. I've also complained about not having a stable version in the past. The attitude in the D community is that having one stable and one experimental branch is not desirable. And for some reason it is claimed that D is production ready. I don't agree, and I think exposing that view leads to problems. It means that features that should have stayed experimental go into the mainline and remain there, and that more half-way features are being added rather than worked on theoretically until a general and more clean solution is found. I believe you will be happier if you view D as being in an experimental state. And I think it is a valuable experiment too. Especially the static reflection capabilities in a C++ like language is interesting to think about. That is what makes D most interesting to me at the moment.
 It's so sad to see interesting projects using the D language 
 abandoned tired of code breakage with any dmd compiler 
 evolution.
The D designers have expressed an interest in gofix which upgrade source from an old version to a newer version. Requirements for this to be fully automatic: - Add a version identifier in the head of each source file, currently not possible? - Remove string mixins!! - Careful addition of new features.
 Now let's see std.str I expect some functions that are widely 
 available on other languages to be present there but some of 
 then are std.algorithm, std.array, std.container, std.format 
 and even on std.str it's crazy for a new developer to find 
 things on phobos.
Yes, I agree. Phobos is a mix of useful, esoteric and experimental features. It should be broken down in a different way. I have recently started to map out the standard features of Haskell and looking at how to represent them in D. The API and structure of phobos need some work. I think the overrated C++ standard library has influenced phobos too much. I also want to see string mixins removed from phobos. It is a very ugly feature. I think phobos should move 100% to lambdas and work on the optimization of lambdas if it is a problem.
 Well I'll update time to time this post and encourage others to 
 do the same hopping that this will drive positive changes to 
 the D language.
I like your attitude, but keep in mind that C++ has many more people behind it. I've changed my view to look at D as being in an experimental state. I think the desire to expand features go beyond the capacity of the project both in the compiler and libraries. And since the compiler is written in C++, it is difficult to make big changes. Compilers written in functional languages such as Haskell or OCaml are more open to experimentation.
Oct 21 2014
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Ola Fosheim Grøstad:

 I think the overrated C++ standard library has influenced 
 phobos too much.
I agree.
 I also want to see string mixins removed from phobos. It is a 
 very ugly feature.
What are your problems with those strings? Bye, bearophile
Oct 22 2014
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Wednesday, 22 October 2014 at 07:46:18 UTC, bearophile wrote:
 Ola Fosheim Grøstad:
 I also want to see string mixins removed from phobos. It is a 
 very ugly feature.
What are your problems with those strings?
1. Source level analysis: Hard to write programs that transform source. 2. Easy to write ugly code: It suffers from the same issues as macros. 3. Language integration: It is desirable to have an application level language that can integrate well with a low level language when calling out to system level libraries. 4. Uniform conventions: a lambda is more generic. A lambda allows you to call into another language because it can be translated to the same intermediate format. An incomplete string is on a different level.
Oct 22 2014
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Ola Fosheim Grøstad:

 2. Easy to write ugly code: It suffers from the same issues as 
 macros.
Do you mean C macros? I think this is not true.
 3. Language integration: It is desirable to have an application 
 level language that can integrate well with a low level 
 language when calling out to system level libraries.
I don't understand.
 4. Uniform conventions: a lambda is more generic.
What's bad in using something less generic? Bye, bearophile
Oct 22 2014
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Wednesday, 22 October 2014 at 08:27:53 UTC, bearophile wrote:
 Ola Fosheim Grøstad:

 2. Easy to write ugly code: It suffers from the same issues as 
 macros.
Do you mean C macros? I think this is not true.
Not C macros, because they are free form and happen before parsing. On the other hand, C macros can be expanded and then you do source-to-source translation. With D mixins you might have to evaluate CTFE first? That's a source-to-source killer. I also think AST macros is a bad idea. It works well for Lisp where you have a clean minimal language.
 3. Language integration: It is desirable to have an 
 application level language that can integrate well with a low 
 level language when calling out to system level libraries.
I don't understand.
Let's say you create a tight new language "APP-C" that is easy to write application code in, but you use libraries written in a system level language "D" when the more restricted new language falls short. Then you want to call into the D libraries using lambdas written in "APP-C". If those libraries (built on top of phobos) take string mixins, then you have to know both "APP-C" and "D" in order to write an application. What you want is this: 1. Compile APP-C => common IR 2. Resolve dependencies 3. Compile D => common IR 4. Resolve lambda optimization/inlining on the common IR With string mixins you get: eh…?
 4. Uniform conventions: a lambda is more generic.
What's bad in using something less generic?
It is bad when you get the disadvantages that lambdas do not have (in an optimizing compiler), but don't get advantages?!
Oct 22 2014
parent reply "Kagamin" <spam here.lot> writes:
On Wednesday, 22 October 2014 at 08:44:44 UTC, Ola Fosheim 
Grøstad wrote:
 On the other hand, C macros can be expanded and then you do 
 source-to-source translation. With D mixins you might have to 
 evaluate CTFE first? That's a source-to-source killer.
If it's fairly complex, like turing-complete, do you think, it will be easier than CTFE?
Oct 23 2014
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Thursday, 23 October 2014 at 11:45:46 UTC, Kagamin wrote:
 On Wednesday, 22 October 2014 at 08:44:44 UTC, Ola Fosheim 
 Grøstad wrote:
 On the other hand, C macros can be expanded and then you do 
 source-to-source translation. With D mixins you might have to 
 evaluate CTFE first? That's a source-to-source killer.
If it's fairly complex, like turing-complete, do you think, it will be easier than CTFE?
What do you mean by turing-complete in this context? Both the C preprocessor and D have to terminate in order to produce output… And I see no point in translating programs that cannot be compiled?
Oct 23 2014
parent reply "Kagamin" <spam here.lot> writes:
Able to perform complex transformations, e.g. D to SQL. Or 
generate parser from syntax definition, like what pegged does.
Oct 23 2014
parent reply "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Thursday, 23 October 2014 at 13:54:35 UTC, Kagamin wrote:
 Able to perform complex transformations, e.g. D to SQL. Or 
 generate parser from syntax definition, like what pegged does.
I'm not really sure where you are heading. I am against string mixins, not CTFE.
Oct 23 2014
next sibling parent "Kagamin" <spam here.lot> writes:
Ah, ok, I thought, you said CTFE is a source-to-source killer.
Oct 23 2014
prev sibling parent "Kagamin" <spam here.lot> writes:
Though some refactorings are so simple, they can be done for 
string mixins too, e.g. 
https://issues.dlang.org/show_bug.cgi?id=3850
Oct 23 2014
prev sibling parent reply "Dejan Lekic" <dejan.lekic gmail.com> writes:
On Wednesday, 22 October 2014 at 08:14:24 UTC, Ola Fosheim 
Grøstad wrote:
 2. Easy to write ugly code: It suffers from the same issues as 
 macros.
It is easy to write ugly code in D without string mixins. Just take a look at the (ab)use of UFCS...
Oct 22 2014
parent "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= writes:
On Wednesday, 22 October 2014 at 12:17:32 UTC, Dejan Lekic wrote:
 It is easy to write ugly code in D without string mixins.
 Just take a look at the (ab)use of UFCS...
I am not a fan of UFCS either… I think it is nice to be able to extend aggregates with new member functions, UFCS isn't required to do that. I think it would be better to focus on formally defining a nice generic vocabulary of free functions: sort, length etc… and rather add regular pipelining with tuples. E.g.: arr -> sort -> serialize -> f.write; ===> savearray(serialize(sort(arr))) [(1,2),(3,4)] -> ((_,y1),(x2,_)) => y1*x2 -> f.write;
Oct 22 2014
prev sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 10/22/14 1:17 AM, Domingo Alvarez Duarte wrote:

 Let's talk about libraries now, there is some silly things like
 associative array not having a "clear/lenght=0" way to reset it, and
 people sugest create templates that does:

 foreach(string key; aa.keys) aa.remove(key);
Annoying... https://github.com/D-Programming-Language/druntime/pull/999 -Steve
Oct 24 2014