February 09, 2018
On Friday, 9 February 2018 at 07:54:49 UTC, Suliman wrote:
> I like D, but sometimes it's look like for me too complicated. Go have a lot of fans even it not simple, but primitive. But some D futures make it very hard to learning.
>
> Small list by me:
> 1. mixins
> 2. inout
> 3. too many attributes like: @safe @system @nogc etc
>
> Which language futures by your opinion make D harder?

My top 4:

- Unclear error messages
- Unfinished parts of language  (ex: shared?)
- Ambiguous things (ex: @property)
- Things that need an upgrade but are still there (ex: containers, xml, ...)


February 09, 2018
On Friday, 9 February 2018 at 13:34:01 UTC, tetyys wrote:
> On Friday, 9 February 2018 at 13:10:16 UTC, rumbu wrote:
>>
>> And not a language feature but I hate dub. Just saying.
>
> Why do people hate dub? I think it's a great package manager and build tool

1. Keeps data in the %APPDATA%/Roaming folder. Connecting my computer to the company network means that AD will sync zillions of files on the company profile server. This issue is 4 years old: https://github.com/dlang/dub/issues/229
2. It's painfully slow.
3. As a library provider, you have a lot to learn about configuration file format (2 formats).
4. Not integrated in Visual Studio. I know, I am a lazy and convenient Windows user and the small black window called cmd scares the sh*t out of me.
February 09, 2018
On Friday, 9 February 2018 at 07:54:49 UTC, Suliman wrote:
> Which language futures by your opinion make D harder?

shared.
February 09, 2018
On Friday, 9 February 2018 at 07:54:49 UTC, Suliman wrote:
> I like D, but sometimes it's look like for me too complicated. Go have a lot of fans even it not simple, but primitive. But some D futures make it very hard to learning.
>
> Small list by me:
> 1. mixins
> 2. inout
> 3. too many attributes like: @safe @system @nogc etc
>
> Which language futures by your opinion make D harder?

Is D really over-complicated? I'm not really sure.

As someone who writes a bit about corner-cases and traps, I feel that there isn't nearly enough content to author an "Effective D" book.

However I feel like D is very long to learn because, like a control panel with many buttons, you have to become intimate with every feature and where to apply them - and D has a lot of buttons. For example when to use "alias this" is a blurry judgement call that have to be finetuned.

It's a long integrative process to use D effectively, but you can mostly write useful programs from day one which I think is interesting.

Of course I've a personal list of things that could be removed, but let's bet it won't match anybody else's kill list :)
February 09, 2018
On Friday, 9 February 2018 at 14:01:23 UTC, Andrea Fontana wrote:
> [snip]
> - Unfinished parts of language  (ex: shared?)

I see this a lot, but I don't really use shared so I always forget how exactly it is unfinished. If there are unfinished parts of the language, it couldn't hurt to put in the wiki how exactly they are unfinished so that people don't need to keep asking.
February 09, 2018
On Friday, 9 February 2018 at 07:54:49 UTC, Suliman wrote:
> Which language futures by your opinion make D harder?

Too many choices.  I tend to obsess over the best way to do something, and when the language gives me several options I want to try them all.  One example is constants (that would typically be #define in C).  From reading forum posts, I've seen many suggest:
const auto MAX_IN = 20;

Others say to use enums.  It turns out enums seems to be the best, as they don't create a symbol in the object file, but const auto does.  The docs say using "private" will keep the symbol out of the file, but that is not true.
https://dlang.org/spec/attribute.html#static


February 09, 2018
On Friday, 9 February 2018 at 14:59:38 UTC, Ralph Doncaster wrote:
> The docs say using "private" will keep the symbol out of the file, but that is not true.
> https://dlang.org/spec/attribute.html#static

That sentence isn't well written since D's private and C's static  are different... what D's private does is make the symbol invisible to other D files; when you import the module, it doesn't import the private names so it acts like they don't exist.

But they do still exist in the object file. I'm pretty sure C's statics do too actually just without an exported name...
February 09, 2018
On Friday, February 09, 2018 14:48:36 jmh530 via Digitalmars-d wrote:
> On Friday, 9 February 2018 at 14:01:23 UTC, Andrea Fontana wrote:
> > [snip]
> > - Unfinished parts of language  (ex: shared?)
>
> I see this a lot, but I don't really use shared so I always forget how exactly it is unfinished. If there are unfinished parts of the language, it couldn't hurt to put in the wiki how exactly they are unfinished so that people don't need to keep asking.

The memory model needs to be properly defined like C++ finally did. It works without that, but as I understand it, it's technically relying too much on implementation-defined behavior.

I'm not sure if shared produces an error in all of the cases that it's supposed to, but it might.

The druntime stuff related to shared (like mutexes, conditional variables, and threads) isn't necessarily marked up like it should be, though some work has been done on that with the past few releases, so it's at least better, and it might be finished, but I'd have to dig through it to be sure.

There are some issues with shared with regards to stuff like destructors which need to be sorted out. IIRC, a partial fix for that went in a few months ago but causes other problems.

Synchronized classes haven't been fully implemented, so there is no mechanism for shared to be implicitly cast away (though honestly, I don't think that synchronized classes would do a good enough job of that to make a significant difference, since they can only strip away the outer layer of shared).

