September 29, 2020
On Tuesday, 29 September 2020 at 11:10:42 UTC, ddcovery wrote:
> On Monday, 21 September 2020 at 09:29:21 UTC, Tomcruisesmart wrote:
>> Hi,
>> I'm looking for healthy conversation.
>> What are the prominent downsides of the D programming language?
>
> As a not D experienced developer (I use rdmd, small game projects and I tried to use as REST service instead play/scala or node/javascript)
>
> Not directly related with DLang but with Development tools:
>
> * Intelligence / autocomplete lack: The use of meta-programming makes it very difficult and really represents a barrier for its incorporation in productive mainstream development (it's funny: we have GC, not good for system/video game developers, but then it makes autocomplete impossible, not good for web services mainstream developers ).
>
> * Inspecting vars while debugging: Why it is so difficult to inspect not trivial vars?. I'm using dlangide, simple and very powerful, but it is hell to inspect variables (especially objects): I have to be defining local variables and assigning object properties to them in order to see their values ​​in the debugger.
>
> * The "auto" Swiss knife:  Yes, I know, "auto" is a powerful tool, but DLang libraries tends to force you to use auto because metaprogramming... it is really difficult to a newcomers to understand the Type returned by a template... and templates are everywhere.
>
> i.e.:  If you read about Tasks (https://dlang.org/phobos/std_parallelism.html), for me is not obvious how to define an empty array of tasks.
>
> Imagine I have a "4 in a line" game and I want to evaluate with a thread each column of the game (a minimax algorithm)
>
>> ??? tasks = [];
>> for( int ixTask=0; ix<COLUMNS; ixTask++){
>>   tasks ~= task!evalColumn(board.clone(), columns[ixTask], maxRecursion - 1);
>>   tasks[ixTask].executeInNewThread();
>> }
>> ...
>
> What do you have to place instead "???"

Basically, the most powerful features of the language (templates/metaprograming/compile time execution) are the barrier to be introduced in the ecosystem of mainstream programming (easy debugging, autocomplete/intelligence, simple typing system), and the only feature mainstream development embraces (GC) is hated by the people that comes from C/C++ (system/game developers).

That said, I like D ... I love it's plasticity, it's versatility ... and it's GC  :D

September 29, 2020
On Tuesday, 29 September 2020 at 11:10:42 UTC, ddcovery wrote:
> * The "auto" Swiss knife:  Yes, I know, "auto" is a powerful tool, but DLang libraries tends to force you to use auto because metaprogramming... it is really difficult to a newcomers to understand the Type returned by a template... and templates are everywhere.
>
> i.e.:  If you read about Tasks (https://dlang.org/phobos/std_parallelism.html), for me is not obvious how to define an empty array of tasks.
>
> Imagine I have a "4 in a line" game and I want to evaluate with a thread each column of the game (a minimax algorithm)
>
>> ??? tasks = [];
>> for( int ixTask=0; ix<COLUMNS; ixTask++){
>>   tasks ~= task!evalColumn(board.clone(), columns[ixTask], maxRecursion - 1);
>>   tasks[ixTask].executeInNewThread();
>> }
>> ...
>
> What do you have to place instead "???"

I mean, you could do this:

auto tasks = COLUMNS.iota.map!(ixTask => task!evalColumn(board.clone(), columns[ixTask], maxRecursion - 1)).array;
tasks.each!"a.executeInNewThread";
September 29, 2020
On Tuesday, 29 September 2020 at 11:35:02 UTC, FeepingCreature wrote:
> On Tuesday, 29 September 2020 at 11:10:42 UTC, ddcovery wrote:
>> * The "auto" Swiss knife:  Yes, I know, "auto" is a powerful tool, but DLang libraries tends to force you to use auto because metaprogramming... it is really difficult to a newcomers to understand the Type returned by a template... and templates are everywhere.
>>
>> i.e.:  If you read about Tasks (https://dlang.org/phobos/std_parallelism.html), for me is not obvious how to define an empty array of tasks.
>>
>> Imagine I have a "4 in a line" game and I want to evaluate with a thread each column of the game (a minimax algorithm)
>>
>>> ??? tasks = [];
>>> for( int ixTask=0; ix<COLUMNS; ixTask++){
>>>   tasks ~= task!evalColumn(board.clone(), columns[ixTask], maxRecursion - 1);
>>>   tasks[ixTask].executeInNewThread();
>>> }
>>> ...
>>
>> What do you have to place instead "???"
>
> I mean, you could do this:
>
> auto tasks = COLUMNS.iota.map!(ixTask => task!evalColumn(board.clone(), columns[ixTask], maxRecursion - 1)).array;
> tasks.each!"a.executeInNewThread";

Hi FeepingCreature,

But "auto" remains :-D.

September 29, 2020
On 9/29/20 8:39 AM, ddcovery wrote:
> On Tuesday, 29 September 2020 at 11:35:02 UTC, FeepingCreature wrote:
>> On Tuesday, 29 September 2020 at 11:10:42 UTC, ddcovery wrote:
>>> * The "auto" Swiss knife:  Yes, I know, "auto" is a powerful tool, but DLang libraries tends to force you to use auto because metaprogramming... it is really difficult to a newcomers to understand the Type returned by a template... and templates are everywhere.
>>>
>>> i.e.:  If you read about Tasks (https://dlang.org/phobos/std_parallelism.html), for me is not obvious how to define an empty array of tasks.
>>>
>>> Imagine I have a "4 in a line" game and I want to evaluate with a thread each column of the game (a minimax algorithm)
>>>
>>>> ??? tasks = [];
>>>> for( int ixTask=0; ix<COLUMNS; ixTask++){
>>>>   tasks ~= task!evalColumn(board.clone(), columns[ixTask], maxRecursion - 1);
>>>>   tasks[ixTask].executeInNewThread();
>>>> }
>>>> ...
>>>
>>> What do you have to place instead "???"
>>
>> I mean, you could do this:
>>
>> auto tasks = COLUMNS.iota.map!(ixTask => task!evalColumn(board.clone(), columns[ixTask], maxRecursion - 1)).array;
>> tasks.each!"a.executeInNewThread";
> 
> Hi FeepingCreature,
> 
> But "auto" remains :-D.
> 

You don't like auto?

pragma(msg, typeof(tasks[]);

now, go back in and replace tasks[] type with whatever that says.

Swift is 99% type inference. It's strongly typed, and you almost never see a type declaration. You *can* type it, but there's no need. People get along swimmingly without having to specify types. It also makes your code much more robust.

-Steve
September 29, 2020
On Tuesday, 29 September 2020 at 13:01:54 UTC, Steven Schveighoffer wrote:
> there's no need. People get along swimmingly without having to specify types. It also makes your code much more robust.

I like type inference and flow typing, but it does not make code more robust.

Specifying twice makes code more robust.

This is basically the principle in verifiable computing, you provide two descriptions of what your code should do and then the check that they line up statically.

September 29, 2020
On 9/29/20 9:07 AM, Ola Fosheim Grøstad wrote:
> On Tuesday, 29 September 2020 at 13:01:54 UTC, Steven Schveighoffer wrote:
>> there's no need. People get along swimmingly without having to specify types. It also makes your code much more robust.
> 
> I like type inference and flow typing, but it does not make code more robust.
> 
> Specifying twice makes code more robust.

If you decide to change your type from e.g. int to long, then you don't need to go edit all the places you declared things.

Just works.

I supposed I should have said more generic.

-Steve
September 29, 2020
On Tuesday, 29 September 2020 at 14:14:34 UTC, Steven Schveighoffer wrote:
> If you decide to change your type from e.g. int to long, then you don't need to go edit all the places you declared things.

Yes, when are certain you understand the code, but it can sometimes prevent understanding. E.g. if th hidden type is some form of ownership then it is very helpful to see the explicit type. Of course an IDE can help here... Depends on the setup/project I guess.
September 29, 2020
On Tuesday, 29 September 2020 at 13:01:54 UTC, Steven Schveighoffer wrote:

>
> You don't like auto?
>
> pragma(msg, typeof(tasks[]);
>
> now, go back in and replace tasks[] type with whatever that says.
>
> Swift is 99% type inference. It's strongly typed, and you almost never see a type declaration. You *can* type it, but there's no need. People get along swimmingly without having to specify types. It also makes your code much more robust.
>
> -Steve

Hi Steve,

I agree, I really appreciate your point and I understand it is difficult to an experienced D developer to understand my point.

My "difficulty" (I assume it is my problem) is when reading documentation about methods returning "auto"... it's hard, at the beginning, to transform this mentally in something I can understand (trying not to hide mentally the information)... D plasticity differs to other simplest "generics" type systems (like Scala) and you need double effort to understand it.

An added difficulty  (that I don't know if the "swift developers" will suffer with xcode) is the missing of a good "autocomplete" or "type inference" that helps developers to understand the type that an "auto" function is really returning in the context of an evocation (i.e.: Right now, I am working with flutter/dart and vscode shows me the inferred type of a variable when hovering with the mouse).




September 29, 2020
On Monday, 21 September 2020 at 09:29:21 UTC, Tomcruisesmart wrote:
> Hi,
> I'm looking for healthy conversation.
> What are the prominent downsides of the D programming language?

-There tends to be a need to switch between compiler versions. Sometimes one may even have to use two different versions for the same project.

-Typical D projects tend to require compiling everything at once. The main reason this is a problem is that you can't use different compiler flags for different parts. It's no worse than on the mainstream object oriented languages, though.

-Heavy use of templates still worsens error messages. They are clear enough that an average programmer won't, in general, hit the wall. But it tends to require several attempts and/or reading the docs to fix template-related errors, as opposed to untemplated error messages like: "function call `serialize` not found, did you mean `serialise`?".

-Using templates and defining simple ones is easy and tidy. But defining really good templates tends to get difficult. Look at Phobos source code: complex template constraints. The most recent D blog entry give a good taste of what it's like. On the other hand, in other languages you'd have to resort to macros to do similar stuff at all...

-Expressing complex data, especially if it's dynamically typed (at least out of the box, without third party libraries). D tends to be good at processing data but not so good in initializing it. Unit tests tend to get longer than I'd imagine them being in Lua or JavaScript.
September 29, 2020
On Tue, Sep 29, 2020 at 03:35:42PM +0000, ddcovery via Digitalmars-d wrote: [...]
> My "difficulty" (I assume it is my problem) is when reading documentation about methods returning "auto"... it's hard, at the beginning, to transform this mentally in something I can understand (trying not to hide mentally the information)... D plasticity differs to other simplest "generics" type systems (like Scala) and you need double effort to understand it.

IMO, this is more a problem with the documentation than with `auto` itself.  The documentation really should be stating exactly what you can / cannot do with the returned object.  But beyond that, a function that returns `auto` really means "the return type is not important to be able to use this function", and by extension, "you really shouldn't need to know what the concrete type is; if you do, you're probably using this function wrong".

This is where it's extremely important for the docs to be as clear as possible about what you can do with the opaque return value.


> An added difficulty  (that I don't know if the "swift developers" will suffer with xcode) is the missing of a good "autocomplete" or "type inference" that helps developers to understand the type that an "auto" function is really returning in the context of an evocation (i.e.: Right now, I am working with flutter/dart and vscode shows me the inferred type of a variable when hovering with the mouse).
[...]

This is a tooling problem; if an issue hasn't been filed already, it should be filed so that this can be improved.  Technically speaking, it's just a matter of inserting `pragma(msg, typeof(return));` into the function; but of course if this were automated by an IDE plugin that would be ideal.

Note that knowing the concrete type may or may not help you always; sometimes the concrete type may be a complex internal implementation type that may be even harder to understand than reading properly-written docs. :-P  Or sometimes it's a Voldemort type with a generic name like `Result` that doesn't really give you very much information (the point being, if the function was designed properly and used properly, you should not need to care what the actual type is).


T

-- 
Ignorance is bliss... until you suffer the consequences!