September 29, 2006 First Impressions | ||||
---|---|---|---|---|
| ||||
Hi, I'm a C++ user who's just tried D and I wanted to give my first impressions. I can't really justify moving any of my codebase over to D, so I wrote a quick tool to parse a dictionary file and make a histogram - a bit like the wc demo in the dmd package. 1.) I was a bit underwhelmed by the syntax of char[]. I've used lua which also has strings,functions and maps as basic primitives, so going back to array notation seems a bit low level. Also, char[][] is not the best start in the main() declaration. Is it a 2D array, an array of arrays? Then there is the char[][char[]]. What a mouthful for a simple map! Well, now I need to find elements.. I'd use std::string's find() here, but the wc example has all array operations. Even isalpha is done as 'a', 'z' comparisons on an indexed array. Back to low level C stuff. A simple alias of char[] to string would simplify the first glance code. string x; // yep, a string main (string[]) // an array of strings string[string] m; // map of string to string I believe single functions get pulled in as member functions? e.g. find(string) can be used as string.find()? If so, it means that all the string functionality can be added and then used naturally as member functions on this "string" (which is really just the plain old char[] in disguise). This is a small thing, but I think it would help in terms of the mindset of strings being a first class primitive, and clear up simple "hello world" examples at the same time. Put simply, every modern language has a first class string primitive type, except D - at least in terms of nomenclature. 2.) I liked the more powerful for loop. I'm curious is there any ability to use delegates in the same way as lua does? I was blown away the first time I realised how simple it was for custom iteration in lua. In short, you write a function that returns a delegate (a closure?) that itself returns arguments, terminating in nil. e.g. for r in rooms_in_level(lvl) // custom function As lua can handle multiple return arguments, it can also do a key,value sort of thing that D can do. What a wonderful way of allowing any sort of iteration. It beats pages of code in C++ to write an iterator that can go forwards, or one that can go backwards (wow, the power of C++!). C++09 still isn't much of an improvement here, it only sugars the awful iterator syntax. 3.) From the newsgroups, it seems like 'auto' as local raii and 'auto' as automatic type deduction are still linked to the one keyword. Well in lua, 'local' is pretty intuitive for locally scoped variables. Also 'auto' will soon mean automatic type deduction in C++. So those make sense to me personally. Looks like this has been discussed to death, but thats my 2c. 4.) The D version of Scintilla and d-build was nice, very easy to use. Personally I would have preferred the default behaviour of dbuild to put object files in an /obj subdirectory and the final exe in the original directory dbuild is run from. This way, it could be run from a root directory, operate on a /src subdirectory, and not clutter up the source with object files. There is a switch for that, of course, but I can't imagine when you would want object files sitting in the same directory as the source. Well, as first impressions go, I was pleased by D, and am interested to see how well it fares as time goes on. Its just a shame that all the tools/library/IDE is all in C++! Thanks, Geoff |
September 29, 2006 Re: First Impressions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Geoff Carlton | "Geoff Carlton" <gcarlton@iinet.net.au> wrote in message news:efhp1r$1r9s$1@digitaldaemon.com... > Hi, > I'm a C++ user who's just tried D and I wanted to give my first > impressions. I can't really justify moving any of my codebase over to > D, so I wrote a quick tool to parse a dictionary file and make a > histogram - a bit like the wc demo in the dmd package. > > 1.) > I was a bit underwhelmed by the syntax of char[]. I've used lua which > also has strings,functions and maps as basic primitives, so going back > to array notation seems a bit low level. Also, char[][] is not the best > start in the main() declaration. Is it a 2D array, an array of > arrays? Then there is the char[][char[]]. What a mouthful for a simple > map! > > Well, now I need to find elements.. I'd use std::string's find() here, but the wc example has all array operations. Even isalpha is done as 'a', 'z' comparisons on an indexed array. Back to low level C stuff. > > A simple alias of char[] to string would simplify the first glance code. > string x; // yep, a string > main (string[]) // an array of strings > string[string] m; // map of string to string > > I believe single functions get pulled in as member functions? e.g. > find(string) can be used as string.find()? If so, it means that all the > string functionality can be added and then used naturally as member > functions on this "string" (which is really just the plain old char[] in > disguise). They're more just syntactic sugar than member functions. You can, in fact do this with any array type, e.g void foo(int[] arr) { ... } int[] x; x = [4, 5, 6, 7]; // bug in the new array literals ;) x.foo(); > This is a small thing, but I think it would help in terms of the mindset of strings being a first class primitive, and clear up simple "hello world" examples at the same time. Put simply, every modern language has a first class string primitive type, except D - at least in terms of nomenclature. It does look nicer. I suppose the counterargument would be that having an alias char[] string might not be portable -- what about wchar[] and dchar[]? Would they be wstring and dstring? Or would we choose wchar[] or dchar[] to be string to be more forward-thinking (since languages like Java and C# already use UTF-16 as the default string type)? I've never been too incredibly put off by char[], but of course other people have other opinions. > 2.) > I liked the more powerful for loop. I'm curious is there any ability to > use delegates in the same way as lua does? I was blown away the first > time I realised how simple it was for custom iteration in lua. In short, > you write a function that returns a delegate (a closure?) that itself > returns arguments, terminating in nil. > > e.g. for r in rooms_in_level(lvl) // custom function > > As lua can handle multiple return arguments, it can also do a key,value sort of thing that D can do. What a wonderful way of allowing any sort of iteration. Unfortunately the way Lua does "foreach" iteration is exactly the inverse of how D does it. Lua gets an iterator and keeps calling it in the loop; D gives the loop (the entire body!) to the iterator function, which runs the loop. So it's something like a "true" iterator as described in the Lua book: level.each(function(r) print("Room: " .. r) end) D does it this way I guess to make it easier to write iterators. Since you're limited to one return value, it's simpler to make the iterator a callback and pass the indices into the foreach body than it is to make the iterator return multiple parameters through "out" parameters. That, and it's easier to keep track of state with a callback iterator. (I'm going through which to use in a Lua-like language that I'm designing too!) > It beats pages of code in C++ to write an iterator that can go forwards, or one that can go backwards (wow, the power of C++!). C++09 still isn't much of an improvement here, it only sugars the awful iterator syntax. Weeeeeeeee! C++ > 3.) > From the newsgroups, it seems like 'auto' as local raii and 'auto' as > automatic type deduction are still linked to the one keyword. Well in > lua, 'local' is pretty intuitive for locally scoped variables. Also > 'auto' will soon mean automatic type deduction in C++. So those make > sense to me personally. Looks like this has been discussed to death, but > thats my 2c. I don't even wanna get into it ;) _Technically_ speaking, auto isn't really "used" in type deduction; instead, the syntax is just <storage class> <identifier>, skipping the type. Since the default storage class is auto, it looks like auto is being used to determine the type, but it also works like e.g. static x = 5; I think a better way to do it would be to have a special "stand-in" type, such as var x = 5; static var y = 20; auto var f = new Foo(); // this will be RAII and automatically type-determined > 4.) > The D version of Scintilla and d-build was nice, very easy to use. > Personally I would have preferred the default behaviour of dbuild to put > object files in an /obj subdirectory and the final exe in the original > directory dbuild is run from. > > This way, it could be run from a root directory, operate on a /src subdirectory, and not clutter up the source with object files. There is a switch for that, of course, but I can't imagine when you would want object files sitting in the same directory as the source. > > Well, as first impressions go, I was pleased by D, and am interested to see how well it fares as time goes on. Its just a shame that all the tools/library/IDE is all in C++! > > Thanks, > Geoff |
September 29, 2006 Re: First Impressions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Geoff Carlton | Geoff Carlton wrote: > Hi, > I'm a C++ user who's just tried D and I wanted to give my first > impressions. I can't really justify moving any of my codebase over to > D, so I wrote a quick tool to parse a dictionary file and make a > histogram - a bit like the wc demo in the dmd package. You'll sure be pleased with D coming from C++. > 1.) > I was a bit underwhelmed by the syntax of char[]... Yes, I was too. But although it looks not very nice at first sight, D's arrays are nothing like C++ arrays. Strings are first class, array notation is consistent and getting used to them together with concatenation and slicing operators, I found they are quite powerful yet simple to use. > 2.) > I liked the more powerful for loop. I'm curious is there any ability to use delegates in the same way as lua does? I was blown away the first time I realised how simple it was for custom iteration in lua. In short, you write a function that returns a delegate (a closure?) that itself returns arguments, terminating in nil. You can enable a class to use the foreach statement. http://www.digitalmars.com/d/statement.html#foreach > 4.) > The D version of Scintilla and d-build was nice, very easy to use. > Personally I would have preferred the default behaviour of dbuild to put object files in an /obj subdirectory and the final exe in the original directory dbuild is run from. > > This way, it could be run from a root directory, operate on a /src subdirectory, and not clutter up the source with object files. There is a switch for that, of course, but I can't imagine when you would want object files sitting in the same directory as the source. Check out build: http://www.dsource.org/projects/build > Well, as first impressions go, I was pleased by D, and am interested to see how well it fares as time goes on. Its just a shame that all the tools/library/IDE is all in C++! > > Thanks, > Geoff |
September 29, 2006 Re: First Impressions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Jarrett Billingsley wrote: > It does look nicer. I suppose the counterargument would be that having an alias char[] string might not be portable -- what about wchar[] and dchar[]? Would they be wstring and dstring? Or would we choose wchar[] or dchar[] to be string to be more forward-thinking (since languages like Java and C# already use UTF-16 as the default string type)? > I'm a fan of utf-8 so it would seem natural to have string, wstring, and dstring. IMO utf-16 is backward thinking, and has the dubious property of being mostly fixed width, except when its not. And even utf-32 isn't one-to-one in terms of glyphs rendered on screen. Anyway, as a low level programmer, I appreciate that its all based on very powerful and flexible arrays. But as a high level programmer, I don't want to be reminded of that fact every time I need a to use a string. > Unfortunately the way Lua does "foreach" iteration is exactly the inverse of how D does it. Lua gets an iterator and keeps calling it in the loop; D gives the loop (the entire body!) to the iterator function, which runs the loop. So it's something like a "true" iterator as described in the Lua book: > Ok, although the advantage of the first method is that you write the iterator once, and then its easy to use for all clients. Wrapping up the loop in a function is just backward, although it is much more palatable in the inline format than a clunky out of line functor or using _1, _2 hackery magic. As an example, I love the fact that I can do this in lua: for r1 in rooms_in_level(lvl) do for r2 in rooms_in_level(lvl) do for c in connections(r1, r2) do print("got connection " .. c) end end end I wrote Floyd's algorithm in lua in the time it would take me in C++ to not even finish thinking about what structures, classes, vectors I would use. I imagine D would be as easy, although not as nice as the above style. > > D does it this way I guess to make it easier to write iterators. Since you're limited to one return value, it's simpler to make the iterator a callback and pass the indices into the foreach body than it is to make the iterator return multiple parameters through "out" parameters. That, and it's easier to keep track of state with a callback iterator. (I'm going through which to use in a Lua-like language that I'm designing too!) > Multiple returns would be tricky. C++ looks like its getting there with std::tuple and std::tie, but as always the downside is the sheer clunkiness. As hetrogenous arrays aren't in the core language for either C++ or D, its tricky to come up with a clean solution. Designing a language would be great fun, and I think lua has done a great many things right. Not sure about the typeless state though, it gets messy with large projects. Still, no templates (or rather, every function is like a template). |
September 29, 2006 Re: First Impressions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Geoff Carlton | On Fri, 29 Sep 2006 10:23:32 +1000, Geoff Carlton wrote: > Hi, > I'm a C++ user who's just tried D > I was a bit underwhelmed by the syntax of char[]. Yes. It isn't very 'nice' for a modern language. Though as you note below a simple alias can help a lot. alias char[] string; > I believe single functions get pulled in as member functions? e.g. > find(string) can be used as string.find()? This syntax sugar works for all arrays. func(T[] x, a) x.func(a) are equivalent. > 2.) > I liked the more powerful for loop. I'm curious is there any ability to > use delegates in the same way as lua does? Yes it can use anonymous delegates. You can also overload it in classes. > > 3.) > From the newsgroups, it seems like 'auto' as local raii and 'auto' as > automatic type deduction are still linked to the one keyword. There are lots of D users hoping that this wart will be repaired before too long. > 4.) > The D version of Scintilla and d-build was nice, very easy to use. > Personally I would have preferred the default behaviour of dbuild to put > object files in an /obj subdirectory and the final exe in the original > directory dbuild is run from. > > This way, it could be run from a root directory, operate on a /src subdirectory, and not clutter up the source with object files. There is a switch for that, of course, but I can't imagine when you would want object files sitting in the same directory as the source. Thanks for the Build comments. One unfortunate thing I find is that one person's defaults are another's exceptions. That is why you can tailor Build to your 'default' behaviour requirements. In this case, create a text file in the same directory that Build.exe is installed in, called 'build.cfg' and place in it the line ... CMDLINE=-od./obj Then when you run the tool, the command line switch is applied every time you run it. -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocrity!" 29/09/2006 4:44:52 PM |
September 29, 2006 Re: First Impressions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Geoff Carlton | Geoff Carlton wrote: > A simple alias of char[] to string would simplify the first glance code. > string x; // yep, a string > main (string[]) // an array of strings > string[string] m; // map of string to string > > I believe single functions get pulled in as member functions? e.g. > find(string) can be used as string.find()? If so, it means that all the > string functionality can be added and then used naturally as member > functions on this "string" (which is really just the plain old char[] in > disguise). Problem of "char[]" is both that it hides the fact that "char" is UTF-8 while at the same time it exposes the fact that it's stored as an array. You can "improve" upon that readability with aliases, like declaring say utf8_t -> char and string -> utf8_t[], but you still need to understand Unicode and Arrays in order to use it outside of the provided methods... I think "hides the implementation" was the biggest argument against it ? http://www.prowiki.org/wiki4d/wiki.cgi?UnicodeIssues > This is a small thing, but I think it would help in terms of the mindset > of strings being a first class primitive, and clear up simple "hello > world" examples at the same time. Put simply, every modern language has > a first class string primitive type, except D - at least in terms of > nomenclature. I did the big mistake of thinking it would be a good thing to be able to switch between "ANSI" and "UNICODE" builds (of wxD), and so did it like: version(UNICODE) alias char[] string; else // version(ANSI) alias wchar_t[] string; // wchar[] on Windows, dchar[] on Unix Still trying to sort out all the code problems with that idea, as there is a ton of toUTF8 and other conversions to make strings work together. In retrospect it would have been much easier to have stuck with char[], and do the conversion from UTF-8 to the local encoding on the C++ side. (since there were no guarantees that the "char" and "wchar_t" types in C++ used UTF encodings, even if they did so in Unix/GTK+ for instance) Any (minor) performance issues of having to do the UTF-8 <-> UTF-32 conversions were not worth the hassle of doing it on the D side, IMHO. So I agree with the "alias char[] string;" and the string[string] args. It's going to be used as wx.common.string for instance, in wxD library. --anders |
September 29, 2006 Re: First Impressions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Anders F Björklund | > I did the big mistake of thinking it would be a good thing to be able to
> switch between "ANSI" and "UNICODE" builds (of wxD), and so did it like:
>
> version(UNICODE)
> alias char[] string;
> else // version(ANSI)
> alias wchar_t[] string; // wchar[] on Windows, dchar[] on Unix
Except the other way around, of course!
version(UNICODE)
alias wchar_t[] string;
else // version(ANSI)
alias char[] string;
Now, to get me some more coffee... :-P
--anders
|
September 29, 2006 Re: First Impressions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | Derek Parnell wrote:
> On Fri, 29 Sep 2006 10:23:32 +1000, Geoff Carlton wrote:
>> I was a bit underwhelmed by the syntax of char[].
>
> Yes. It isn't very 'nice' for a modern language. Though as you note below a
> simple alias can help a lot.
>
> alias char[] string;
On the other hand, the reasons other languages have strings as classes is because they just don't support arrays very well. C++'s std::string combines the worst of core functionality and libraries, and has the advantages of neither.
An early design goal for D was to upgrade arrays to the point where string classes weren't necessary.
|
September 29, 2006 Re: First Impressions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | Walter Bright wrote:
> An early design goal for D was to upgrade arrays to the point where string classes weren't necessary.
A string alias might still be, just as the bool alias was.
--anders
|
September 29, 2006 Re: First Impressions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Geoff Carlton | I also ALWAYS create aliases for char[], wchar[], dchar[]... I DO wish they would be included by default in Phobos. alias char[] string; alias wchar[] wstring; alias dchar[] dstring; Perhaps, using string instead of char[], it's more obvious that it's not zero-terminated. I've seen D examples online that just cast a char[] to char* for use in MessageBox and the like (which worked since it were string constants.) L. |
Copyright © 1999-2021 by the D Language Foundation