May 12, 2022
On Wednesday, 11 May 2022 at 05:41:35 UTC, Ali Çehreli wrote:
> What are you stuck at? What was the most difficult features to understand? etc.
>
> To make it more meaningful, what is your experience with other languages?
>
> Ali

When i take old library from a dub or github and cannot compile it with latest compiler because of small and subtle language changes.

For example
https://github.com/buggins/dlangide/pull/410/commits/43a82ed2f45143270482aa94c447e577174f0108#diff-375ecd44ef501b93adc6106fe404f55d353e667c21681c1c13a9e2008510ab42L937

I dont know even now, which D's features changes here.
May 12, 2022
On Wednesday, 11 May 2022 at 05:41:35 UTC, Ali Çehreli wrote:
> What are you stuck at? What was the most difficult features to understand? etc.
>
> To make it more meaningful, what is your experience with other languages?
>
> Ali

Overhall I think that D was not hard to learn because well designed (i.e intuitive).

A few specific points however that I remember

- Certain variant forms of the `is` Expression are not obvious (not intuitive), I'm pretty sure I still cant use them without a quick look to the specs.

- Operator overloading in certain cases was confusing, I remember that for one particular form once I had to use your book instead of the official specs (when opSlice and opIndex are combined)

The main difficulty I had is actually not specific to D. It was to accept that a GC is OK.
May 12, 2022
Some keywords are overloaded and have different meaning when used in a different place.
Also some syntactic-sugar is way to much meaning too many different ways to do the same thing. I would prefer one way which is advised.
May 12, 2022
On Thursday, 12 May 2022 at 11:50:59 UTC, Alain De Vos wrote:
> Some keywords are overloaded and have different meaning when used in a different place.
> Also some syntactic-sugar is way to much meaning too many different ways to do the same thing. I would prefer one way which is advised.

`ptr1 is ptr2` VS `is(T==U)` is ok even if the keyword is reused for two different things.