I think that the biggest thing is simply that too many folks don't understand how to use it properly. They get compilation errors when they try to use it and get mad about it and end up using __gshared, which is just begging for bugs, because unless you're dealing with a C global, you're almost certainly subverting the type system, since the variable is still treated as thread-local by the type system even though it isn't.

The reality of the matter is that shared is _supposed_ to result in a bunch of compilation errors when you try to do stuff to it. You're supposed to either use atomics to mutate a shared object or protect it with a mutex and temporarily cast away shared so that you can actually do stuff with it. You're really not supposed to do much with a shared object while it's shared, and a lot of folks don't understand that.

It would be really nice if the language had a better way to implicitly remove shared when the object was properly protected by a mutex rather than requiring an explicit cast, but that's _really_ hard to do (which is why synchronized classes can only strip away the outer layer of shared). So, ultimately, I expect that we're going to be stuck with having to use explicit casts when using shared objects.

So, there are some rough edges in the implementation (both in the compiler and the runtime) which need to be fixed for shared to work as well as it should, but the design itself is generally solid. It's more a question of folks not understanding how to use it properly and getting mad when the compiler prevents them from doing stuff that's not thread-safe.

I suspect that part of why the lingering implementation issues haven't been fixed is simply because so few programs actually need shared objects. It's debatable how much of a success shared has been, but having everything be thread-local by default has been a smashing success for the most part.

- Jonathan M Davis

February 09, 2018
On Friday, 9 February 2018 at 13:53:51 UTC, Seb wrote:
> On Friday, 9 February 2018 at 13:10:16 UTC, rumbu wrote:
>> On Friday, 9 February 2018 at 08:27:21 UTC, Nick Sabalausky (Abscissa) wrote:
>>
>>> Defining input ranges (one of my biggest pet peeves):
>>>
>>> C# knocked it out of the park ages ago with its design for a stackless!!! (ie no-fibers) coroutine syntax. There's no reason the same approach couldn't be used in D for creating input ranges.
>>
>> I'm missing too the yield return and await syntax in D every time.
>
> What's wrong with the library solution from std.concurrency?


let's take the D's example from std.concurrency:

static void spawnedFunc(Tid ownerTid)
{
    receive((int i){
        received = text("Received the number ", i);

        // Send a message back to the owner thread
        // indicating success.
        send(ownerTid, true);
    });
}

rough C# translation:

async void spawnedFunc()
{
    int i = await receive();
}


> All good point. A few questions:
>
>> - alias this;
>
> Do you mean no multiple alias this or the problem with overloading?

When I learnt D first time, it was a very difficult concept for me. Personally I don't find any use of it today.

>
>> - everything is a range. If not, we will rangify it.
>
>> Autodecoded eventually.
>
> No one likes it, but you can opt-out with byCodeUnit - that doesn't work for you?

This topic was about how difficult is D to learn. Due to the obsessive "range them all" politics, you cannot really use most of the D library functions if you don't understand very well range concepts. And after you learn them, you'll have autodecoding surprises.

>
>> - no dedicated syntax sugar for ranges;
>
> What do you expect here?
> (also it's not entirely true - foreach already supports ranges)
>
>> - no dedicated syntax sugar for coroutines;
>
> What syntax sugar that can't be done by a library do you expect?

Let's take a classic range in D:

struct FibonacciRange(int limit)
{
    int a = 1, b = 1;

    bool empty() const @property
    {
       return a > limit;
    }

    int front() const @property
    {
        return a;
    }

    void popFront()
    {
        auto t = a;
        a = b;
        b = t + b;
    }
}

C#:

IEnumerable<int> Fibonacci(int limit)
{
   int a = 1, b = 1;
   while (a < limit)
   {
     yield return a;  //syntactic sugar
     var t = a;
     a = b;
     b = t + b;
   }
}

>
>> - no dedicated syntax sugar for events;
>
> What syntax sugar that can't be done by a library do you expect?
> await?

D library is using signals instead of events. Personally I find events easier to learn.

February 09, 2018
On Friday, 9 February 2018 at 14:59:38 UTC, Ralph Doncaster wrote:

> const auto MAX_IN = 20;

const MAX_IN = 20;

The auto is superfluous and is only needed when there's no storage class or type.

>
> Others say to use enums.  It turns out enums seems to be the best, as they don't create a symbol in the object file, but const auto does.

If you need to take the address of a constant, use immutable or const (doesn't really matter, but I prefer immutable). If you don't need the address, use enum.