July 23, 2015
On 2015-07-23 08:46, ponce wrote:

>> Algebraic data types
>> --------------------
>> Haven't looked into `Algebraic!`, so I won't start bashing D here :)
>> But given the lack of pattern matching, I doubt it will be as pretty
>> as Rust.
>
> You can pattern-match with visit.

I had a look at the example for "visit" and looked at the implementation. I would hardly call that "pattern matching".

-- 
/Jacob Carlborg
July 23, 2015
On Thursday, 23 July 2015 at 06:50:44 UTC, Jacob Carlborg wrote:
> On 2015-07-22 21:41, Jack Stouffer wrote:
>
>> Dub is endorsed by the leadership and is included in the same Github
>> organization as the complier and the standard library
>
> It's not available in the Downloads, Compiler & Tools or Resources sections on dlang.org, so I disagree.

That's because it has its own top-level link in the sidebar, More libraries.  You could argue that's not the best description of dub, but it's certainly prominently placed.
July 23, 2015
On 7/22/2015 11:47 PM, Jacob Carlborg wrote:
> On 2015-07-22 20:47, simendsjo wrote:
>
>> Traits
>> ------
>> I think the ability to express an interface without buying into
>> inheritance is the right move. The alternative in D is specifying the
>> behavior as a template
>
> I completely agree and don't really like the approach D has implemented template
> constraints. Yeah I know, Andrei will destroy this :)

Consider that template constraints can be arbitrarily complex, and can even check behavior, not just a list of function signatures ANDed together. Turns out many constraints in Phobos are of the form (A || B), not just (A && B).


>> and verifying the contract in a unittest for the type.

I am a bit puzzled by the notion of shipping template code that has never been instantiated as being a positive thing. This has also turned up in the C++ static_if discussions.
July 23, 2015
On Wednesday, 22 July 2015 at 18:47:33 UTC, simendsjo wrote:
> Long rant ahead - a bit dipsy..
[snip]

It's one thing to list "nice features", and it's another thing to use these features in production code. As a code base grows, the limitations become more and more obvious. Thus, I would be wary of jumping to conclusions or hailing new features as game changers, before having tested them thoroughly in the real world. Only time will tell, if something really scales. I've learned to wait and see what people with experience report after a year or two of using a given language.
July 23, 2015
On Thursday, 23 July 2015 at 06:46:14 UTC, ponce wrote:
> I've not used Rust, but don't plan to.
>
> On Wednesday, 22 July 2015 at 18:47:33 UTC, simendsjo wrote:
>> While code.dlang.org has 530 packages, crates.io has 2610 packages,
>
> I think this tells something foremost about the size of the community. More people leads to more code.
>


But does it reflect the size of the community? Look at these numbers, below.
D is ranked no 26, Rust is not in the top 50 !!

http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html

Nick
July 23, 2015
Thank you for sharing your impressions! I think posts like this are really useful for the community, because it's important from time to time to take a look outside of the D ecosystem.

I've been watching Rust with interest myself, though I've mostly been a passive observer. Some of it's concept fascinate me. My general impression is that it's a lot stricter than D (good for correctness), but at the cost of expressiveness. I'm going to comment on some of your points below:

On Wednesday, 22 July 2015 at 18:47:33 UTC, simendsjo wrote:

> Cargo
> -----

Very important. Fortunately, dub will be bundled with D in one of the next versions.

>
> Traits
> ------
> I think the ability to express an interface without buying into inheritance is the right move. The alternative in D is specifying the behavior as a template and verifying the contract in a unittest for the type.

Not only that, but Rust does so much more with traits, e.g. closures. They seem to be a simple, yet powerful concept, that a big part of the language is built on.

http://blog.rust-lang.org/2015/05/11/traits.html

On the other hand, it is extremely restrictive in contrast to `static if()` and template constraints. D's approach is a lot more expressive and - at least for me - intuitive.

>
> Macros
> ------
> I haven't written more than extremely simple macros in Rust, but having macros that is possible for tools to understand is a win.  Templates and string mixins is often used for this purpose, but trying to build tools when string mixins exists is probably extremely hard. If D had hygenic macros, I expect several features could be expressed with this instead of string mixins, making tooling easier to implement.

