March 21, 2012
On Tuesday, 20 March 2012 at 19:02:16 UTC, Andrei Alexandrescu wrote:
> What are your faves? I have a few in mind, but wouldn't want to influence answers.
>
> Thanks,
>
> Andrei

1) inferred types (auto)
2) slices
3) whole > sum(mixin, opDispatch, static if)


March 21, 2012
On 3/20/2012 8:00 PM, Andrei Alexandrescu wrote:
> On 3/20/12 9:47 PM, Walter Bright wrote:
>> And now x is an instance of a voldemort type! It's completely encapsulated.
>
> LOL. Heck, I'd include "Voldemort types" just because it sounds so cool.

Yeah, I'm going to title my next blog entry that!
March 21, 2012
On 2012-03-20 23:58, Nick Sabalausky wrote:
> - Type inference
> - alias
> - foreach
> - Everything about arrays/slices
> - Built-in associative arrays that support nearly any type as a key
> - Reference semantics for classes
> - All the niceities of ctors compared with C++'s ctors
> - Backtick strings
> - Scope guards (And even finally: I head somewhere C++ doesn't even have
> finally: Is that true?!?)
> - GC
> - Name any of D's metaprogramming features
>
> Many of those can seem like simple things, but I'd *hate* to have to get by
> without them. Heck, most of them I now take for granted.
>
> Alias in particular is a much bigger deal than it seems since it's seemingly
> trivial but can be *incredibly* helpful with templates *and* with importing.
>
> Actually, looking at this list, I'm now starting to get a little worried
> about an upcoming C++ project... No doubt I'll be trying to reinvent a lot
> of D in it. Probably in ugly hackish ways.

I did that in one project. I emulated properties, using boost I emulated foreach, auto, lambdas and other features. If you're using C++11 you'll have these features native, expect for properties.

I did the mistake and learned D before I learned C++.

-- 
/Jacob Carlborg
March 21, 2012
"H. S. Teoh" <hsteoh@quickfur.ath.cx> wrote in message news:mailman.949.1332305140.4860.digitalmars-d@puremagic.com...
>
> Yeah, AA's with int keys are like arrays enhanced with O(1)
> insertion/removal and sparse storage (if you have very large indices,
> e.g.). :-) You can even have (pseudo) linear access if you iterate keys
> from 0 to $.

Exactly.

> For example, it lets you accept keys/values that are not strictly the AA's key/value type, but can be implicitly converted to them. It lets you return keys and values without needing the ugly typeinfo and void* casts that are necessary in aaA.d.  This in turn lets you mark many AA methods as pure, and almost all as @safe or @trusted. It lets you cleanly interoperate with types that define opAssign (currently aaA.d does a blind binary copy of data from key/value pointers, which leads to potential bugs when the data has subobjects.)
>
> It also makes it *much* easier to fix many existing AA bugs in the bugtracker. So far, I have working unittests for the following issues: 3824, 3825, 4337, 4463, 5685, 6210, 7512, 7512, 7602, 7632, 7665, 7665, 7704. I haven't looked through all AA-related issues yet; this list may very well grow. :-) To fix these in the current aaA.d implementation can be rather tricky, and quite possibly requires compiler changes.
>

I see. Cool stuff.

> Better yet, I thought of a way of making AA's instantiable at compile-time via CTFE and mixins: this will let you write AA literals that can be evaluated at compile-time and have them turn into object code directly without needing runtime initialization.
>

Ah! Now *that's* fucking awesome! That limitation has kinda stuck out as an odd, annoying wart.

>
>> And even *that* still doesn't work if you don't catch *every* exception (and then rethrow the ones you don't care about? Ick!).
>
> Actually, you can catch "..." and it will catch *everything*. And I believe a single "throw;" will rethrow whatever it is you caught.
>

I see. It has been awhile since I've been in the C++ loop.

>
>> I've seen C++ programmers swear off exceptions because of this, and I can't blame them at all.  Exception systems *need* a finally.
>
> Yeah. "catch(...)" sorta works, but it's very ugly. And while being able to throw *anything* at all is nice (I'm guilty of writing code that throws char*, for example), not being able to make *any* assumptions at all about what you caught (e.g., no common exception superclass with some useful methods, like .msg) is, shall we say, practically useless in a large enough project?
>

