www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - D code length vs other languages

reply Walter Bright <newshound2 digitalmars.com> writes:
https://danuker.go.ro/programming-languages.html

I'm unsure of the accuracy of the methodology of determining this, but D does 
fairly well in it. It wasn't designed to be a particularly terse language, and 
personally I find that excessive terseness makes for a hard-to-understand 
language as well as making typos more likely to produce buggy programs.

(Taken to its logical extreme, for a language with no redundancy, any random 
sequence of bytes would be a valid program. It would be impossible for a 
compiler to diagnose any errors.)

D being about a third less code than C++ is consistent with my unscientific 
experience with it.

I'm a little surprised that D is significantly more compact than Rust.
Dec 05 2019
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Thursday, 5 December 2019 at 22:21:13 UTC, Walter Bright wrote:
 D being about a third less code than C++ is consistent with my 
 unscientific experience with it.
Indeed, I actually frequently do even less. A lot of repetition in other languages I find myself able to automate pretty well in D. Whole blocks of 1,000 lines of glue code in other languages can be replaced with 30 lines of CT reflection stuff.
Dec 05 2019
next sibling parent reply Paolo Invernizzi <paolo.invernizzi gmail.com> writes:
On Thursday, 5 December 2019 at 22:28:53 UTC, Adam D. Ruppe wrote:
 On Thursday, 5 December 2019 at 22:21:13 UTC, Walter Bright 
 wrote:
 D being about a third less code than C++ is consistent with my 
 unscientific experience with it.
Indeed, I actually frequently do even less. A lot of repetition in other languages I find myself able to automate pretty well in D. Whole blocks of 1,000 lines of glue code in other languages can be replaced with 30 lines of CT reflection stuff.
Yesterday happened to me to translate a modest size python script into D, to incorporate it in a product, and it was a pleasant experience. The port was really really easy ... but I'm starting to miss list comprehension ... Anyway, point taken!
Dec 06 2019
parent reply Craig Dillabaugh <craig.dillabaugh gmail.com> writes:
On Friday, 6 December 2019 at 08:47:59 UTC, Paolo Invernizzi 
wrote:
 On Thursday, 5 December 2019 at 22:28:53 UTC, Adam D. Ruppe
clip
 Yesterday happened to me to translate a modest size python 
 script into D, to incorporate it in a product, and it was a 
 pleasant experience.

 The port was really really easy ... but I'm starting to miss 
 list comprehension ...

 Anyway, point taken!
Wouldn't it be fairly easy to write some sort simple library that gives you list comprehensions in D. It wouldn't be a nice as the python syntax, but it should be doable no?
Dec 06 2019
parent reply Jonathan Marler <johnnymarler gmail.com> writes:
On Friday, 6 December 2019 at 18:25:20 UTC, Craig Dillabaugh 
wrote:
 On Friday, 6 December 2019 at 08:47:59 UTC, Paolo Invernizzi 
 wrote:
 On Thursday, 5 December 2019 at 22:28:53 UTC, Adam D. Ruppe
clip
 Yesterday happened to me to translate a modest size python 
 script into D, to incorporate it in a product, and it was a 
 pleasant experience.

 The port was really really easy ... but I'm starting to miss 
 list comprehension ...

 Anyway, point taken!
Wouldn't it be fairly easy to write some sort simple library that gives you list comprehensions in D. It wouldn't be a nice as the python syntax, but it should be doable no?
You could do that, or you could use a UFCS chain as well. More flexible than list comprehensions.
Dec 06 2019
parent reply Paolo Invernizzi <paolo.invernizzi gmail.com> writes:
On Friday, 6 December 2019 at 18:53:22 UTC, Jonathan Marler wrote:
 On Friday, 6 December 2019 at 18:25:20 UTC, Craig Dillabaugh 
 wrote:
 On Friday, 6 December 2019 at 08:47:59 UTC, Paolo Invernizzi 
 wrote:
 On Thursday, 5 December 2019 at 22:28:53 UTC, Adam D. Ruppe
clip
 Yesterday happened to me to translate a modest size python 
 script into D, to incorporate it in a product, and it was a 
 pleasant experience.

 The port was really really easy ... but I'm starting to miss 
 list comprehension ...

 Anyway, point taken!
