digitalmars.D - Three Unlikely Successful Features of D
- Andrei Alexandrescu (9/9) Mar 20 2012 I plan to give a talk at Lang.NEXT
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= (6/15) Mar 20 2012 In no particular order: Lazy values, guaranteed initialization, scope
- Dmitry Olshansky (5/12) Mar 20 2012 To throw in a few:
- Jesse Phillips (4/7) Mar 20 2012 I like this list. And add, the template shorthand to!(int)() ->
- bcs (2/15) Mar 20 2012 that and d2 operator overloading.
- maarten van damme (6/6) Mar 20 2012 I really like the $ opperator on slices. It's something small and looks
- H. S. Teoh (9/17) Mar 20 2012 [...]
- Don (17/26) Mar 20 2012 There's one huge one.
- Don (5/35) Mar 20 2012 Note that because it was so successful, it was incorporated into static
- Brad Roberts (6/11) Mar 20 2012 I wrote the original msg part of assert and static assert. It wasn't
- dsimcha (13/13) Mar 20 2012 1. Scope guards. The need to execute some code at the end of a
- H. S. Teoh (7/23) Mar 20 2012 [...]
- Walter Bright (6/7) Mar 20 2012 Although array slices have been in D nearly since the beginning, I had l...
- Andrei Alexandrescu (3/11) Mar 20 2012 Go has slices. (Unlike D slices, they include capacity.)
- Walter Bright (4/16) Mar 20 2012 Can you, in Go:
- bcs (4/21) Mar 20 2012 3. have arbitrary overlapping slices?
- Jan Knepper (2/10) Mar 21 2012 Oh... I remember those early D-Days...
- Kagamin (7/15) Mar 21 2012 As to me, slices are the most important feature of D, and they
- F i L (26/27) Mar 20 2012 opDispatch was expectantly successful for me. I haven't seen it
- deadalnix (2/11) Mar 20 2012 To me it is pragma(msg, blabla) and slices.
- Piotr Szturmaj (3/18) Mar 20 2012 Yes, pragma(msg, ...) is very handy when debugging templates and generic...
- Andrej Mitrovic (5/7) Mar 20 2012 Here's one: C compatibility.
- David (7/7) Mar 20 2012 I really love CTFE, even though it's sometimes pretty slow, maybe
- Andrej Mitrovic (5/6) Mar 20 2012 Now a real one: auto type inference. Could you possibly imagine what
- Nick Sabalausky (19/19) Mar 20 2012 - Type inference
- Walter Bright (4/6) Mar 20 2012 I'd have to agree with this. I find it amazing that other languages enti...
- Nick Sabalausky (4/12) Mar 20 2012 I particulary love how D's alias is used to disambiguate symbol conflict...
- H. S. Teoh (61/75) Mar 20 2012 Yeah I forgot about this one. Being able to write:
- Nick Sabalausky (41/118) Mar 20 2012 Yea, C++'s STL *needs* type inference and alias. At least the new spec h...
- Nick Sabalausky (7/9) Mar 20 2012 And AIUI, even *that* doesn't work in C++ because, IIRC, the class hiera...
- H. S. Teoh (107/187) Mar 20 2012 Yeah, AA's with int keys are like arrays enhanced with O(1)
- Nick Sabalausky (57/137) Mar 21 2012 Exactly.
- Walter Bright (3/6) Mar 21 2012 You're correct. Metaprogramming was an emergent property of C++ template...
-
Brad Anderson
(13/25)
Mar 20 2012
On Tue, Mar 20, 2012 at 10:47 PM, H. S. Teoh
wr... - Martin Nowak (4/17) Mar 21 2012 More throughput but higher latency.
- Brad Anderson (4/23) Mar 21 2012 Interesting. Thanks for the link.
- H. S. Teoh (17/26) Mar 21 2012 [...]
- Sean Kelly (16/18) Mar 21 2012 important issues you're addressing but have you given much thought to =
- Nick Sabalausky (4/13) Mar 21 2012 People still use SPARC?
- Sean Kelly (3/19) Mar 21 2012 Yup. Though these days it seems more common to use x86 Solaris instead,...
- Jacob Carlborg (4/5) Mar 21 2012 Would it be possible to use different algorithms on different platforms?
- Jonathan M Davis (9/18) Mar 21 2012 I'm sure that it would be, but it sounds like part of his complaint is t...
- Sean Kelly (10/15) Mar 21 2012 because the site had no copyright license for the code (a mistake that =
- H. S. Teoh (7/19) Mar 21 2012 [...]
- Walter Bright (12/22) Mar 20 2012 Andrei discovered an amazing use of auto. It enables you to create varia...
- Andrei Alexandrescu (3/11) Mar 20 2012 LOL. Heck, I'd include "Voldemort types" just because it sounds so cool.
- Walter Bright (2/5) Mar 20 2012 Yeah, I'm going to title my next blog entry that!
- Andrej Mitrovic (8/9) Mar 20 2012 It's funny how the book explicitly stated that this doesn't work (page 2...
- Patrick Down (2/4) Mar 21 2012 +1 LOL for Voldemort types
- Don Clugston (4/32) Mar 21 2012 That idiom is already built into the language. Anonymous nested classes
- Walter Bright (3/8) Mar 21 2012 True, but it's the ability to return them from a function that's new & c...
- Don (3/17) Mar 21 2012 BTW what is 'nested' about anonymous nested classes? They seem to work
- Timon Gehr (4/6) Mar 21 2012 Seems reasonable.
- Jacob Carlborg (7/26) Mar 21 2012 I did that in one project. I emulated properties, using boost I emulated...
- Adam D. Ruppe (56/56) Mar 20 2012 What you might want to do is look back at
- Adam D. Ruppe (6/9) Mar 20 2012 LOL, I was bloviating about "enum" and ended up
- Nick Sabalausky (11/25) Mar 20 2012 Yea, that's a good one. I seem to remember initally thinking that it fel...
- Adam D. Ruppe (25/27) Mar 21 2012 I wouldn't call that unlikely, since nested functions are
- Walter Bright (5/9) Mar 21 2012 I knew import would be good :-)
- Jacob Carlborg (5/9) Mar 21 2012 I've never been able to properly handle includes in C/C++. Import is SO
- Kapps (20/30) Mar 21 2012 On the topic of import, mixin imports are something that I
- F i L (5/6) Mar 21 2012 I've thought about that before. It would be great to have fully
- Nick Sabalausky (4/9) Mar 21 2012 That hits on the one irritating limitation of CTFE: No I/O. So that cach...
- F i L (7/20) Mar 21 2012 Didn't realize that. Well until IO in CTFE is possible,
- Timon Gehr (7/18) Mar 21 2012 I once cached CTFE results by wrapping some templates into another
- Jacob Carlborg (6/11) Mar 21 2012 I've been thinking on that as well since I'm writing a tool for
- F i L (7/9) Mar 21 2012 That would probably be a better option I think. In fact,
- Nick Sabalausky (4/32) Mar 21 2012 Oh yea, definitely. I'm already using HTML mixin imports for the little ...
- Adam D. Ruppe (9/12) Mar 21 2012 I use a *lot* of import() (one of my work projects imports()
- Tove (1/5) Mar 21 2012 Definitely.... mixin imports and ctfe gets my 3 votes!
- Nick Sabalausky (13/24) Mar 21 2012 Yea. It especially would have been great back when I was doing GBA homeb...
- Adam D. Ruppe (35/38) Mar 22 2012 Now, this reminds me, what if you want to access the
- Nick Sabalausky (3/41) Mar 22 2012 Clever idea, I like it.
- Nick Sabalausky (17/24) Mar 21 2012 The main thing that grabbed me in the pre-D1 days was the lack of header...
- Adam D. Ruppe (21/24) Mar 21 2012 Aye, that's a nice touch.
- Nick Sabalausky (6/10) Mar 21 2012 Heh, yea. I think in a way that's kind of the problem with C++: It can b...
- Jesse Phillips (5/12) Mar 22 2012 I take that feature for granted! Try using it in other languages
- bearophile (9/13) Mar 20 2012 After thinking some time about this, I can't find one of them :-)
- Rene Zwanenburg (66/75) Mar 20 2012 I've seen most of D's cool features mentioned, but I believe
- Rene Zwanenburg (4/83) Mar 20 2012 And there goes the formatting, here's a pastebin version:
- Jay Norwood (8/12) Mar 20 2012 I'll have to say its whatever it is ( and I don't know what it
- Joshua Niehus (5/9) Mar 20 2012 1) inferred types (auto)
- so (7/16) Mar 21 2012 . ctfe - mixin
- Masahiro Nakagawa (13/22) Mar 21 2012 1. Compile time reflection
- Steven Schveighoffer (14/21) Mar 21 2012 The two that I would cite are auto and slice syntax. I see others have ...
- Walter Bright (3/5) Mar 21 2012 Yes, Andrei was the lone advocate of that for a while. Everyone else poo...
- Andrei Alexandrescu (3/9) Mar 21 2012 I appreciate you implemented it in spite of not finding it compelling.
- pillsy (42/47) Mar 21 2012 I know people have said all of these already, but I still want to
- F i L (33/33) Mar 21 2012 Another feature I like a lot about D, is it's approach to nested
- F i L (26/26) Mar 21 2012 And for my third favorite (in no order), I like custom
- Dmitry Olshansky (5/8) Mar 21 2012 Sorry to spoil the excitement, but aren't they deprecated?
- F i L (7/14) Mar 21 2012 Come on, really? What's the reason for this? I did here about
- Nick Sabalausky (4/17) Mar 21 2012 There's a new custom allocator system being worked on. And there's alrea...
- Andrei Alexandrescu (3/5) Mar 21 2012 They don't exist anymore.
- deadalnix (2/7) Mar 21 2012 And we are waiting for the replacement !
- Andrei Alexandrescu (4/11) Mar 21 2012 It's official:
- Andrej Mitrovic (3/5) Mar 21 2012 "Go In Three Easy Pieces" followed by "Three Unlikely Successful Feature...
- Andrej Mitrovic (6/8) Mar 21 2012 Hey here's a big one: Phobos. Or maybe both Phobos and D2. I don't
- Matt Peterson (8/17) Mar 22 2012 It isn't mainline yet, but UFCS from git has made working with
- bearophile (14/20) Mar 22 2012 I suggest to compile all your D2 code with -wi (or -w) and
- Matt Peterson (7/15) Mar 23 2012 Already using -w, and I thought I was using -property. I am now,
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
Mar 20 2012
On 20-03-2012 20:02, 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, AndreiIn no particular order: Lazy values, guaranteed initialization, scope guards, perhaps array slices, alias this / single inheritance, unittest blocks. -- - Alex
Mar 20 2012
On 20.03.2012 23:02, 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.To throw in a few: Scope guards, opDispatch, alias and _string_ template parameters. -- Dmitry Olshansky
Mar 20 2012
On Tuesday, 20 March 2012 at 19:50:25 UTC, Dmitry Olshansky wrote:To throw in a few: Scope guards, opDispatch, alias and _string_ template parameters.I like this list. And add, the template shorthand to!(int)() -> to!int() and q{} strings (though I need to remember them more often.
Mar 20 2012
On 03/20/2012 12:50 PM, Dmitry Olshansky wrote:On 20.03.2012 23:02, Andrei Alexandrescu wrote:that and d2 operator overloading.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.To throw in a few: Scope guards, opDispatch, alias and _string_ template parameters.
Mar 20 2012
I really like the $ opperator on slices. It's something small and looks rather unneeded. When I was dealing with java I never even wished it was there but when I came to d and did some array manipulation I was really glad we had that $ sign. I regularly use it and I don't seem to be the only one feeling that way. Maarten
Mar 20 2012
On Tue, Mar 20, 2012 at 02:02:15PM -0500, 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.[...] By far: CTFE. Unittest blocks, extended concept of purity, template syntax (as opposed to C++'s ugly mess), all types have a default value (.init - makes it so painless to write generic code!), scope guards. T -- I am a consultant. My job is to make your job redundant. -- Mr Tom
Mar 20 2012
On 20.03.2012 20:02, 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, AndreiThere's one huge one. Strings as built-in types, including concatenation and slicing. This meant that they could be constant-folded. Together with 'static if', this was the basis of metaprogramming in D. Pretty much all the rest was a natural consequence of that foundation. It was *completely* unexpected. When, as a D newbie, I posted some of my initial exploration of the language, Walter wrote "I had no idea this was even possible." Probably not what you have in mind, though -- it *was* expected to be a success, just not to anything like this extent. * pragma(msg) is something that's been used 100X as often as anticipated. * Builtin properties of types, eg int.max. Doesn't sound like much of an improvement over a header file of constants, but it's had a huge impact. It really encourages you to write correct code, (I especially notice it for floating point, but I bet if you grep for "int.max" in D code, you'll get far more hits than for "MAXINT" in C code).
Mar 20 2012
On 20.03.2012 21:33, Don wrote:On 20.03.2012 20:02, Andrei Alexandrescu wrote:Note that because it was so successful, it was incorporated into static assert.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, AndreiThere's one huge one. Strings as built-in types, including concatenation and slicing. This meant that they could be constant-folded. Together with 'static if', this was the basis of metaprogramming in D. Pretty much all the rest was a natural consequence of that foundation. It was *completely* unexpected. When, as a D newbie, I posted some of my initial exploration of the language, Walter wrote "I had no idea this was even possible." Probably not what you have in mind, though -- it *was* expected to be a success, just not to anything like this extent. * pragma(msg) is something that's been used 100X as often as anticipated.* Builtin properties of types, eg int.max. Doesn't sound like much of an improvement over a header file of constants, but it's had a huge impact. It really encourages you to write correct code, (I especially notice it for floating point, but I bet if you grep for "int.max" in D code, you'll get far more hits than for "MAXINT" in C code).And is(typeof()), even though the syntax is really horrible. Brilliant concept.
Mar 20 2012
On Tue, 20 Mar 2012, Don wrote:On 20.03.2012 21:33, Don wrote:I wrote the original msg part of assert and static assert. It wasn't because of pragma(msg), it was because I wanted a message with my asserts. :) Later, Brad* pragma(msg) is something that's been used 100X as often as anticipated.Note that because it was so successful, it was incorporated into static assert.
Mar 20 2012
1. Scope guards. The need to execute some code at the end of a scope is pervasive and has led to about a zillion workarounds with statements in Python. D is the only language I know of that lets the programmer specify such a simple and common intention directly. 2. CTFE. There's a certain elegance to having most of the language available at compile time and it seems like there's no shortage of creative uses for this. 3. Static if. This is the most important feature for converting template metaprogramming from an esoteric form of sorcery to a practical, readable tool for the masses. Most of the compile time introspection D provides would be almost unusable without it.
Mar 20 2012
On Tue, Mar 20, 2012 at 01:31:08PM -0700, H. S. Teoh wrote:On Tue, Mar 20, 2012 at 02:02:15PM -0500, Andrei Alexandrescu wrote:[...] Oh, and I forgot static if. It's a major feature in making compile-time stuff work like a charm. T -- Life is too short to run proprietary software. -- Bdale GarbeeI 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.[...] By far: CTFE. Unittest blocks, extended concept of purity, template syntax (as opposed to C++'s ugly mess), all types have a default value (.init - makes it so painless to write generic code!), scope guards.
Mar 20 2012
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).
Mar 20 2012
On 3/20/12 4:43 PM, Walter Bright wrote:On 3/20/2012 12:02 PM, Andrei Alexandrescu wrote:Go has slices. (Unlike D slices, they include capacity.) AndreiWhat 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).
Mar 20 2012
On 3/20/2012 2:51 PM, Andrei Alexandrescu wrote:On 3/20/12 4:43 PM, Walter Bright wrote:Can you, in Go: 1. slice a static string? 2. slice any arbitrary data?On 3/20/2012 12:02 PM, Andrei Alexandrescu wrote:Go has slices. (Unlike D slices, they include capacity.)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).
Mar 20 2012
On 03/20/2012 04:10 PM, Walter Bright wrote:On 3/20/2012 2:51 PM, Andrei Alexandrescu wrote:3. have arbitrary overlapping slices? OTOH slices in D do have a capacity in some regards in that the GC can allow in place extend.On 3/20/12 4:43 PM, Walter Bright wrote:Can you, in Go: 1. slice a static string? 2. slice any arbitrary data?On 3/20/2012 12:02 PM, Andrei Alexandrescu wrote:Go has slices. (Unlike D slices, they include capacity.)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).
Mar 20 2012
On 03/20/2012 17:43, Walter Bright wrote:On 3/20/2012 12:02 PM, Andrei Alexandrescu wrote:Oh... I remember those early D-Days...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).
Mar 21 2012
On Tuesday, 20 March 2012 at 21:43:25 UTC, Walter Bright wrote:On 3/20/2012 12:02 PM, Andrei Alexandrescu wrote:As to me, slices are the most important feature of D, and they were the major improvement from the start, aimed to fix the buffer overflow vulnerabilities - the plague of low level languages - at the lowest cost. What can do more than that? I thought they were born to be epic: safety, minimalism a efficiency combined.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).
Mar 21 2012
Andrei Alexandrescu wrote:What are your faves?opDispatch was expectantly successful for me. I haven't seen it often used in examples or others peoples code, but it allows for some really awesome stuff. For instance, who says D doesn't have multiple inheritance? struct A { void a() { writeln("a"); } } struct B { void b() { writeln("b"); } } struct C { private A _a; private B _b; void opDispatch(string s)() { static if (__traits(hasMember, A, s)) mixin("_a."~s~"();"); else if (__traits(hasMember, B, s)) mixin("_b."~s~"();"); else static assert("Method not found."); } } void main() { auto c = C(); c.a(); c.b(); } and similarly, "alias x this" is useful for pseudo hierarchy. The only down-side to doing this is that Mono-D doesn't currently parse the syntax.
Mar 20 2012
Le 20/03/2012 20:02, Andrei Alexandrescu a écrit :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, AndreiTo me it is pragma(msg, blabla) and slices.
Mar 20 2012
deadalnix wrote:Le 20/03/2012 20:02, Andrei Alexandrescu a écrit :Yes, pragma(msg, ...) is very handy when debugging templates and generic code.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, AndreiTo me it is pragma(msg, blabla) and slices.
Mar 20 2012
On 3/20/12, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:What are your faves? I have a few in mind, but wouldn't want to influence answers.Here's one: C compatibility. Maybe it wasn't "unlikely" to be successful but most new languages don't seem to care about C compatibility all that much. It's been a boon for D though.
Mar 20 2012
I really love CTFE, even though it's sometimes pretty slow, maybe because I am axaggerating it … One more thing are these slices, they really impressed me when working with pointers, float* v; v[x..y] = foo; ! awesome, no more memcpy And of yourse opDispatch, I haven't used it a lot yet, just in gl3n for vector swizzling, I've seen glms swizzling ... I thought I can never do this in D, I made it in nearly no time and 10 lines of code!
Mar 20 2012
On 3/20/12, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:Here's one: C compatibility.Now a real one: auto type inference. Could you possibly imagine what the type name should be on the left-hand side? ? x = retro(stride(chain([1, 2], [3, 4]), 2)); Who knows. auto is great for these higher-level types.
Mar 20 2012
- 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.
Mar 20 2012
On 3/20/2012 3:58 PM, Nick Sabalausky wrote: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.I'd have to agree with this. I find it amazing that other languages entirely miss the boat on this. C++ has a very crippled version of it in "template template parameters".
Mar 20 2012
"Walter Bright" <newshound2 digitalmars.com> wrote in message news:jkb2v6$kq4$2 digitalmars.com...On 3/20/2012 3:58 PM, Nick Sabalausky wrote:I particulary love how D's alias is used to disambiguate symbol conflicts. Brilliant approach. I know I wouldn't have thought of it.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.I'd have to agree with this. I find it amazing that other languages entirely miss the boat on this. C++ has a very crippled version of it in "template template parameters".
Mar 20 2012
On Tue, Mar 20, 2012 at 06:58:31PM -0400, Nick Sabalausky wrote:- Type inferenceYeah I forgot about this one. Being able to write: auto veryLongNamedObject = new VeryLongNamedClass(veryLongArguments); is a big boon over C++ or Java's stuttering verbosity: VeryLongNamedClass veryLongNamedObject = new VeryLongNamedClass(veryLongArguments); Plus, it's immensely useful when dealing with Range templates... can you imagine the horrifically long typenames you'd have to type you have to explicitly specify the type of a long chain of functional expressions involving 15+ std.algorithm and std.range templates?- aliasThis, together with static ifs and templates, make for awesome tricks involving templates that would've been an utter bear to pull off in C++. template innerKeyType(T) { static if (is(T U : U[K], K)) alias innerKeyType!K innerKeyType; else alias T innerKeyType; } innerKeyType!(int[string[char[byte]]]) innerKey; [...]- Built-in associative arrays that support nearly any type as a keyThis is actually quite buggy right now... but that's merely an implementation issue. :-) My new AA implementation, for example, already correctly supports AA's with AA keys, which can be arbitrarily nested. So you could have something like int[string[char[byte]]], and it does lookups correctly based on the contents of the AA's you pass in as key.- All the niceities of ctors compared with C++'s ctorsC++ ctors are a royal pain in the neck. I remember in the early days of C++ when you can still call the base class ctor in the body of the derived class ctor... nowadays you have to contort ctor code into a horrible ugly mess just to get your ctor to do things right. Plus, the C++ standard requires fields to be initialized in declaration order, which is needlessly restrictive and basically makes ctors even more of a pain. I ended up using just stub ctors for a lot of my code, and doing the actual initialization after the object is constructed. Which is very bad OO style, I agree, but the pain of working with C++ ctors just pushes me in the wrong direction, y'know?- Scope guards (And even finally: I head somewhere C++ doesn't even have finally: Is that true?!?)Yes, it's true. I don't know about C++11, but certainly the previous standard has no finally clause, leading to horribly unmaintainable and ugly code like: Resource r = acquireResource(); try { doSomethingDangerous(); } catch(...) { r.release(); } r.release(); (Yes, yes, I know, RAII and all that... which leads to inventing ridiculous classes which make no sense in terms of OO, just to wrap resource handles.)- GCFor all the warts the current GC has, the fact that D has a GC at all makes things like array slicing possible, and *fast*, which leads to all the other niceties of slicing.- Name any of D's metaprogramming features[...]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.Definitely. Using alias and static if in a recursive template is one of the hallmarks of the awesomeness of D templates.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.[...] #include "dmd.h" ;-) T -- Don't modify spaghetti code unless you can eat the consequences.
Mar 20 2012
"H. S. Teoh" <hsteoh quickfur.ath.cx> wrote in message news:mailman.933.1332286692.4860.digitalmars-d puremagic.com...On Tue, Mar 20, 2012 at 06:58:31PM -0400, Nick Sabalausky wrote:Yea, C++'s STL *needs* type inference and alias. At least the new spec has "auto". Don't know about other stuff though.- Type inferenceYeah I forgot about this one. Being able to write: auto veryLongNamedObject = new VeryLongNamedClass(veryLongArguments); is a big boon over C++ or Java's stuttering verbosity: VeryLongNamedClass veryLongNamedObject = new VeryLongNamedClass(veryLongArguments); Plus, it's immensely useful when dealing with Range templates... can you imagine the horrifically long typenames you'd have to type you have to explicitly specify the type of a long chain of functional expressions involving 15+ std.algorithm and std.range templates?- aliasThis, together with static ifs and templates, make for awesome tricks involving templates that would've been an utter bear to pull off in C++. template innerKeyType(T) { static if (is(T U : U[K], K)) alias innerKeyType!K innerKeyType; else alias T innerKeyType; } innerKeyType!(int[string[char[byte]]]) innerKey;[...]Heck, I just love that I can use a string, or an int, or make my own struct work as a key, etc. Actually, over just the last 24 hours I've been making a lot of use of AAs with int keys. (AA's make it *so* much easier to avoid poor time complexity in a lot of things.) Many langauges (like Haxe, for example) will have hashtables, and may even have them templated (or otherwise generic) on *value*, but the keys will be string-only. Which is still very useful, but it also misses out on many other use-cases.- Built-in associative arrays that support nearly any type as a keyThis is actually quite buggy right now... but that's merely an implementation issue. :-)My new AA implementation, for example, already correctly supports AA's with AA keys, which can be arbitrarily nested. So you could have something like int[string[char[byte]]], and it does lookups correctly based on the contents of the AA's you pass in as key.Crazy stuff :) Actually I've been meaning to ask what the main benefits of your new AA implementation are. I know there's the benefit of just simply having it be implemented in the library. And you mention using AA's as AA keys here. Are there any other, umm, "key" points?Yea, that's what I've been planning on doing with the C++ stuff I have coming up. Don't even want to bother with C++'s ctor limitations. Just make an init() member and be done with it. Actually, that seems to be turning into more and more of a common C++ idiom though, from what (little) I've seen.- All the niceities of ctors compared with C++'s ctorsC++ ctors are a royal pain in the neck. I remember in the early days of C++ when you can still call the base class ctor in the body of the derived class ctor... nowadays you have to contort ctor code into a horrible ugly mess just to get your ctor to do things right. Plus, the C++ standard requires fields to be initialized in declaration order, which is needlessly restrictive and basically makes ctors even more of a pain. I ended up using just stub ctors for a lot of my code, and doing the actual initialization after the object is constructed. Which is very bad OO style, I agree, but the pain of working with C++ ctors just pushes me in the wrong direction, y'know?Haxe also lacks finally! Which I always found rediculous. So yea, I'm intimately familiar with that idiom. I've used it myself far more than I would like. 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!). I've seen C++ programmers swear off exceptions because of this, and I can't blame them at all. Exception systems *need* a finally.- Scope guards (And even finally: I head somewhere C++ doesn't even have finally: Is that true?!?)Yes, it's true. I don't know about C++11, but certainly the previous standard has no finally clause, leading to horribly unmaintainable and ugly code like: Resource r = acquireResource(); try { doSomethingDangerous(); } catch(...) { r.release(); } r.release();(Yes, yes, I know, RAII and all that... which leads to inventing ridiculous classes which make no sense in terms of OO, just to wrap resource handles.)Yea, if I wanted to write Java-style code, I'd just use Java (and at least not have to deal with header files).I used to do indie game dev in C/C++ and I feel downright spoiled now with tossing in a "new" whenever appropriate and not have to worry about cleanup (and even that wouldn't be *too* bad...in certain cases...if there were at least scope guards).- GCFor all the warts the current GC has, the fact that D has a GC at all makes things like array slicing possible, and *fast*, which leads to all the other niceties of slicing.I'd say one of the hallmarks of D's metaprogramming is the enormous *decrease* in the need for recursive templates in the first place ;) With C++'s templates, it would appear that you have to use recursion and helper templates for damn near anything.- Name any of D's metaprogramming features[...]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.Definitely. Using alias and static if in a recursive template is one of the hallmarks of the awesomeness of D templates.Heh, yea. :)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.[...] #include "dmd.h" ;-)-- Don't modify spaghetti code unless you can eat the consequences.Hah! :)
Mar 20 2012
"Nick Sabalausky" <a a.a> wrote in message news:jkbcoh$15k3$1 digitalmars.com...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!).And AIUI, even *that* doesn't work in C++ because, IIRC, the class hierarchy doesn't have *any* common root. So what, are you going to have a catch block for *every* class type in your program? Heck, even *that* might be feasable in D thanks to the compile-time reflection and quality metaprogramming, but with C++, you're SOL.
Mar 20 2012
On Tue, Mar 20, 2012 at 09:59:27PM -0400, Nick Sabalausky wrote:"H. S. Teoh" <hsteoh quickfur.ath.cx> wrote in message news:mailman.933.1332286692.4860.digitalmars-d puremagic.com...[...]On Tue, Mar 20, 2012 at 06:58:31PM -0400, Nick Sabalausky wrote: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 $.Heck, I just love that I can use a string, or an int, or make my own struct work as a key, etc. Actually, over just the last 24 hours I've been making a lot of use of AAs with int keys. (AA's make it *so* much easier to avoid poor time complexity in a lot of things.)- Built-in associative arrays that support nearly any type as a keyThis is actually quite buggy right now... but that's merely an implementation issue. :-)Many langauges (like Haxe, for example) will have hashtables, and may even have them templated (or otherwise generic) on *value*, but the keys will be string-only. Which is still very useful, but it also misses out on many other use-cases.Yep.Haha, I love that pun. I would say the main benefit is having it implemented in the library, because that allows the implementation have direct access to key/value types. I didn't implement any clever new hashing algorithm at all, I just mainly followed the implementation in aaA.d. But having direct access to key/value types is a *huge* win. 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. 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. Another major benefit is that once the AA implementation is decoupled from the compiler (the compiler will only provide syntactic sugar like V[K] and literal syntax), we can finally fix AA bugs without getting roadblocked by compiler limitations or hard-to-repair compiler design flaws (or dirty hacks in the compiler that were introduced to paper over the fundamental schizophrenic problem of struct AssociativeArray being distinct yet not different from the AA implementation in aaA.d). Things are MUCH easier to fix when you can directly access key/value types instead of having only TypeInfo's and needing to resort to void* casting. [...]My new AA implementation, for example, already correctly supports AA's with AA keys, which can be arbitrarily nested. So you could have something like int[string[char[byte]]], and it does lookups correctly based on the contents of the AA's you pass in as key.Crazy stuff :) Actually I've been meaning to ask what the main benefits of your new AA implementation are. I know there's the benefit of just simply having it be implemented in the library. And you mention using AA's as AA keys here. Are there any other, umm, "key" points?The fact that C++ is pushing people in that direction is scary. It breaks one of the principles of good object design, which is that all sequences of method calls should never cause it to enter into an inconsistent state. This no longer holds if init() has to be called first. This is a sign that something is fundamentally wrong with the language.C++ ctors are a royal pain in the neck. [...] I ended up using just stub ctors for a lot of my code, and doing the actual initialization after the object is constructed. Which is very bad OO style, I agree, but the pain of working with C++ ctors just pushes me in the wrong direction, y'know?Yea, that's what I've been planning on doing with the C++ stuff I have coming up. Don't even want to bother with C++'s ctor limitations. Just make an init() member and be done with it. Actually, that seems to be turning into more and more of a common C++ idiom though, from what (little) I've seen.And actually there's already a bug in the code I wrote: I forgot the rethrow inside the catch(...). See, that's how bug-prone this stupid idiom is.Haxe also lacks finally! Which I always found rediculous. So yea, I'm intimately familiar with that idiom. I've used it myself far more than I would like.[...] (And even finally: I head somewhere C++ doesn't even have finally: Is that true?!?)Yes, it's true. I don't know about C++11, but certainly the previous standard has no finally clause, leading to horribly unmaintainable and ugly code like: Resource r = acquireResource(); try { doSomethingDangerous(); } catch(...) { r.release(); } r.release();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'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? (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 --- 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. Like if you forget to define a copy ctor for your exception class, and you forget to catch by reference instead of by value... With a char*, there can be no such problem unless the compiler is completely unusable.) [...]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! [...]For all the warts the current GC has, the fact that D has a GC at all makes things like array slicing possible, and *fast*, which leads to all the other niceties of slicing.I used to do indie game dev in C/C++ and I feel downright spoiled now with tossing in a "new" whenever appropriate and not have to worry about cleanup (and even that wouldn't be *too* bad...in certain cases...if there were at least scope guards).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.Definitely. Using alias and static if in a recursive template is one of the hallmarks of the awesomeness of D templates.I'd say one of the hallmarks of D's metaprogramming is the enormous *decrease* in the need for recursive templates in the first place ;)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. T -- Which is worse: ignorance or apathy? Who knows? Who cares? -- Erich Schubert
Mar 20 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.I see. It has been awhile since I've been in the C++ loop.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.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).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?(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 problemsThat 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...)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.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.-- Which is worse: ignorance or apathy? Who knows? Who cares? -- Erich Schubertlol :) Now that's without a doubt one of my favorites.
Mar 21 2012
On 3/21/2012 1:01 AM, Nick Sabalausky wrote: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...)You're correct. Metaprogramming was an emergent property of C++ templates, and was discovered, not designed.
Mar 21 2012
On Tue, Mar 20, 2012 at 10:47 PM, H. S. Teoh <hsteoh quickfur.ath.cx> wrote: [snip] I would say the main benefit is having it implemented in the library,because that allows the implementation have direct access to key/value types. I didn't implement any clever new hashing algorithm at all, I just mainly followed the implementation in aaA.d. But having direct access to key/value types is a *huge* win. 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'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
Mar 20 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 AndersonMore 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.
Mar 21 2012
On Wed, Mar 21, 2012 at 2:06 AM, Martin Nowak <dawg dawgfoto.de> wrote:It's probably far too early to think about this with all the otherInteresting. Thanks for the link. Regards, Brad Andersonimportant 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<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 AndersonMore 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.
Mar 21 2012
On Tue, Mar 20, 2012 at 11:54:37PM -0600, Brad Anderson wrote: [...]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.[...] The current implementation actually has (at least) two different hash functions: - Paul Hsieh's SuperFastHash (rt.util.hash.hashOf) - A custom hash for char[] and string: look in rt/typeinfo/ti_Ag.d for class TypeInfo_Aa, which has this: hash_t hash = 0; foreach (char c; s) hash = hash * 11 + c; I'm going to benchmark both hash functions to see which is actually faster. I suspect the custom hash is faster for small strings, though it may not have good hash distribution. T -- Microsoft is to operating systems & security ... what McDonalds is to gourmet cooking.
Mar 21 2012
On Mar 20, 2012, at 10:54 PM, Brad Anderson wrote:=20 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. Druntime actually did use MurmurHash for a while and then dropped it = because the site had no copyright license for the code (a mistake that = has since been rectified). I'd consider switching back, though I don't = really like that MurmurHash has a number of separate implementations = targeted at different platforms, each having different performance = characteristics. It's 4x faster than SuperFastHash on x86 but 10x = slower than SuperFastHash on SPARC, for example.=
Mar 21 2012
"Sean Kelly" <sean invisibleduck.org> wrote in message news:mailman.981.1332359368.4860.digitalmars-d puremagic.com...Druntime actually did use MurmurHash for a while and then dropped it because the site had no copyright license for the code (a mistake that has since been rectified). I'd consider switching back, though I don't really like that MurmurHash has a number of separate implementations targeted at different platforms, each having different performance characteristics. It's 4x faster than SuperFastHash on x86 but 10x slower than SuperFastHash on SPARC, for example.=People still use SPARC? /me out of the loop
Mar 21 2012
On Mar 21, 2012, at 1:24 PM, Nick Sabalausky wrote:"Sean Kelly" <sean invisibleduck.org> wrote in message=20 news:mailman.981.1332359368.4860.digitalmars-d puremagic.com...Yup. Though these days it seems more common to use x86 Solaris instead, = and even that subset is transitioning to Linux.==20 Druntime actually did use MurmurHash for a while and then dropped it because the site had no copyright license for the code (a mistake that has since been rectified). I'd consider switching back, though I don't really like that MurmurHash has a number of separate implementations targeted at different platforms, each having different performance characteristics. It's 4x faster than SuperFastHash on x86 but 10x slower than SuperFastHash on SPARC, for example.=3D=20 People still use SPARC? =20 /me out of the loop
Mar 21 2012
On 2012-03-21 20:49, Sean Kelly wrote:Druntime actually did use MurmurHash for a while and then dropped it because the site had no copyright license for the code (a mistake that has since been rectified). I'd consider switching back, though I don't really like that MurmurHash has a number of separate implementations targeted at different platforms, each having different performance characteristics. It's 4x faster than SuperFastHash on x86 but 10x slower than SuperFastHash on SPARC, for example.Would it be possible to use different algorithms on different platforms? -- /Jacob Carlborg
Mar 21 2012
On Wednesday, March 21, 2012 22:18:16 Jacob Carlborg wrote:On 2012-03-21 20:49, Sean Kelly wrote:I'm sure that it would be, but it sounds like part of his complaint is that you end up with different implementations per platform with using MurmurHash, and using a different hash algorithm per architecture is just as bad in that respect. If you're trying to absolutely maximize performance though, that would probably be the way to go if there isn't one which is a clear winner on all architectures. It doesn't matter all that much for dmd at present though, since it's x86-only. - Jonathan M DavisDruntime actually did use MurmurHash for a while and then dropped it because the site had no copyright license for the code (a mistake that has since been rectified). I'd consider switching back, though I don't really like that MurmurHash has a number of separate implementations targeted at different platforms, each having different performance characteristics. It's 4x faster than SuperFastHash on x86 but 10x slower than SuperFastHash on SPARC, for example.Would it be possible to use different algorithms on different platforms?
Mar 21 2012
On Mar 21, 2012, at 2:18 PM, Jacob Carlborg wrote:On 2012-03-21 20:49, Sean Kelly wrote: =20because the site had no copyright license for the code (a mistake that = has since been rectified). I'd consider switching back, though I don't = really like that MurmurHash has a number of separate implementations = targeted at different platforms, each having different performance = characteristics. It's 4x faster than SuperFastHash on x86 but 10x = slower than SuperFastHash on SPARC, for example.Druntime actually did use MurmurHash for a while and then dropped it ==20 Would it be possible to use different algorithms on different =platforms? Depends whether there's any reason to have different platforms attempt = to generate the same hash for a given input.=
Mar 21 2012
On Wed, Mar 21, 2012 at 10:18:16PM +0100, Jacob Carlborg wrote:On 2012-03-21 20:49, Sean Kelly wrote:[...] Should be as simple as adding version() to rt.util.hash.hashOf, I think. But I don't know if there may be potential issues with that. T -- If you want to solve a problem, you need to address its root cause, not just its symptoms. Otherwise it's like treating cancer with Tylenol...Druntime actually did use MurmurHash for a while and then dropped it because the site had no copyright license for the code (a mistake that has since been rectified). I'd consider switching back, though I don't really like that MurmurHash has a number of separate implementations targeted at different platforms, each having different performance characteristics. It's 4x faster than SuperFastHash on x86 but 10x slower than SuperFastHash on SPARC, for example.Would it be possible to use different algorithms on different platforms?
Mar 21 2012
On 3/20/2012 4:39 PM, H. S. Teoh wrote:On Tue, Mar 20, 2012 at 06:58:31PM -0400, Nick Sabalausky wrote:Andrei discovered an amazing use of auto. It enables you to create variables with voldemort types "that may not be named". For example: auto foo() { struct S { ... } S s; return s; } auto x = foo(); And now x is an instance of a voldemort type! It's completely encapsulated.- Type inferenceYeah I forgot about this one. Being able to write: auto veryLongNamedObject = new VeryLongNamedClass(veryLongArguments); is a big boon over C++ or Java's stuttering verbosity: VeryLongNamedClass veryLongNamedObject = new VeryLongNamedClass(veryLongArguments); Plus, it's immensely useful when dealing with Range templates... can you imagine the horrifically long typenames you'd have to type you have to explicitly specify the type of a long chain of functional expressions involving 15+ std.algorithm and std.range templates?
Mar 20 2012
On 3/20/12 9:47 PM, Walter Bright wrote:auto foo() { struct S { ... } S s; return s; } auto x = foo(); 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. Andrei
Mar 20 2012
On 3/20/2012 8:00 PM, Andrei Alexandrescu wrote:On 3/20/12 9:47 PM, Walter Bright wrote:Yeah, I'm going to title my next blog entry that!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.
Mar 20 2012
On 3/21/12, Walter Bright <newshound2 digitalmars.com> wrote:Andrei discovered an amazing use of auto.It's funny how the book explicitly stated that this doesn't work (page 263): "Nested struct objects cannot be returned from functions because the caller doesn't have access to their type". I posted about this back in 2011: http://www.digitalmars.com/d/archives/digitalmars/D/Has_the_ban_on_returning_function_nested_structs_been_lifted_132233.html It might have been a relic from earlier TDPL writing when this feature didn't exist. :)
Mar 20 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
Mar 21 2012
On 21/03/12 03:47, Walter Bright wrote:On 3/20/2012 4:39 PM, H. S. Teoh wrote:That idiom is already built into the language. Anonymous nested classes don't have a name at all. auto x = new class { ... }On Tue, Mar 20, 2012 at 06:58:31PM -0400, Nick Sabalausky wrote:Andrei discovered an amazing use of auto. It enables you to create variables with voldemort types "that may not be named". For example: auto foo() { struct S { ... } S s; return s; } auto x = foo(); And now x is an instance of a voldemort type! It's completely encapsulated.- Type inferenceYeah I forgot about this one. Being able to write: auto veryLongNamedObject = new VeryLongNamedClass(veryLongArguments); is a big boon over C++ or Java's stuttering verbosity: VeryLongNamedClass veryLongNamedObject = new VeryLongNamedClass(veryLongArguments); Plus, it's immensely useful when dealing with Range templates... can you imagine the horrifically long typenames you'd have to type you have to explicitly specify the type of a long chain of functional expressions involving 15+ std.algorithm and std.range templates?
Mar 21 2012
On 3/21/2012 8:21 AM, Don Clugston wrote:On 21/03/12 03:47, Walter Bright wrote:True, but it's the ability to return them from a function that's new & cool! (Yes, I know you can return x as type "Object".)And now x is an instance of a voldemort type! It's completely encapsulated.That idiom is already built into the language. Anonymous nested classes don't have a name at all. auto x = new class { ... }
Mar 21 2012
On 21.03.2012 18:14, Walter Bright wrote:On 3/21/2012 8:21 AM, Don Clugston wrote:BTW what is 'nested' about anonymous nested classes? They seem to work anywhere! Can we just drop that from the name?On 21/03/12 03:47, Walter Bright wrote:True, but it's the ability to return them from a function that's new & cool! (Yes, I know you can return x as type "Object".)And now x is an instance of a voldemort type! It's completely encapsulated.That idiom is already built into the language. Anonymous nested classes don't have a name at all. auto x = new class { ... }
Mar 21 2012
On 03/21/2012 09:00 PM, Don wrote:BTW what is 'nested' about anonymous nested classes? They seem to work anywhere! Can we just drop that from the name?Seems reasonable. BTW: They don't work in a typeof expression: http://d.puremagic.com/issues/show_bug.cgi?id=7104
Mar 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
Mar 21 2012
What you might want to do is look back at early ng posts about features and see which ones were met with "meh", but universally considered to rok now. Asking for stuff now will be hard to be unbiased on the surprise issue. If my memory serves, a few things that were "meh" when announced but that rok now are: 1) enum. I remember an argument over if we should call it invariant, manifest, or the relatively unpopular enum keyword, but I don't recall people at the time expecting it to be as useful as it is now. The argument was between manifest MY_VALUE = 1; and enum MY_VALUE = 1; without thoughts along the line of: template octal(...) { alias octalImpl(t) octal; } or most the other stuff we use ctfe with now. (Speaking of octal, I remember that being dismisses as a "hack" by some members too. Now, it looks like that pattern is catching on for user defined literals, and it rox.) My memory might be bad, but looking at some old posts could confirm if the "unlikely success" label is warranted. 2) Leaving the parenthesis off of simple template instantiations is something I was against early on, and now I love it. IIRC, you wanted to use a different symbol entirely, and leaving the parens off was a compromise between the radical Unicode character proposal and Walter's conservative parenthesis. This is a really small change. At the time, it seemed like it would be stupid and useless. But, would templates be as popular now if we didn't make this change? auto a = to!(int)("10"); vs auto a = to!int("10"); to!int feels like one word, unlike to!(int)(). Who needs atoi when we can say to!int? Decls too: Appender!int, etc. The popularity of this in phobos and outside speaks to a success I didn't expect. 3) My mind is coming up blank on a third newsgroup argument over an awesome feature we use now. But, something I am often amazed about is how cool structs are. When you say "struct", I used to think of "whoo a collection of vars, big deal". But, now, with D2, when you say "struct", I think "fully customizable powerhouse". (even coming from C++, where much of this can be done, D's structs are still a little mindblowing in comparison.)
Mar 20 2012
On Wednesday, 21 March 2012 at 00:53:19 UTC, Adam D. Ruppe wrote:template octal(...) { alias octalImpl(t) octal; }LOL, I was bloviating about "enum" and ended up using "alias" here. alias rox too (which is a bit amazing, considering how simple it is), but I should have said: enum octal = octalImpl(t);
Mar 20 2012
"Adam D. Ruppe" <destructionator gmail.com> wrote in message news:txwnbkafemkurcqjermf forum.dlang.org...2) Leaving the parenthesis off of simple template instantiations is something I was against early on, and now I love it. IIRC, you wanted to use a different symbol entirely, and leaving the parens off was a compromise between the radical Unicode character proposal and Walter's conservative parenthesis. This is a really small change. At the time, it seemed like it would be stupid and useless.Yea, that's a good one. I seem to remember initally thinking that it felt sloppy, but I was otherwise relatively indifferent about it. But now I absolutely love it...sooo much.But, would templates be as popular now if we didn't make this change? auto a = to!(int)("10"); vs auto a = to!int("10");Exactly. Ooh, nested functions and closures are another good one (or two). I get so much use of of those. Speaking of, here's a good one (IMO): The syntax for delegate types (as opposed to C's crude function pointer syntax). A small change, but really helps open up the world of first-class functions, even just by itself.
Mar 20 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.
Mar 21 2012
On 3/21/2012 7:23 AM, Adam D. Ruppe wrote: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.I knew import would be good :-) It's because I've used languages before with an import, and as a compiler guy, I knew what a kludge #include is. The preprocessor in C/C++ is a crutch to make up for deficiencies in the language.
Mar 21 2012
On 2012-03-21 18:20, Walter Bright wrote:I knew import would be good :-) It's because I've used languages before with an import, and as a compiler guy, I knew what a kludge #include is. The preprocessor in C/C++ is a crutch to make up for deficiencies in the language.I've never been able to properly handle includes in C/C++. Import is SO much better. -- /Jacob Carlborg
Mar 21 2012
On Wednesday, 21 March 2012 at 17:20:28 UTC, Walter Bright wrote:On 3/21/2012 7:23 AM, Adam D. Ruppe wrote:On the topic of import, mixin imports are something that I believe will eventually become a great deal more popular than they are today. First, there's the advantage of being able to use a language/syntax more appropriate for the task at hand. For example, for things that output html you could just import mixin a raw html file. But the real advantage is that you can still do compile-time processing on this. Plug in an xml parser, or something like pegged, and you can now extend Html and generate D code for it. For example, if you have something like runat="server" on an element, just like in ASP.net you could create a serverside element for this and manipulate it. Because you know exactly which parts are static and which are dynamic, you could (at compile time) create buffers containing the static portions to prevent having to copy things many times. Unlike other languages, there would be no performance hit to doing this because it's all done at compile time. This is just one example. Another one would be automatically creating bindings for a scripting language, or even automatically creating bindings for a C header file.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.I knew import would be good :-) It's because I've used languages before with an import, and as a compiler guy, I knew what a kludge #include is. The preprocessor in C/C++ is a crutch to make up for deficiencies in the language.
Mar 21 2012
Kapps wrote:or even automatically creating bindings for a C header file.I've thought about that before. It would be great to have fully automatic linking to C libs. You could even have a cache system that stores .di files and only regenerates them if the .h file was modified.
Mar 21 2012
"F i L" <witte2008 gmail.com> wrote in message news:sofbqiiyvragxjaxqbix forum.dlang.org...Kapps wrote:That hits on the one irritating limitation of CTFE: No I/O. So that cache system would be a no-go right now.or even automatically creating bindings for a C header file.I've thought about that before. It would be great to have fully automatic linking to C libs. You could even have a cache system that stores .di files and only regenerates them if the .h file was modified.
Mar 21 2012
On Wednesday, 21 March 2012 at 21:38:16 UTC, Nick Sabalausky wrote:"F i L" <witte2008 gmail.com> wrote in message news:sofbqiiyvragxjaxqbix forum.dlang.org...Didn't realize that. Well until IO in CTFE is possible, converting a .h file into a .di file is still possible. Once that's done then it could just be wrapped up into a mixin cache system. D already has a tool to do this I believe (htod). Never used it though.Kapps wrote:That hits on the one irritating limitation of CTFE: No I/O. So that cache system would be a no-go right now.or even automatically creating bindings for a C header file.I've thought about that before. It would be great to have fully automatic linking to C libs. You could even have a cache system that stores .di files and only regenerates them if the .h file was modified.
Mar 21 2012
On 03/21/2012 10:37 PM, Nick Sabalausky wrote:"F i L"<witte2008 gmail.com> wrote in message news:sofbqiiyvragxjaxqbix forum.dlang.org...I once cached CTFE results by wrapping some templates into another template that would generate pragma(msg, ...) output that was then fitered out by an external d program and written to temporary files. On the next compilation run, the wrapper template would notice the existence of a suitable cache file and use its contents instead of starting the CTFE execution.Kapps wrote:That hits on the one irritating limitation of CTFE: No I/O. So that cache system would be a no-go right now.or even automatically creating bindings for a C header file.I've thought about that before. It would be great to have fully automatic linking to C libs. You could even have a cache system that stores .di files and only regenerates them if the .h file was modified.
Mar 21 2012
On 2012-03-21 22:32, F i L wrote:Kapps wrote:I've been thinking on that as well since I'm writing a tool for converting header files. But I was thinking more of modifying the compiler and adding a new pragma that calls into my library. -- /Jacob Carlborgor even automatically creating bindings for a C header file.I've thought about that before. It would be great to have fully automatic linking to C libs. You could even have a cache system that stores .di files and only regenerates them if the .h file was modified.
Mar 21 2012
Jacob Carlborg wrote:But I was thinking more of modifying the compiler and adding a new pragma that calls into my library.That would probably be a better option I think. In fact, eventually DMD could just have the cache system built in and the ability to import .h files just like .d ones. Now that would be pretty cool. All the .di cache files could be stored in ~/.dmd/ (or equivalent) or converted manually (dmd -CtoD file.h) for distribution.
Mar 21 2012
"Kapps" <opantm2+spam gmail.com> wrote in message news:nnqtlpjqwdnzuwiqcycr forum.dlang.org...On Wednesday, 21 March 2012 at 17:20:28 UTC, Walter Bright wrote:Oh yea, definitely. I'm already using HTML mixin imports for the little bit of sever-side web stuff I've started playing around with in D.On 3/21/2012 7:23 AM, Adam D. Ruppe wrote:On the topic of import, mixin imports are something that I believe will eventually become a great deal more popular than they are today. First, there's the advantage of being able to use a language/syntax more appropriate for the task at hand. For example, for things that output html you could just import mixin a raw html file. But the real advantage is that you can still do compile-time processing on this. Plug in an xml parser, or something like pegged, and you can now extend Html and generate D code for it. For example, if you have something like runat="server" on an element, just like in ASP.net you could create a serverside element for this and manipulate it. Because you know exactly which parts are static and which are dynamic, you could (at compile time) create buffers containing the static portions to prevent having to copy things many times. Unlike other languages, there would be no performance hit to doing this because it's all done at compile time. This is just one example. Another one would be automatically creating bindings for a scripting language, or even automatically creating bindings for a C header file.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.I knew import would be good :-) It's because I've used languages before with an import, and as a compiler guy, I knew what a kludge #include is. The preprocessor in C/C++ is a crutch to make up for deficiencies in the language.
Mar 21 2012
On Wednesday, 21 March 2012 at 21:01:10 UTC, Kapps wrote:On the topic of import, mixin imports are something that I believe will eventually become a great deal more popular than they are today.I use a *lot* of import() (one of my work projects imports() about 140 files!) but I fairly rarely use mixin with it. What I love about it is simply having a one-piece executable. All your default data is right there. Deployment is easy. If replacement files exist at runtime, you might use them, but if not, you always have a default built in! It is much easier than external resource files, and being able to process is a nice win.
Mar 21 2012
On Wednesday, 21 March 2012 at 21:01:10 UTC, Kapps wrote:Definitely.... mixin imports and ctfe gets my 3 votes!On the topic of import, mixin imports are something that I believe will eventually become a great deal more popular than they are today.
Mar 21 2012
"Adam D. Ruppe" <destructionator gmail.com> wrote in message news:vuegxcpcbsefvmjdqesp forum.dlang.org...On Wednesday, 21 March 2012 at 21:01:10 UTC, Kapps wrote:Yea. It especially would have been great back when I was doing GBA homebrew. With that stuff having been in C/C++, just to include *any* real binary data, we had to use external tools (as a pre-compilation build step) to convert the binary data files into C files that contained "char myData[] = [0x01, 0x5B, 0xFF, 0x80, ...];" (or something like that - my C muscles have atrophied). And then later on someone made sort of a mini file-system where you could add data to a ROM image and then query/access it from your code in the ROM. If we had been doing things in D, we could all have just typed import("myData.dat") and been *done*. None of those extra tools or MIME-like-bloating^H^H^H^H^H^H^H^Hencoding bullshit.On the topic of import, mixin imports are something that I believe will eventually become a great deal more popular than they are today.I use a *lot* of import() (one of my work projects imports() about 140 files!) but I fairly rarely use mixin with it. What I love about it is simply having a one-piece executable. All your default data is right there. Deployment is easy. If replacement files exist at runtime, you might use them, but if not, you always have a default built in! It is much easier than external resource files, and being able to process is a nice win.
Mar 21 2012
On Thursday, 22 March 2012 at 04:49:24 UTC, Nick Sabalausky wrote:And then later on someone made sort of a mini file-system where you could add data to a ROM image and then query/access it from your codeNow, this reminds me, what if you want to access the compile time files from runtime? For instance, one of my projects lets you include other files in the html. (Something I actually don't like, but it is an easy crutch.) You can also replace these at runtime, so the other team members can change stuff without access to the compiler. Here's what I ended up writing: // filesystem alternatives... string getFile(string name)() { if(std.file.exists(dir ~ name)) return std.file.readText(dir ~ name); else return import(name); } // runtime fetching string getIncludeFile(string name) { enum manifest = ["file1.html", "file2.html", ......]; string manifests() { string cases; foreach(f; manifest) cases ~= "case \""~f~"\": return getFile!(\""~f~"\");"; return cases; } switch(name) { default: assert(0, name); mixin(manifests()); } } I'm a bit disappointed that I needed a list of files duplicated there. With import(), if it is in the import directory, it just works, but then the name must be known at compile time. This is the best I have so far... and i like it, but it isn't quite ideal yet.
Mar 22 2012
"Adam D. Ruppe" <destructionator gmail.com> wrote in message news:oyqxvngsgjfmrlrwhohf forum.dlang.org...On Thursday, 22 March 2012 at 04:49:24 UTC, Nick Sabalausky wrote:Clever idea, I like it.And then later on someone made sort of a mini file-system where you could add data to a ROM image and then query/access it from your codeNow, this reminds me, what if you want to access the compile time files from runtime? For instance, one of my projects lets you include other files in the html. (Something I actually don't like, but it is an easy crutch.) You can also replace these at runtime, so the other team members can change stuff without access to the compiler. Here's what I ended up writing: // filesystem alternatives... string getFile(string name)() { if(std.file.exists(dir ~ name)) return std.file.readText(dir ~ name); else return import(name); } // runtime fetching string getIncludeFile(string name) { enum manifest = ["file1.html", "file2.html", ......]; string manifests() { string cases; foreach(f; manifest) cases ~= "case \""~f~"\": return getFile!(\""~f~"\");"; return cases; } switch(name) { default: assert(0, name); mixin(manifests()); } } I'm a bit disappointed that I needed a list of files duplicated there. With import(), if it is in the import directory, it just works, but then the name must be known at compile time. This is the best I have so far... and i like it, but it isn't quite ideal yet.
Mar 22 2012
"Adam D. Ruppe" <destructionator gmail.com> wrote in message news:fuxnqnmrskrfqqmhdjws forum.dlang.org...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" :)The main thing that grabbed me in the pre-D1 days was the lack of header files in a non-VM systems langauge. Everything else was icing on the cake. Although, while it wasn't a major selling point in and of itself, the ability to put underscores in numeric literals *really* helped tell me, "Now *this* is a language that's very well thought out and values pragmatism." And *that* was the other main thing about D that grabbed me.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..Heh, really? I started getting tired of C++ around 2002-ish, and around the same time, some college courses I was taking were introducing me to Java. I was never a fan of Java overall, and there's a lot about it I always *hated*, but the lack of header files was one thing that *did* really impress me about Java (the other things were reference semantics for classes and GC). It was enough that, at the time, I considered it a reasonable alternative to C++ for things that didn't need number crunching, high
Mar 21 2012
On Wednesday, 21 March 2012 at 19:11:08 UTC, Nick Sabalausky wrote:Although, while it wasn't a major selling point in and of itself, the ability to put underscores in numeric literalsAye, that's a nice touch.Heh, really?Oh yes, I was a staunch defender of C++ for a while. "garbage collection? gah apparently you don't know how to use RAII" "header files? more like good thing, it's called a clean interface" BTW one thing I do kinda like is how you can group member functions however you want in C++. For example, in the dmd source, you have special features in separate files, with all the functions still virtual from the header. void InvariantDeclaration::toJsonBuffer(OutBuffer *buf) { } void DtorDeclaration::toJsonBuffer(OutBuffer *buf) { } void StaticCtorDeclaration::toJsonBuffer(OutBuffer *buf) { } etc. That's actually pretty cool. I like that kind of organization. But, eh, D pwns C++ in so many ways that while I still like C++, I'm no longer in the camp of "c++ is obviously great and totally sufficient and if you don't see it, you must be some kind of idiot" like I was for a while.
Mar 21 2012
"Adam D. Ruppe" <destructionator gmail.com> wrote in message news:utkgtgcgguydxrabkily forum.dlang.org...But, eh, D pwns C++ in so many ways that while I still like C++, I'm no longer in the camp of "c++ is obviously great and totally sufficient and if you don't see it, you must be some kind of idiot" like I was for a while.Heh, yea. I think in a way that's kind of the problem with C++: It can be technically considered "sufficient"...but that's it - it's *merely* sufficient. "Why have a Pop-Tart(tm) when you can have a warm delicious Pillsbury(tm) Toaster Strudel(tm)?" ;)
Mar 21 2012
On Wednesday, 21 March 2012 at 19:11:08 UTC, Nick Sabalausky wrote:Although, while it wasn't a major selling point in and of itself, the ability to put underscores in numeric literals *really* helped tell me, "Now *this* is a language that's very well thought out and values pragmatism." And *that* was the other main thing about D that grabbed me.I take that feature for granted! Try using it in other languages and am always taken back on what it is complaining about, its just a stupid integer literal... oh.
Mar 22 2012
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?After thinking some time about this, I can't find one of them :-) I see many useful/successful features in D, but none of them seemed unimportant at first to me. Maybe I am just strange, but very little of syntax and semantics of a language is unimportant. In languages even unused features (C trigraphs?) sometimes bite your bum, so they become important, with negative value. Bye, bearophile
Mar 20 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, AndreiI've seen most of D's cool features mentioned, but I believe nobody mentioned mixins yet. Mixins are messy to maintain, but together with CTFE they can be used to create some really neat code if used properly. One of the first things I wrote while learning D is a vector class. In GLSL vectors can be 'swizzled', for example: vec3(1, 2, 3).zyx == vec3(3, 2, 1); Swizzles are often useful in graphics or physics code. I don't know of any non-shading language that allows me to use swizzle syntax. As the following code shows, it's quite easy to do in D: module main; import std.stdio; import std.process; import std.conv; int main(string[] argv) { alias Vec!4 Vec4; Vec4 v = Vec4(1, 2, 3, 4); writeln(v.bgra); // Prints Vec!(4)([3, 2, 1, 4]) writeln(v.rg); // Prints Vec!(2)([1, 2]) return 0; } private immutable (char[][]) elementNames = [['x', 'y', 'z', 'w'], ['r', 'g', 'b', 'a'], ['s', 't', 'p', 'q']]; struct Vec(size_t size) { alias size Size; mixin(generateConstructor(Size)); mixin(generateProperties(Size)); auto opDispatch(string s)() { mixin(generateSwizzle(s)); } float v[Size]; } private string generateConstructor(size_t size) { string constructorParams; string constructorBody; foreach(i; 0..size) { string paramName = "v" ~ to!string(i); constructorParams ~= "float " ~ paramName ~ "=0,"; constructorBody ~= "v[" ~ to!string(i) ~ "] = " ~ paramName ~ ";"; } return "this(" ~ constructorParams[0..$-1] ~ "){" ~ constructorBody ~ "}"; } private string generateProperties(size_t size) { string props; foreach(names; elementNames) { foreach(i, name; names[0..size]) { props ~= " property float " ~ name ~ "() const { return v[" ~ to!string(i) ~ "]; }"; props ~= " property void " ~ name ~ "(float f) { v[" ~ to!string(i) ~ "] = f; }"; } } return props; } private string generateSwizzle(string elements) { string swizzleImpl = "return Vec!" ~ to!string(elements.length) ~ "("; foreach(e; elements) { swizzleImpl ~= e ~ ","; } return swizzleImpl[0..$-1] ~ ");"; }
Mar 20 2012
And there goes the formatting, here's a pastebin version: http://pastebin.com/dHdiG0ce On Wednesday, 21 March 2012 at 01:41:27 UTC, Rene Zwanenburg wrote: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, AndreiI've seen most of D's cool features mentioned, but I believe nobody mentioned mixins yet. Mixins are messy to maintain, but together with CTFE they can be used to create some really neat code if used properly. One of the first things I wrote while learning D is a vector class. In GLSL vectors can be 'swizzled', for example: vec3(1, 2, 3).zyx == vec3(3, 2, 1); Swizzles are often useful in graphics or physics code. I don't know of any non-shading language that allows me to use swizzle syntax. As the following code shows, it's quite easy to do in D: module main; import std.stdio; import std.process; import std.conv; int main(string[] argv) { alias Vec!4 Vec4; Vec4 v = Vec4(1, 2, 3, 4); writeln(v.bgra); // Prints Vec!(4)([3, 2, 1, 4]) writeln(v.rg); // Prints Vec!(2)([1, 2]) return 0; } private immutable (char[][]) elementNames = [['x', 'y', 'z', 'w'], ['r', 'g', 'b', 'a'], ['s', 't', 'p', 'q']]; struct Vec(size_t size) { alias size Size; mixin(generateConstructor(Size)); mixin(generateProperties(Size)); auto opDispatch(string s)() { mixin(generateSwizzle(s)); } float v[Size]; } private string generateConstructor(size_t size) { string constructorParams; string constructorBody; foreach(i; 0..size) { string paramName = "v" ~ to!string(i); constructorParams ~= "float " ~ paramName ~ "=0,"; constructorBody ~= "v[" ~ to!string(i) ~ "] = " ~ paramName ~ ";"; } return "this(" ~ constructorParams[0..$-1] ~ "){" ~ constructorBody ~ "}"; } private string generateProperties(size_t size) { string props; foreach(names; elementNames) { foreach(i, name; names[0..size]) { props ~= " property float " ~ name ~ "() const { return v[" ~ to!string(i) ~ "]; }"; props ~= " property void " ~ name ~ "(float f) { v[" ~ to!string(i) ~ "] = f; }"; } } return props; } private string generateSwizzle(string elements) { string swizzleImpl = "return Vec!" ~ to!string(elements.length) ~ "("; foreach(e; elements) { swizzleImpl ~= e ~ ","; } return swizzleImpl[0..$-1] ~ ");"; }
Mar 20 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, AndreiI'll have to say its whatever it is ( and I don't know what it is) that enabled that std.parallelism code to be written with such clean syntax and operate with such low overhead. You can explain what enabled both, I'm sure. Also I'm happy that the array operation syntax is included in the language.
Mar 20 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, Andrei1) inferred types (auto) 2) slices 3) whole > sum(mixin, opDispatch, static if)
Mar 20 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.
Mar 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, Andrei1. 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
Mar 21 2012
On Tue, 20 Mar 2012 15:02:15 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> 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.The two that I would cite are auto and slice syntax. I see others have chimed in with the same two. These were two features that did *not* attract me to D, but I found them to be two of my favorites, and ones I miss the most when writing in other languages. If I had to pick a third, I'd say the omitting parentheses for 1-arg templates was something I didn't expect to be as great as it is. Possibly one other thing I didn't expect to be so nice was shared (more specifically, the implications when something is *not* shared). That enabled weak-pure functions which I think are going to be a HUGE feature for D. -Steve
Mar 21 2012
On 3/21/2012 7:45 AM, Steven Schveighoffer wrote:If I had to pick a third, I'd say the omitting parentheses for 1-arg templates was something I didn't expect to be as great as it is.Yes, Andrei was the lone advocate of that for a while. Everyone else pooh-poohed it, including me.
Mar 21 2012
On 3/21/12 12:26 PM, Walter Bright wrote:On 3/21/2012 7:45 AM, Steven Schveighoffer wrote:I appreciate you implemented it in spite of not finding it compelling. AndreiIf I had to pick a third, I'd say the omitting parentheses for 1-arg templates was something I didn't expect to be as great as it is.Yes, Andrei was the lone advocate of that for a while. Everyone else pooh-poohed it, including me.
Mar 21 2012
On Tuesday, 20 March 2012 at 19:02:16 UTC, Andrei Alexandrescu wrote: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.I know people have said all of these already, but I still want to vote for them, because they're so useful, and I routinely find myself wishing I had them in other languages. 1. Array slices. These allow for a lot of gains from structure sharing and "flyweighting"; safe structure sharing is one of the potential big wins from GC, but in most languages with GC it's tricky to share structure that's in arrays, leading to a lot of extra space overhead for pointers and worse cache behavior due to excessive scattering of objects around the heap. 2. Scope guard. At first I thought it was a neat little curiosity, but it makes it so easy to write and (more importantly) *read* error handling code that, whenever I use D, I find myself thinking about and dealing with potential failure modes that I would gloss over in another language. 3. Template syntax. When I first saw that it used an infix '!' of all things, and that the parentheses were optional, I thought it was the dumbest syntax ever. In practice, though, it's so much better than C++'s <> disaster that it's just not funny. A bunch of other features, like type inference, I totally expected to be extremely useful. The way auto lets you work with objects that have unutterable types is pretty cool, though I picked that up from the C++11 materials I've seen. They really need the feature to make the new lambdas work. Cheers, Pillsy
Mar 21 2012
Another feature I like a lot about D, is it's approach to nested classes. I'm not sure how it compares to other languages, but in don't have access to their containing class's variables. D's approach is much more logical, and works great for simple state systems: abstract class Actor { interface State { void update(); } State state; final void update() { assert(state, "State is null"); state.update(); } } class Fighter : Actor { Idle : State { void update() { punch(); // can punch automatically } } Idle idleState = new Idle(); this() { state = idleState; } void punch() { ... } } constructor and manually manage the reference. It's a small thing, but considering referencing the container class is a core mechanic of any Stated object, it's a pain having to rewrite it, while D just works.
Mar 21 2012
And for my third favorite (in no order), I like custom allocators/deallocators. They're nice for creating "invisible" memory pools: static class Pool(T, uint size = 100) { static T[size] pool; static void* alloc() { ... } static void free(void* p) { ... } } mixin template UsePool(T, uint size = 100) { new(uint s) { return Pool!(T, size).alloc(); } delete(void* p) { Pool!(T, size).free(p); } } class Test { mixin UsePool!(Test, 50); } then later in you code, you can just instantiate Test like any other object: auto t = new Test(); But if instances of Test are often created/released the performance is much better. Or you can wired it up so that you can pass custom Pools (overriding a default): auto t = new(CustomPool) Test();
Mar 21 2012
On 21.03.2012 21:14, F i L wrote:And for my third favorite (in no order), I like custom allocators/deallocators. They're nice for creating "invisible" memory pools:Sorry to spoil the excitement, but aren't they deprecated? [snip] -- Dmitry Olshansky
Mar 21 2012
On Wednesday, 21 March 2012 at 17:16:55 UTC, Dmitry Olshansky wrote:On 21.03.2012 21:14, F i L wrote:Come on, really? What's the reason for this? I did here about delete being depreciated, though I guess I didn't make the connection. Why is delete being removed anyways? I really liked this ability, and I hope that it doesn't completely disappear, even if it's only sugar.And for my third favorite (in no order), I like custom allocators/deallocators. They're nice for creating "invisible" memory pools:Sorry to spoil the excitement, but aren't they deprecated? [snip]
Mar 21 2012
"F i L" <witte2008 gmail.com> wrote in message news:fnlcdpyemasuaomabxxl forum.dlang.org...On Wednesday, 21 March 2012 at 17:16:55 UTC, Dmitry Olshansky wrote:There's a new custom allocator system being worked on. And there's already emplace, which (I imagine) is a key component of it.On 21.03.2012 21:14, F i L wrote:Come on, really? What's the reason for this? I did here about delete being depreciated, though I guess I didn't make the connection. Why is delete being removed anyways? I really liked this ability, and I hope that it doesn't completely disappear, even if it's only sugar.And for my third favorite (in no order), I like custom allocators/deallocators. They're nice for creating "invisible" memory pools:Sorry to spoil the excitement, but aren't they deprecated? [snip]
Mar 21 2012
On 3/21/12 12:14 PM, F i L wrote:And for my third favorite (in no order), I like custom allocators/deallocators.They don't exist anymore. Andrei
Mar 21 2012
Le 21/03/2012 19:32, Andrei Alexandrescu a écrit :On 3/21/12 12:14 PM, F i L wrote:And we are waiting for the replacement !And for my third favorite (in no order), I like custom allocators/deallocators.They don't exist anymore. Andrei
Mar 21 2012
On 3/20/12 2:02 PM, 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.It's official: http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012/Three-Unlikely-Successful-Features-of-D Andrei
Mar 21 2012
On 3/21/12, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:It's official: http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012/Three-Unlikely-Successful-Features-of-D"Go In Three Easy Pieces" followed by "Three Unlikely Successful Features of D". Conspiracy? :P
Mar 21 2012
On 3/20/12, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:What are your faves? I have a few in mind, but wouldn't want to influence answers.Hey here's a big one: Phobos. Or maybe both Phobos and D2. I don't have the numbers but I think quite a few people thought D was going to die because of a backwards-incompatible change of a language, and the fact that Tango was missing from D2 (it seems people avoided using Phobos in D1 days).
Mar 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, AndreiIt isn't mainline yet, but UFCS from git has made working with std.algorithm much nicer. Instead of something like array(filter!"a > 0"(map!((a){return somefunc(a);})(data))) where you can quickly drown in parenthesis and the order seems somewhat backwards, you can use data.map!((a){return somefunc(a);}).filter!"a > 0".array
Mar 22 2012
Matt Peterson:It isn't mainline yet, but UFCS from git has made working with std.algorithm much nicer. Instead of something like array(filter!"a > 0"(map!((a){return somefunc(a);})(data))) where you can quickly drown in parenthesis and the order seems somewhat backwards, you can use data.map!((a){return somefunc(a);}).filter!"a > 0".arrayI suggest to compile all your D2 code with -wi (or -w) and -property. And one bug of UFCS will be probably fixed by Hara (http://d.puremagic.com/issues/show_bug.cgi?id=7722 ), so map and filter will require an ending () (I have closed my http://d.puremagic.com/issues/show_bug.cgi?id=7723 ). So your last line is better written like this: data.map!somefunc().filter!q{a > 0}().array() This is indeed a significant improvement in D syntax for functional-style code, because this reduced nesting a lot, making such code significantly more readable. Bye, bearophile
Mar 22 2012
On Friday, 23 March 2012 at 04:07:53 UTC, bearophile wrote:I suggest to compile all your D2 code with -wi (or -w) and -property.Already using -w, and I thought I was using -property. I am now, thanks.And one bug of UFCS will be probably fixed by Hara (http://d.puremagic.com/issues/show_bug.cgi?id=7722 ), so map and filter will require an ending () (I have closed my http://d.puremagic.com/issues/show_bug.cgi?id=7723 ). So your last line is better written like this: data.map!somefunc().filter!q{a > 0}().array()Yes, I agree. I had to work around a bug a few months ago that using map!some_nested_func wouldn't compile, and I still haven't gotten out of the habit of using delegate literals for all but the simplest maps.
Mar 23 2012