Boy, it really has been awhile. I knew you could throw any class object in C++, but I thought that was all. Haxe lets you throw literally anything, even Int, and I found that to be more of a problem than a feature (In very much the same way as VB's ability to change the lower bound of an array: It gains little and just means you have to remember to do the rediculous "UBound(arr) - LBound(arr)".)  Just have a proper Exception class and nothing else should be throwable (D's "Error" notwithstanding).

> (Actually, the lack of .msg was what drove me to throw char*. Obviously checking return codes for every lousy function I call is out of the question, but so is throwing error codes that come from different subsystems, since you've no way of telling which error code scheme to use to look up the error. So I said to myself, why not throw a string that actually tells you what the error is? Furthermore, if these strings were predefined in char arrays that had unique pointer addresses, the value of the pointer itself serves as a kind of "global error number". So this worked as a kind of a poor man's error code + message exception that can be freely thrown around without problems

That is an interesting work around.

> the reason I shied
> away from throwing class objects in the first place was because early
> implementations of C++ had problems that sometimes caused pointer bugs
> and all kinds of nasty side effects when a class object is thrown.

Ouch!

>
> Scope guards rule. Ironically, D's GC mostly alleviates the need for scope guards. :-) They're still immensely useful when you acquire resources that must be cleaned up no matter what happens later. D is the first and only language I know that got resource cleanup done right. Cleanups belong with the acquisition code, not dangling somewhere 200 lines down at the end of the scope, with who knows how many possible leaks in between due to goto's, exceptions, returns, and who knows what!
>

I've even come across at least a couple uses of scope guard that aren't strictly related to releasing resources. Actually, I've just been working with both of them today:

- Temporarily changing a value:

    int bar;
    void foo()
    {
        // Change bar temporarily
        auto saveBar = bar;
        bar = 777;
        scope(exit) bar = saveBar;

        [...do anything here...]
    }

- Timing a section of code. I saw this trick in someone else's code once, loved it, and made a helper tool out of it:

https://bitbucket.org/Abscissa/semitwistdtools/src/4455e019cd95/src/semitwist/util/mixins.d#cl-643

It's a string mixin that, after features and hygenic issues and such, basically boils down to mixing in this psuedo-code:

    if(verbose)
    {
        write(customMessage, "..."); // no newline
        stdout.flush();
        startTimer(); // Using the awesome new std.datetime
    }
    scope(exit) if(verbose)
        writeln(timerInMilliseconds(), "ms");

>
> CTFE even makes it possible to express what many recursive templates express, in pure imperative style. I mean, you can't get any better than this:
>
> int factorial(int n) {
> int result = 1;
> while (n>1) {
> result *= n;
> result--;
> }
> return result;
> }
> enum x = factorial(12); // compile-time computation
> int y = factorial(12); // runtime computation
>
> In C++, you'd have to use recursive templates that are extremely difficult to read and write beyond the simplest of functions.
>

Yup exactly. It's Haskell with bad syntax and compile times. Not only that, but even something as trivial as "if" has to be built out of pure-fp primitives in C++-template-land, whereas D just has: "static if...done!"

Of course, to C++'s credit, its templates (AIUI) weren't really designed for metaprogramming, just for generics. The metaprogramming was just a happy accident (At least that's my understanding, maybe I'm wrong...)

>
>> With C++'s templates, it would appear that you have to use recursion and helper templates for damn near anything.
> [...]
>
> Not to mention the horrible, horrible, syntax that comes with recursive templates. My previous manager used to tell me that as soon as he sees nested templates deeper than 2 levels, his eyes start glazing over, and it all becomes just arcane black magic.
>

Yea. Even a "simpler" use of C++'s templates can feel like staring into the depths of hell: Ever see a loop over a collection using STL iterators? Sheesh. I like the idea behind the STL, but with syntax like that I'd rather use the old "for(int i=0; i<theEnd; i++)". Gimme a proper foreach anyday.

Come to think of it, foreach probably fits the bill for the OP: For people who came from C/C++ like I did, it can seem like a relatively trivial sugar over "for(int i=0; i<theEnd; i++)". But it makes such a difference to just not have to constantly deal with those minute mechanics.

> -- 
> Which is worse: ignorance or apathy? Who knows? Who cares? -- Erich Schubert

lol :) Now that's without a doubt one of my favorites.