Wouldn't it be fairly easy to write some sort simple library that gives you list comprehensions in D. It wouldn't be a nice as the python syntax, but it should be doable no?
You could do that, or you could use a UFCS chain as well. More flexible than list comprehensions.
Maybe you are both right ... and maybe I've written too much Python code in the past years and indeed, UFCS chains are a killer future of D: every list comprehension was turned into a nice UFCS chain. Let's forget about that: the point is still taken by D, converting python code in D code is a pleasant experience!
Dec 06 2019
next sibling parent reply Jesse Phillips <Jesse.K.Phillips+D gmail.com> writes:
On Friday, 6 December 2019 at 20:09:46 UTC, Paolo Invernizzi 
wrote:
 Maybe you are both right ... and maybe I've written too much 
 Python code in the past years and indeed, UFCS chains are a 
 killer future of D: every list comprehension was turned into a 
 nice UFCS chain.

 Let's forget about that: the point is still taken by D, 
 converting python code in D code is a pleasant experience!
https://dev.to/jessekphillips/map-reduce-in-d-25nm This was my very brief comparison of List comprehension vs Ds libraries.
Dec 07 2019
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 12/7/19 4:28 AM, Jesse Phillips wrote:
 On Friday, 6 December 2019 at 20:09:46 UTC, Paolo Invernizzi wrote:
 Maybe you are both right ... and maybe I've written too much Python 
 code in the past years and indeed, UFCS chains are a killer future of 
 D: every list comprehension was turned into a nice UFCS chain.

 Let's forget about that: the point is still taken by D, converting 
 python code in D code is a pleasant experience!
https://dev.to/jessekphillips/map-reduce-in-d-25nm This was my very brief comparison of List comprehension vs Ds libraries.
"In the first situation filtering came before the operation, here it will ultimately be useless because it operates on the square of a number which is always even." You sure about that? ;) -Steve
Dec 09 2019
parent reply Jesse Phillips <Jesse.K.Phillips+D gmail.com> writes:
On Monday, 9 December 2019 at 16:33:30 UTC, Steven Schveighoffer 
wrote:
 On 12/7/19 4:28 AM, Jesse Phillips wrote:
 On Friday, 6 December 2019 at 20:09:46 UTC, Paolo Invernizzi 
 wrote:
 [...]
https://dev.to/jessekphillips/map-reduce-in-d-25nm This was my very brief comparison of List comprehension vs Ds libraries.
"In the first situation filtering came before the operation, here it will ultimately be useless because it operates on the square of a number which is always even." You sure about that? ;) -Steve
Yes because anything else is filtered out. I must have been thinking about addition :)
Dec 09 2019
parent reply norm <norm.rowtree gmail.com> writes:
On Tuesday, 10 December 2019 at 02:23:21 UTC, Jesse Phillips 
wrote:
 On Monday, 9 December 2019 at 16:33:30 UTC, Steven 
 Schveighoffer wrote:
 On 12/7/19 4:28 AM, Jesse Phillips wrote:
 On Friday, 6 December 2019 at 20:09:46 UTC, Paolo Invernizzi 
 wrote:
 [...]
https://dev.to/jessekphillips/map-reduce-in-d-25nm This was my very brief comparison of List comprehension vs Ds libraries.
"In the first situation filtering came before the operation, here it will ultimately be useless because it operates on the square of a number which is always even." You sure about that? ;) -Steve
Yes because anything else is filtered out. I must have been thinking about addition :)
--- new_range = [i * i for i in range(5) if i % 2 == 0] --- import std.range; auto new_range = iota(5) .filter!(i => i % 2) .map!(i => i * i); These produce different results, is that intended? I think the filter should be `filter!(i => i % 2 == 0)` For your use case it makes no difference if you map first or filter first. It might be useful to show a case where it does matter to highlight how the UFCS allows D to give a more natural order of the chained operations. Cheers, Norm
Dec 09 2019
parent Jesse Phillips <Jesse.K.Phillips+D gmail.com> writes:
On Tuesday, 10 December 2019 at 02:46:58 UTC, norm wrote:
 ---
 new_range  = [i * i for i in range(5)   if i % 2 == 0]
 ---
 import std.range;
 auto new_range = iota(5)
                  .filter!(i => i % 2)
                  .map!(i => i * i);

 These produce different results, is that intended? I think the 
 filter should be

 `filter!(i => i % 2 == 0)`

 For your use case it makes no difference if you map first or 
 filter first. It might be useful to show a case where it does 
 matter to highlight how the UFCS allows D to give a more 
 natural order of the chained operations.

 Cheers,
 Norm