Problem is more (from https://dlang.org/spec/expression.html#is_expression)

```
is ( Type : TypeSpecialization , TemplateParameterList )
is ( Type == TypeSpecialization , TemplateParameterList )
is ( Type Identifier : TypeSpecialization , TemplateParameterList )
is ( Type Identifier == TypeSpecialization , TemplateParameterList )
```

I never remember those variants, because basically you never need them...
They were required for std.traits and that's it.
May 12, 2022
On Thursday, 12 May 2022 at 12:13:32 UTC, Basile B. wrote:
> On Thursday, 12 May 2022 at 11:50:59 UTC, Alain De Vos wrote:
>> Some keywords are overloaded and have different meaning when used in a different place.
>> Also some syntactic-sugar is way to much meaning too many different ways to do the same thing. I would prefer one way which is advised.
>
> `ptr1 is ptr2` VS `is(T==U)` is ok even if the keyword is reused for two different things.
>
> Problem is more (from https://dlang.org/spec/expression.html#is_expression)
>
> ```
> is ( Type : TypeSpecialization , TemplateParameterList )
> is ( Type == TypeSpecialization , TemplateParameterList )
> is ( Type Identifier : TypeSpecialization , TemplateParameterList )
> is ( Type Identifier == TypeSpecialization , TemplateParameterList )
> ```
>
> I never remember those variants, because basically you never need them...
> They were required for std.traits and that's it.

Perfect example of reuse that is never a problem : `final`.

what statically does `is` should have been several `__traits` I think.
May 12, 2022
On Thursday, 12 May 2022 at 11:05:08 UTC, Basile B. wrote:
> On Wednesday, 11 May 2022 at 05:41:35 UTC, Ali Çehreli wrote:
>> What are you stuck at? What was the most difficult features to understand? etc.
>>
>> To make it more meaningful, what is your experience with other languages?
>>
>> Ali
>
> Overhall I think that D was not hard to learn because well designed (i.e intuitive).

 I concur..

> A few specific points however that I remember
>
> - Certain variant forms of the `is` Expression are not obvious (not intuitive), I'm pretty sure I still cant use them without a quick look to the specs.

Yes indeed, had to read through the then excellent pdf()https://github.com/PhilippeSigaud/D-templates-tutorial by Philippe Sigaud (of PEG) to grasp the whole idea first, and still have to look it up when the need to use it arises...

>
> - Operator overloading in certain cases was confusing, I remember that for one particular form once I had to use your book instead of the official specs (when opSlice and opIndex are combined)

Indeed same experience. Also opCmp and opEquals caused some confusion.

D's [][] !== C's [][],

Range peculiarities w.r.t some algo's (algo want's fwdRange but got inputRange but did not have the constraint ea)

lazy vs eager algorithms (the need to call .array)
>
> The main difficulty I had is actually not specific to D. It was to accept that a GC is OK.

Nice one.

I recon I have to think much harder sometimes to know where the data is and 'who' has access: stack heap tls mutexed or not whatever, but find myself almost never asking this question anymore in D, which I use(d) to do almost all the time in c++ land. The need for it is almost removed by D.


May 12, 2022
On Thursday, 12 May 2022 at 11:05:08 UTC, Basile B. wrote:
> - Certain variant forms of the `is` Expression are not obvious (not intuitive), I'm pretty sure I still cant use them without a quick look to the specs.

That one was a trouble to hear about => http://p0nce.github.io/d-idioms/#Get-parent-class-of-a-class-at-compile-time



May 12, 2022

On Wednesday, 11 May 2022 at 05:41:35 UTC, Ali Çehreli wrote:

>

What are you stuck at? What was the most difficult features to understand? etc.

I came from shell scripts. They grew too large and overly complex when I wanted to do non-trivial things in a neat way, so I looked to proper programming languages and arbitrarily settled on D over python and similar. So for me the norm is D, and everything else is "other languages".

That said, one thing I cannot seem to firmly wrap my head around is is expressions. is does so many things. There's probably more intricate examples of how it's confusing, but I don't know it well enough to construe one:

alias AA = long*[string];
static if (is(AA whatEvenGoesHere : VP[K], VP, K))
{
    static if(is(VP : V*, V))
    {
        assert(is(V));
    }
}

The one thing that has caused me most anguish and woe is hands-down https://issues.dlang.org/show_bug.cgi?id=18026 though. It hasn't bit me for a while now, but the feeling of uncertainty, that the compiler might just suddenly after an innocent change no longer compile your project, seemingly outside of your control, is just... disheartening when it happens.

May 12, 2022

On Thursday, 12 May 2022 at 14:06:13 UTC, Arjan wrote:

>

On Thursday, 12 May 2022 at 11:05:08 UTC, Basile B. wrote:

>

On Wednesday, 11 May 2022 at 05:41:35 UTC, Ali Çehreli wrote:

  • Operator overloading in certain cases was confusing, I remember that for one particular form once I had to use your book instead of the official specs (when opSlice and opIndex are combined)

I still have the thing :

/**
 * CharMap is an helper struct that allows to test
 * if a char is within a set of characters.
 */
struct CharMap
{
    private bool[] _map;
    private dchar _min, _max;

    private void setMinMax(dchar value) pure nothrow @safe
    {
        if (value <= _min) _min = value;
        else if (value >= _max) _max = value;
        _map.length = _max + 1 - _min;
    }

    /**
     * Used in the construction process.
     *
     * Params:
     *      lo = The dchar that defines the range lower bound.
     *      hi = The dchar that defines the range upper bound (inclusive).
     *
     * Examples:
     * ---
     * CharMap cm = CharMap['0'..'9'];
     * ---
     */
    static CharRange opSlice(int index)(dchar lo, dchar hi) pure nothrow @safe @nogc
    {
        return CharRange(lo, hi);
    }

    /**
     * Used in the construction process.
     *
     * Params:
     *      a = A list made of character slices, of single characters or
     *
     * any other values whose type is implicitly convertible to dchar.
     *
     * Examples:
     * ---
     * CharMap cm = CharMap['0'..'9', '.', 'f', 'd', 38, 39];
     * ---
     */
    static CharMap opIndex(A...)(A a) pure nothrow @safe
    {
        CharMap result;

        // bounds
        foreach(elem; a)
        {
            alias T = typeof(elem);
            static if (isSomeChar!T || isImplicitlyConvertible!(T, dchar))
            {
                result.setMinMax(elem);
            }
            else static if (is(T == CharRange))
            {
                result.setMinMax(elem._min);
                result.setMinMax(elem._max);
            }
            else static assert(0, "unsupported opIndex argument type: " ~ T.stringof);
        }

        result._map[] = false;
        foreach(elem; a)
        {
            alias T = typeof(elem);
            static if (isSomeChar!T || isImplicitlyConvertible!(T, dchar))
                result._map[elem - result._min] = true;
            else static if (is(T == CharRange))
            {
                foreach(size_t i; elem._min - result._min .. elem._max - result._min + 1)
                    result._map[i] = true;
            }
        }
        return result;
    }

    /**
     * Returns true if a character is within the map.
     *
     * Params:
     *      c = A character or any value convertible to a dchar.
     */
    bool opBinaryRight(string op = "in", C)(C c) const pure nothrow @safe @nogc
    if (op == "in")
    {
        static if (isSomeChar!C || isImplicitlyConvertible!(C, dchar))
        {
            if (_min > c || c > _max) return false;
            else return _map[c - _min];
        }
        else static assert(0, `invalid argument type for CharMap.opBinaryRight!"in"(): ` ~ C.stringof);
    }
}
///
pure @safe unittest
{
    CharMap cm = CharMap['a'..'f', '0'..'9' , 'A'..'F', '_', 9];
    assert('a' in cm);
    assert('b' in cm);
    assert('c' in cm);
    assert('d' in cm);
    assert('e' in cm);
    assert('f' in cm);
    assert('g' !in cm);
    assert('A' in cm);
    assert('B' in cm);
    assert('C' in cm);
    assert('D' in cm);
    assert('E' in cm);
    assert('F' in cm);
    assert('G' !in cm);
    assert('0' in cm);
    assert('4' in cm);
    assert('9' in cm);
    assert('_' in cm);
    assert('%' !in cm);
    assert('\t' in cm);
}
May 12, 2022
On Thursday, 12 May 2022 at 14:42:43 UTC, Anonymouse wrote:
> That said, one thing I cannot seem to firmly wrap my head around is `is` expressions. `is` does so many things.

It is simpler than it looks, I wrote about it in my book and in a post here:

https://forum.dlang.org/post/xklcgjaqggihvhctczxx@forum.dlang.org

> ```
> alias AA = long*[string];
> static if (is(AA whatEvenGoesHere : VP[K], VP, K))

You don't have to put anything there. The is expression kinda parallels declarations, so that thing would be the name for the newly declared symbol. But you don't need to declare a new symbol there so you can leave it blank; most the pieces are optional.

> The one thing that has caused me most anguish and woe is hands-down https://issues.dlang.org/show_bug.cgi?id=18026 though.

yeah bugs happen.