March 21, 2012
> It's probably far too early to think about this with all the other
> important issues you're addressing but have you given much thought to
> improving the hashing function?  I haven't hit any issues with the speed of
> the current hasher but better performance is always welcome. MurmurHash
> seems to be all the rage these days with a lot of languages and systems
> adopting it <http://en.wikipedia.org/wiki/MurmurHash> (it compiles down to
> ~52 instructions on x86). It'd be interesting to see benchmarks with it.
> I'm not sure where the current hashing function lives to see what it's like.
>
> Regards,
> Brad Anderson

More throughput but higher latency.
http://codepad.org/kCVQ8eoq
Murmurhash was a little slower than CityHash but
both are a little expensive for very few bytes.
March 21, 2012
On Tuesday, 20 March 2012 at 19:02:16 UTC, Andrei Alexandrescu
wrote:
> I plan to give a talk at Lang.NEXT (http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012) with the subject above. There are a few features of D that turned out to be successful, in spite of them being seemingly unimportant or diverging from related consecrated approaches.
>
> What are your faves? I have a few in mind, but wouldn't want to influence answers.
>
>
> Thanks,
>
> Andrei

. ctfe - mixin
. explain them why templates without "static if" is like a
language without "if".
. string, float and anything that matters can be used as template
parameters.
March 21, 2012
On 03/20/2012 17:43, Walter Bright wrote:
> On 3/20/2012 12:02 PM, Andrei Alexandrescu wrote:
>> What are your faves? I have a few in mind, but wouldn't want to
>> influence answers.
>
> Although array slices have been in D nearly since the beginning, I had
> little idea they would become so darn useful and foundational. They
> originated from an idea by Jan Knepper.
>
> The unexpected utility of them explains why they haven't appeared in
> other languages (yet).

Oh... I remember those early D-Days...
March 21, 2012
On Tuesday, 20 March 2012 at 19:02:16 UTC, Andrei Alexandrescu wrote:
> I plan to give a talk at Lang.NEXT (http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012) with the subject above. There are a few features of D that turned out to be successful, in spite of them being seemingly unimportant or diverging from related consecrated approaches.
>
> What are your faves? I have a few in mind, but wouldn't want to influence answers.
>
>
> Thanks,
>
> Andrei

1. Compile time reflection

This feature enables MessagePack to (de)serialize existing class and struct :)

2. Template friends

Easy syntax, static if(and is), alias,  mixin and other features are very useful.
An essential parts ingredient to write D program.

3. Built-in array and slice

I heavily use this feature in many cases.
Template engine, complex computation and network programming :)


Masahiro
March 21, 2012
On Wednesday, 21 March 2012 at 02:47:20 UTC, Walter Bright wrote:
> Andrei discovered an amazing use of auto. It enables you to create variables with voldemort types "that may not be named".

+1 LOL for Voldemort types



March 21, 2012
On Wednesday, 21 March 2012 at 02:14:26 UTC, Nick Sabalausky wrote:
> Ooh, nested functions and closures are another good one (or two).

I wouldn't call that unlikely, since nested functions are
one of the things I considered a potential killer feature
when I started with D.

(and indeed, it is very useful!)

Nested functions, auto, and scope guards were the
three killers in the pre-D1 that roped me in. And
they rok, oh they rok. But that is "likely success" :)

(well, and fast compilation; going back to Digital Mars
after some years of slow ass g++ was/is heaven)


One that surprised me personally though is import. Indeed,
import is why I passed over D the first time I looked
at it (in 2004 IIRC) - I saw "import" and said "gah
include is fine, eff this Java like poo..

Even when I got into D, I had to give myself comfort
that I can still have #include with mixin(import()) -
something I have never actually wanted to use after
writing the first line of real code.


import is amazing. D gets it all right, even with
stuff like bug 314, it is awesome.



But, is import unlikely success, or is this just a
leftover feeling from my massive bias in the early
days? I have to say it is my bias, since everyone
else uses import and they all know it is good.