Done, using addition and adding the missing equality
Dec 09 2019
prev sibling parent reply Tobias Pankrath <tobias pankrath.net> writes:
On Friday, 6 December 2019 at 20:09:46 UTC, Paolo Invernizzi 
wrote:
 Maybe you are both right ... and maybe I've written too much 
 Python code in the past years and indeed, UFCS chains are a 
 killer future of D: every list comprehension was turned into a 
 nice UFCS chain.

 Let's forget about that: the point is still taken by D, 
 converting python code in D code is a pleasant experience!
What I miss though is creating ranges with something like python's generator functions.
Dec 07 2019
next sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Saturday, 7 December 2019 at 09:59:01 UTC, Tobias Pankrath 
wrote:
 What I miss though is creating ranges with something like 
 python's generator functions.
Implement C++ stackless coroutines, perhaps? It will eventually be important to have something compatible in order to interface well.
Dec 07 2019
prev sibling parent reply mipri <mipri minimaltype.com> writes:
On Saturday, 7 December 2019 at 09:59:01 UTC, Tobias Pankrath 
wrote:
 On Friday, 6 December 2019 at 20:09:46 UTC, Paolo Invernizzi 
 wrote:
 Maybe you are both right ... and maybe I've written too much 
 Python code in the past years and indeed, UFCS chains are a 
 killer future of D: every list comprehension was turned into a 
 nice UFCS chain.

 Let's forget about that: the point is still taken by D, 
 converting python code in D code is a pleasant experience!
What I miss though is creating ranges with something like python's generator functions.
You can use std.range.generate with any random closure: import std.stdio; void main() { import std.range : take, zip, generate; auto multiples(int n) { int i; return generate!({ return i += n; }); } foreach (p; zip(multiples(2), multiples(3)).take(5)) { writeln(p[0], " ", p[1]); } } Or use std.concurrency to get the same control flow: void main() { import std.range : take, zip; import std.concurrency : Generator, yield; auto multiples(int n) { return new Generator!int({ int i; while (true) yield (i += n); }); } foreach (p; zip(multiples(2), multiples(3)).take(5)) { writeln(p[0], " ", p[1]); } }
Dec 07 2019
parent reply Tobias Pankrath <tobias pankrath.net> writes:
On Saturday, 7 December 2019 at 10:17:46 UTC, mipri wrote:
 On Saturday, 7 December 2019 at 09:59:01 UTC, Tobias Pankrath 
 wrote:
 [...]
You can use std.range.generate with any random closure: import std.stdio; void main() { import std.range : take, zip, generate; auto multiples(int n) { int i; return generate!({ return i += n; }); } foreach (p; zip(multiples(2), multiples(3)).take(5)) { writeln(p[0], " ", p[1]); } } Or use std.concurrency to get the same control flow: void main() { import std.range : take, zip; import std.concurrency : Generator, yield; auto multiples(int n) { return new Generator!int({ int i; while (true) yield (i += n); }); } foreach (p; zip(multiples(2), multiples(3)).take(5)) { writeln(p[0], " ", p[1]); } }
Didn't know std.concurrency.Generator, thanks! With std.range.generate I don't know how to signal exhaustion/emptyness of a range. For simple infinite use cases it's cool though.
Dec 07 2019
parent Paul Backus <snarwin gmail.com> writes:
On Saturday, 7 December 2019 at 10:49:37 UTC, Tobias Pankrath 
wrote:
 On Saturday, 7 December 2019 at 10:17:46 UTC, mipri wrote:
 You can use std.range.generate with any random closure:

   import std.stdio;

   void main() {
       import std.range : take, zip, generate;

       auto multiples(int n) {
           int i;
           return generate!({
               return i += n;
           });
       }

       foreach (p; zip(multiples(2), multiples(3)).take(5)) {
           writeln(p[0], " ", p[1]);
       }
   }

 [...]