They're certainly cleaner than string mixins. On the other hand, they are really complex (and probably costly to implement, because they need to expose the AST). I don't know how representative it is, but I mostly use them for accessing aggregate members by name in meta-programming:

foreach(member; FieldNameTuple!T) {
    static if(typeof(mixin("T.init." ~ member)) : int) {
        // ...
    }
}

Or sometimes in cases where using recursive templates to build a list is too tedious.

I don't think AST macros would gain us much in D.

>
> Safe by default
> ---------------
> D is often said being safe by default, but D still has default nullable references and mutable by default. I don't see it being possible to change at this stage, but expressing when I want to be unsafe rather than the opposite is very nice. I end up typing a lot more in D than Rust because of this.

@safe by default would be really nice. It's easy to add `@safe:` at the beginning of your file, but large parts of e.g. vibe.d are not annotated and need to be called from @system functions. Maybe more inference would help here, too.

>
> Pattern matching
> ----------------
> Ooooh... I don't know what to say.. D should definitely look into implementing some pattern matching! final switch is good for making sure all values are handled, but deconstructing is just so ergonomic.

Yes, and it goes hand in hand with a more handy tuple syntax.

>
> Expressions
> -----------
> This probably also falls in the "too late" category, but statements-as-expressions is really nice. `auto a = if ...` <- why not?

Generally I find this an elegant concept. But in Rust, it leads to the distinction between expressions terminated with `;` and those without, which in turn makes it necessary to use braces even if you have only one statement or expression. This is something that I dislike very much.

>
> Borrowing
> ---------
> This is probably the big thing that makes Rust really different.  Everything is a resource, and resources have an owner and a lifetime. As a part of this, you can either have multiple aliases with read-only references, or a single reference with a writeable reference. I won't say I have a lot of experience with this, but it seems like it's not an extremely unergonomic trade-off. I cannot even remotely imagine the amount of possible compiler optimizations possible with this feature.

Yes. I haven't given up hope that we can introduce a simplified version of this in D. It doesn't need to be as strict and pervasive as Rust's system. I'm still thinking about how to reduce that into something less complex without breaking too many of the guarantees it provides.
July 23, 2015
On 7/22/15 5:36 PM, jmh530 wrote:
> On Wednesday, 22 July 2015 at 20:43:04 UTC, simendsjo wrote:
>> When "everything" is an expressions, you can write things like
>>     auto a = if(e) c else d;
>>
>> In D you have to write
>>     type a = invalid_value;
>>     if(e) a = c;
>>     else  a = d;
>>     assert(a != invalid_value);
>>
>
>
> I prefer this example from one of the various Rust tutorials
>
> let foo = if x == 5 {
>                  "five"
>            }
>            else if x == 6 {
>                  "six"
>            }
>            else {
>                  "neither"
>            }
>
> You're basically using a conditional expression as an rvalue. You can do
> the same thing with a { } block.

I used to be quite jazzed about the everything-is-an-expression mantra, but it's not all great.

1. Inferring function return types when everything is an expression (i.e. last expression there is the return type) may yield WAT results.

2. Defining a result type for loops is awkward.

At the end of the day everything-is-an-expression is natural for functional languages, but doesn't seem it makes a large difference to an imperative language.

To OP: thanks for your rant! Instead of getting defensive we'd do good to derive action items from it.


Andrei

July 23, 2015
On Wednesday, 22 July 2015 at 21:04:57 UTC, simendsjo wrote:
> :) The example was written to save space. I recon you understand what I mean.

Yeah, but the if/else is one of the most useful examples of it, and is covered by ?:, so the whole thing becomes less compelling then.

The other places where I've used it in languages that support it are little blocks crammed into a line and sometimes exception grabbing... but still, the value isn't that great.
July 23, 2015
On 7/22/15 7:47 PM, rsw0x wrote:
> On Wednesday, 22 July 2015 at 18:47:33 UTC, simendsjo wrote:
>> ...
>
> I think rust makes the ugliness of D's "push everything into phobos for
> simplicity" become very visible. D and Rust share many equal constructs,
> but D's is almost always uglier.

Care for a list? Thanks! -- Andrei

July 23, 2015
On Thursday, 23 July 2015 at 13:30:49 UTC, Andrei Alexandrescu wrote:
> At the end of the day everything-is-an-expression is natural for functional languages, but doesn't seem it makes a large difference to an imperative language.
>

Good points.