Didn't know std.concurrency.Generator, thanks! With std.range.generate I don't know how to signal exhaustion/emptyness of a range. For simple infinite use cases it's cool though.
You can use Nullable (or Optional from dub) and a bit of post-processing to get a finite range: import std; void main() { auto seq(int start, int end) in (start <= end) { int i = start; return generate!({ if (i >= end) { return Nullable!int.init; } else { return nullable(i++); } }) .until!(n => n.isNull) .map!(n => n.get); } writeln(seq(10, 20).array); }
Dec 07 2019
prev sibling parent German Diago <germandiago gmail.com> writes:
On Thursday, 5 December 2019 at 22:28:53 UTC, Adam D. Ruppe wrote:
 On Thursday, 5 December 2019 at 22:21:13 UTC, Walter Bright 
 wrote:
 D being about a third less code than C++ is consistent with my 
 unscientific experience with it.
Indeed, I actually frequently do even less. A lot of repetition in other languages I find myself able to automate pretty well in D. Whole blocks of 1,000 lines of glue code in other languages can be replaced with 30 lines of CT reflection stuff.
This is something that D excels at. That is why I like it. Many external world communication can be done efficiently. About a third of the code. There are still things in C++20 that cannot be done, but modules will allow to use using directives more liberally and they remove the implicit inline from classes. This means that code will get quite shorter I think. C++20 has a lot of baggage but still stays as a very competent language IMHO.
Dec 11 2019
prev sibling parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 5 December 2019 at 22:21:13 UTC, Walter Bright wrote:
 https://danuker.go.ro/programming-languages.html

 I'm unsure of the accuracy of the methodology of determining 
 this, but D does fairly well in it.
It is probably better to look at the examples on the Rosetta website. Seems to me that some try to be terse, yet others try to show off language features. So, for the same language you have sometimes very verbose low level and very terse high level solutions (some are clearly cheating).
Dec 05 2019
parent reply Jab <jab_293 gmall.com> writes:
On Friday, 6 December 2019 at 00:26:14 UTC, Ola Fosheim Grøstad 
wrote:
 On Thursday, 5 December 2019 at 22:21:13 UTC, Walter Bright 
 wrote:
 https://danuker.go.ro/programming-languages.html

 I'm unsure of the accuracy of the methodology of determining 
 this, but D does fairly well in it.
It is probably better to look at the examples on the Rosetta website. Seems to me that some try to be terse, yet others try to show off language features. So, for the same language you have sometimes very verbose low level and very terse high level solutions (some are clearly cheating).
They also use different (non-standard) libraries, which really depends on what they implement and what kind of interface they provide. Some of the C++ code examples have variables defined at the start in old C-style. With multiple variables just being declared on 7+ more lines. The examples weren't intended to be used a means to measure number of lines of code. Even on the page it points out that comments weren't taken into consideration. This data is extremely unreliable and should be taken with a huge grain of salt.
Dec 05 2019
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Friday, 6 December 2019 at 05:44:31 UTC, Jab wrote:
 provide. Some of the C++ code examples have variables defined 
 at the start in old C-style. With multiple variables just being 
 declared on 7+ more lines. The examples weren't intended to be 
 used a means to measure number of lines of code.
Yes, I think there are too many tasks in Rosetta as well. Many of the code examples states that it is translated from the C example. That clearly makes a lot of the code "unnatural" for any given language. Probably the D code too. C++ is more verbose than D. In part because the C++ std lib requires more syntax and also because C++ code often use explicit namespaces. C++ is gradually getting less verbose by newer features like for-each, lambdas and constexpr.
Dec 06 2019
parent reply Gregor =?UTF-8?B?TcO8Y2ts?= <gregormueckl gmx.de> writes:
On Friday, 6 December 2019 at 09:58:28 UTC, Ola Fosheim Grøstad 
wrote:
 C++ is more verbose than D. In part because the C++ std lib 
 requires more syntax and also because C++ code often use 
 explicit namespaces. C++ is gradually getting less verbose by 
 newer features like for-each, lambdas and constexpr.
Also, the need for headers. That alone can add considerably to a codebase.
Dec 06 2019
parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Friday, 6 December 2019 at 10:16:59 UTC, Gregor Mückl wrote:
 Also, the need for headers. That alone can add considerably to 
 a codebase.
True, you that you have to specify the signature of all class members that is implemented in a .cpp file. So you often have to write a lot of code twice, once for the .hpp file and once for the .cpp file. Kinda made sense before C++ added templates as the .hpp file was slim and easy to read, now it is quite the opposite.
Dec 06 2019