digitalmars.D - Other language features you'd want in D
- Denton Cockburn (11/11) Feb 22 2008 What are some features found in other languages that you believe would b...
- Robert Fraser (7/22) Feb 22 2008 Initializing runtime constants without a static this() a la Java,
- Denton Cockburn (11/35) Feb 22 2008 I don't mind the static this() thing much. It puts all the initializati...
- Robert Fraser (9/48) Feb 23 2008 Constant initialization can already be paired with declaration for
- Denton Cockburn (4/58) Feb 23 2008 I agree.
- Alexander Panek (15/28) Feb 23 2008 You're having a compile-time literal vs. a runtime object here. That's
- Robert Fraser (7/40) Feb 23 2008 You don't need a class for that, as you probably know. What I want is fo...
- Simen Kjaeraas (17/53) Feb 23 2008 th =
- dominik (248/250) Feb 22 2008 Since I'm still learning, I can't say on much more advanced stuff.
- dominik (17/17) Feb 22 2008 I know its not polite to answer my own post, but one more thing - even
- downs (7/16) Feb 28 2008 Agreed. Initializers' type deductions should automatically use the most ...
- bearophile (4/6) Feb 28 2008 Too much automatic things may lead to problems. I don't like that too mu...
- =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= (9/17) Feb 28 2008 Having the most general case as default is easier to remember. But if on...
- Clay Smith (14/29) Feb 22 2008 For me, I feel that D 2.0 or 3.0 will become a dreaded kitchen sink of
- bearophile (4/5) Feb 23 2008 Many features add complexity to a language (or to a system), but that's ...
- yvad (4/4) Apr 02 2008 Using foreach with named enum/
What are some features found in other languages that you believe would be really good to have in D? These can be language features or library features. It shouldn't be any of the general items found in the comparison FAQ (like Multiple inheritance). Something that's relatively nice and specific. e.g. I miss multiple value returns found in Lisp. Out parameters are not nearly as nice. P.S. Has anyone thought to write a document on some of the struct tricks that I've been seeing mentioned? They exploit struct features, but I think only a select few understand them.
Feb 22 2008
Denton Cockburn wrote:What are some features found in other languages that you believe would be really good to have in D? These can be language features or library features. It shouldn't be any of the general items found in the comparison FAQ (like Multiple inheritance). Something that's relatively nice and specific. e.g. I miss multiple value returns found in Lisp. Out parameters are not nearly as nice. P.S. Has anyone thought to write a document on some of the struct tricks that I've been seeing mentioned? They exploit struct features, but I think only a select few understand them.Initializing runtime constants without a static this() a la Java, class C { static int x = someRuntimeInitializer(10); int y = someRuntimeInitializer(20); }
Feb 22 2008
On Fri, 22 Feb 2008 15:25:24 -0800, Robert Fraser wrote:Denton Cockburn wrote:I don't mind the static this() thing much. It puts all the initialization in one place. I hated having to read this in java: class Foo { /* variables with inits */ /* some functions */ /* some variables with inits that were added to the class later */ } I will admit that it's quite a bit more typing though, especially with many defaulted variables.What are some features found in other languages that you believe would be really good to have in D? These can be language features or library features. It shouldn't be any of the general items found in the comparison FAQ (like Multiple inheritance). Something that's relatively nice and specific. e.g. I miss multiple value returns found in Lisp. Out parameters are not nearly as nice. P.S. Has anyone thought to write a document on some of the struct tricks that I've been seeing mentioned? They exploit struct features, but I think only a select few understand them.Initializing runtime constants without a static this() a la Java, class C { static int x = someRuntimeInitializer(10); int y = someRuntimeInitializer(20); }
Feb 22 2008
Denton Cockburn wrote:On Fri, 22 Feb 2008 15:25:24 -0800, Robert Fraser wrote:Constant initialization can already be paired with declaration for non-class types: const(int) HTTP_PORT = 80; But it can't be for class types at global scope: const(Port) HTTP_PORT = new Port(80); How is making it valid for (primitives, arrays, structs, anything with a constant initializer) but not for classes "keeping initialization in one place"?Denton Cockburn wrote:I don't mind the static this() thing much. It puts all the initialization in one place. I hated having to read this in java: class Foo { /* variables with inits */ /* some functions */ /* some variables with inits that were added to the class later */ } I will admit that it's quite a bit more typing though, especially with many defaulted variables.What are some features found in other languages that you believe would be really good to have in D? These can be language features or library features. It shouldn't be any of the general items found in the comparison FAQ (like Multiple inheritance). Something that's relatively nice and specific. e.g. I miss multiple value returns found in Lisp. Out parameters are not nearly as nice. P.S. Has anyone thought to write a document on some of the struct tricks that I've been seeing mentioned? They exploit struct features, but I think only a select few understand them.Initializing runtime constants without a static this() a la Java, class C { static int x = someRuntimeInitializer(10); int y = someRuntimeInitializer(20); }
Feb 23 2008
On Sat, 23 Feb 2008 03:13:45 -0800, Robert Fraser wrote:Denton Cockburn wrote:I agree. It's also somewhat inconsistent that we can initial these primitives during declaration globally, but yet, it can't be done in classes.On Fri, 22 Feb 2008 15:25:24 -0800, Robert Fraser wrote:Constant initialization can already be paired with declaration for non-class types: const(int) HTTP_PORT = 80; But it can't be for class types at global scope: const(Port) HTTP_PORT = new Port(80); How is making it valid for (primitives, arrays, structs, anything with a constant initializer) but not for classes "keeping initialization in one place"?Denton Cockburn wrote:I don't mind the static this() thing much. It puts all the initialization in one place. I hated having to read this in java: class Foo { /* variables with inits */ /* some functions */ /* some variables with inits that were added to the class later */ } I will admit that it's quite a bit more typing though, especially with many defaulted variables.What are some features found in other languages that you believe would be really good to have in D? These can be language features or library features. It shouldn't be any of the general items found in the comparison FAQ (like Multiple inheritance). Something that's relatively nice and specific. e.g. I miss multiple value returns found in Lisp. Out parameters are not nearly as nice. P.S. Has anyone thought to write a document on some of the struct tricks that I've been seeing mentioned? They exploit struct features, but I think only a select few understand them.Initializing runtime constants without a static this() a la Java, class C { static int x = someRuntimeInitializer(10); int y = someRuntimeInitializer(20); }
Feb 23 2008
Robert Fraser wrote:Constant initialization can already be paired with declaration for non-class types: const(int) HTTP_PORT = 80; But it can't be for class types at global scope: const(Port) HTTP_PORT = new Port(80); How is making it valid for (primitives, arrays, structs, anything with a constant initializer) but not for classes "keeping initialization in one place"?You're having a compile-time literal vs. a runtime object here. That's kinda a big difference, you know? I wouldn't want to have my runtime object initialization to be somewhere in class declaration scope. Kinda hard to measure the performance then. Oh, besides... this wouldn't even be in static constructor, but rather the normal constructor. class A { Port httpPort; this (int port = 80) { httpPort = new Port(port); } } I'd like to keep the "verbosity" of initializing class members at runtime as-is.
Feb 23 2008
Alexander Panek wrote:Robert Fraser wrote:You don't need a class for that, as you probably know. What I want is for: const(Port) HTTP_PORT = new Port(80); to be equivalent to: Port HTTP_PORT; static this() { HTTP_PORT = new Port(80); } except, you know, allowing the const in there somewhere.Constant initialization can already be paired with declaration for non-class types: const(int) HTTP_PORT = 80; But it can't be for class types at global scope: const(Port) HTTP_PORT = new Port(80); How is making it valid for (primitives, arrays, structs, anything with a constant initializer) but not for classes "keeping initialization in one place"?You're having a compile-time literal vs. a runtime object here. That's kinda a big difference, you know? I wouldn't want to have my runtime object initialization to be somewhere in class declaration scope. Kinda hard to measure the performance then. Oh, besides... this wouldn't even be in static constructor, but rather the normal constructor. class A { Port httpPort; this (int port = 80) { httpPort = new Port(port); } } I'd like to keep the "verbosity" of initializing class members at runtime as-is.
Feb 23 2008
On Sun, 24 Feb 2008 00:19:59 +0100, Robert Fraser = <fraserofthenight gmail.com> wrote:Alexander Panek wrote:Robert Fraser wrote:Constant initialization can already be paired with declaration for =th =non-class types: const(int) HTTP_PORT =3D 80; But it can't be for class types at global scope: const(Port) HTTP_PORT =3D new Port(80); How is making it valid for (primitives, arrays, structs, anything wi=in =a constant initializer) but not for classes "keeping initialization ='s =one place"?You're having a compile-time literal vs. a runtime object here. That==kinda a big difference, you know? I wouldn't want to have my runtime =da =object initialization to be somewhere in class declaration scope. Kin=er =hard to measure the performance then. Oh, besides... this wouldn't even be in static constructor, but rath=the normal constructor. class A { Port httpPort; this (int port =3D 80) { httpPort =3D new Port(port); } } I'd like to keep the "verbosity" of initializing class members at ==runtime as-is.You don't need a class for that, as you probably know. What I want is =for: const(Port) HTTP_PORT =3D new Port(80); to be equivalent to: Port HTTP_PORT; static this() { HTTP_PORT =3D new Port(80); } except, you know, allowing the const in there somewhere.Something like this was mentioned a few months back. That any compile-ti= me = initialization the compiler wasn't able to do at compile time, should be= = automagically moved to a static this. I don't remember what Walter said = = about it, though. IMO it sounds like a nice feature, but one that should show a warning.
Feb 23 2008
"Denton Cockburn" <diboss hotmail.com> wrote in message news:pan.2008.02.22.21.00.40.605571 hotmail.com...What are some features found in other languages that you believe would be really good to have in D?Since I'm still learning, I can't say on much more advanced stuff. But, the most problematic aspect of the language I've seen yet (I use D1 still) has got to be array initialization, struct initialization and god-forbid both in the same context. for example, though this might've been solved for D2 already: char[][int] foo = [1:"barbar", 2:"bar"]; - this won't work with dmd compiler, but this will: char[][int] foo = [1:"barbar"[], 2:"bar"]; then, as a newcomer, I seem to never quite understand how shall I initialize my array.. so I got into a habit of instead modeling an array in head like I did with C, I use this little trick with pragma where I actually model data in order to get an array definition out of it: so, for example this little line where it is OBVIOUS to me what I wan't data to be modeled: pragma(msg, typeof([["foo"[]: "bar"[]]: 5]).stringof); gives me: int[char[][char[]]] - which is something rather UGH to model in my mind, since words fail me here :) ok, so I thought to myself, no big deal, right? I'll use .typeof(..).stringof to get the right definition since I'm retarded and can model data immidiately, while I can't seem to model the definition.. nice trick there with that line.. moving on.. AND then.. while working on something I had to make a static struct definitions which consists of its own substructs and arrays of different sorts (I have tried to model my incoming data as precisely as possible to avoid possible translation issues later on). So, first things first - I have tried to write a simple test, and it worked: file: test.d ?? more text below code --- module test; import tango.io.Stdout; align(1) struct DST { private int test; private char[] secondtest; } public static DST[char[]] AA; static this() { AA["Africa/Asmara"] = DST(5, "bla"); AA["Africabambata/Asmara"] = DST(6, "blabla"); } void main() { foreach(v; AA) { Stdout.formatln("{} : {}", v.test, v.secondtest); } Stdout.formatln("{}", AA["Africa/Asmara"].test); Stdout.formatln("{}", AA["Africa/Asmara"].secondtest); } --- sure, confident with this little test, I wrote one with static or dynamic initialization of "pointers" to static data, so it looked like this: file: test2.d ?? more text below code --- module test2; import tango.io.Stdout; struct Foo { int x; char[] y; char[] key; } static Foo[] data = [ {0, "blah", "key1"}, {10, "foo", "key2"} ]; Foo*[char[]] aa; void init() { foreach (inout foo; data) { aa[foo.key] = &foo; } } static this(){ init(); // initialize compile time } void main() { //init(); // initialize run-time foreach(v; aa) { Stdout.formatln("{} - {} - {}", v.x, v.y, v.key); } Stdout.formatln("{}", aa["key2"].x); } --- alrighty then, it works, now onto the real thing - where TROUBLE, for me, starts: first let me post a definition of struct itself: --- struct DST { char[] tz_key; char[] tz_version; char[] timestamp; //-aliases char[] geo_coordinates; //-Annual Transition Policy annualTransitionPolicy[] annualTransitionPolicies; //-Initial Annual Transition Policy initialAnnualTransitionPolicy[] initialAnnualTransitionPolicies; } struct annualTransitionPolicy { intraYearTransition[] intraYearTransitions; endOfYearTransition[] endOfYearTransitions; int effectiveYear; char[] effectiveYearCalendar; char[] effectiveYearRelativity; bool isSymmetric; } struct intraYearTransition { char[] defaultAbbreviation; uint offsetSecondsFromUT; uint stdTimeOffsetSecondsFromUT; char[] relativity; uint transitionSecondsSinceStartOfDay; transitionAnnualDate[] transitionAnnualDates; } struct transitionAnnualDate { char[] calendar; month[] months; ushort minDayOfMonth; dayOfWeek[] dayOfWeeks; ushort daysOffset; } struct month { ushort ordial; } struct dayOfWeek { char[] key; } struct endOfYearTransition { char[] defaultAbbreviation; uint offsetSecondsFromUT; uint stdTimeOffsetSecondsFromUT; } struct initialAnnualTransitionPolicy { endOfYearTransition[] endOfYearTransitions; } --- which in lame-mans graph would look like this (hopefully indentation will be right in NG reader, if not follow this url for this particular paste: http://rafb.net/p/5hcyWq21.html) --- struct DST { char[] tz_key; char[] tz_version; char[] timestamp; char[] geo_coordinates; annualTransitionPolicy[] annualTransitionPolicies; intraYearTransition[] intraYearTransitions; char[] defaultAbbreviation; uint offsetSecondsFromUT; uint stdTimeOffsetSecondsFromUT; char[] relativity; uint transitionSecondsSinceStartOfDay; transitionAnnualDate[] transitionAnnualDates; char[] calendar; month[] months; ushort ordial; ushort minDayOfMonth; dayOfWeek[] dayOfWeeks; char[] key; ushort daysOffset; endOfYearTransition[] endOfYearTransitions; int effectiveYear; char[] effectiveYearCalendar; char[] effectiveYearRelativity; bool isSymmetric; initialAnnualTransitionPolicy[] initialAnnualTransitionPolicies; endOfYearTransition[] endOfYearTransitions; char[] defaultAbbreviation; uint offsetSecondsFromUT; uint stdTimeOffsetSecondsFromUT; } --- and now I have tried to manually initialize static data so I can make a working model in order to feed it to my custom parser/generator for that kind of data (paste if indentation is wrong: http://rafb.net/p/ZhpxOw98.html: --- static DST[] DSTData_build = [ { "bla", "bla", "bla", "bla", //annualTransitionPolicy[] annualTransitionPolicies; {[ //intraYearTransition{} intraYearTransitions; [ "bla", 0, 0, "bla", 0, //transitionAnnualDate{} transitionAnnualDates; [ "bla", //month{} months; [ 0 ], 0, //dayOfWeek{} dayOfWeeks; [ "bla" ], 0 ] ], //endOfYearTransition{} endOfYearTransitions; [ 0, "bla", "bla", true ] ]}, //initialAnnualTransitionPolicy{} initialAnnualTransitionPolicies; {[ //endOfYearTransition{} endOfYearTransitions; [ "bla", 0, 0 ] ]} } ]; --- full source is here: http://rafb.net/p/j33uH170.html so that I don't spam NG with any more of text.. now as you can see, as a newcomer I simply can't get along with this initializer things, particulary arrays and structs - and combinations of both. What I would like to see is some kind of a switch to a compiler or some tool that reads in the definition of a struct like I've shown and generates a dummy initializer upon which I can work with. Since working on this for last couple of days on and off, I still haven't been able to properly initialize my static data, I just can't do it - yes, I may be retarded, I even considered to split out structs and possibly arrays and hash their keys with their parent struct identifier, but data is too complex to be split off in that way for now - and in the end, this SHOULD BE EASY TO DO - all other things in D are easy, even for me, but this is something that needs to be either better explained or reimplemented in a more simpler fashion OR that kind of tool/switch thing that makes a dummy initializer upon which one can work. Thank you and my apologies for a huge rant.
Feb 22 2008
I know its not polite to answer my own post, but one more thing - even though I use tango from day to day, I applaud bitfields implementation in std.. now make them part of the language - certanly most people don't use it, but those who do work with them all the time I know its a fantasy but it would be "cool" - and here I'm just pitching an idea - to access bits in a variable in D array fashion for example classic way: ubyte x = 14; ubyte temp = x &0x7; // to access "first" three bits x: 00001110 temp: 00000110 "new" way of sorts (I haven't gave much thought to syntax, ofcourse - cast is foolish, but eh): ubyte x = 14; ubyte temp = cast(bitselect)x[$-3..$];
Feb 22 2008
dominik wrote:for example, though this might've been solved for D2 already: char[][int] foo = [1:"barbar", 2:"bar"]; - this won't work with dmd compiler, but this will: char[][int] foo = [1:"barbar"[], 2:"bar"];Agreed. Initializers' type deductions should automatically use the most specialized type that can accomodate all the values. Same thing for delegate/function literal return-type deductions. so ["foo", "bar"] should be char[3][2], as currently, but ["foo", "barf"] should use char[][2] automatically, (int i) { if (i) return 2; else return 3f; } should be float delegate(int). That falls under "small stuff that adds to language polish". And language polish, in the long run, is probably more important than groundbreaking features. Please think about it. :) --downs
Feb 28 2008
downs:so ["foo", "bar"] should be char[3][2], as currently, but ["foo", "barf"] should use char[][2] automatically,Too much automatic things may lead to problems. I don't like that too much. I'd like a more systematic (uniform) behavior there (for example: "always create dynamic array when not explicitly specified otherwise"). Bye, bearophile
Feb 28 2008
On Thu, 28 Feb 2008, bearophile wrote:downs:Having the most general case as default is easier to remember. But if one writes: char[3][2] foo = [ "foo", "bar" ]; it should still be able to unify the types. Having the opposite as default is annoying since it can lead to subtle bugs. I once had an array of strings that worked just fine with Stdout() (in tango), but FilePath couldn't find the file. Even strace couldn't reveal the bug. But adding missing []s fixed it.so ["foo", "bar"] should be char[3][2], as currently, but ["foo", "barf"] should use char[][2] automatically,Too much automatic things may lead to problems. I don't like that too much. I'd like a more systematic (uniform) behavior there (for example: "always create dynamic array when not explicitly specified otherwise").Bye, bearophile
Feb 28 2008
Denton Cockburn wrote:What are some features found in other languages that you believe would be really good to have in D? These can be language features or library features. It shouldn't be any of the general items found in the comparison FAQ (like Multiple inheritance). Something that's relatively nice and specific. e.g. I miss multiple value returns found in Lisp. Out parameters are not nearly as nice. P.S. Has anyone thought to write a document on some of the struct tricks that I've been seeing mentioned? They exploit struct features, but I think only a select few understand them.For me, I feel that D 2.0 or 3.0 will become a dreaded kitchen sink of features. Rather, I like to think about what features should be kept out of the language. I appreciate language elegance and simplicity because it helps create more maintainable code, and as one of D's original goals, it helps make writing a compiler easier. However, with D 2.0 etc. writing a D compiler is no longer an easy task. Probably still easier than C++, but C++ is a freak hybrid language. I don't really care about super-meta-macro-templates or constness... although there does seem to be an elite few who love abusing the compiler and that's pretty amusing to see their codes... at least /me thinks of Tom S. ;0
Feb 22 2008
Clay Smith:For me, I feel that D 2.0 or 3.0 will become a dreaded kitchen sink of features.Many features add complexity to a language (or to a system), but that's not the main problem. The main source of complexity is the strange interactions between features. When they keep being orthogonal they don't add too much complexity. Many features of C++ interact in messy ways, and they have exceptions, and exceptions to exceptions. That's the recipe to quickly increase the complexity. If you want D to keep having low complexity, you have to clean (and debug) the interaction between features. At the moment D has various things that are less clean than possible, so it can be improved there... Bye, bearophile
Feb 23 2008
Using foreach with named enum/ enum X {A=0x80000000, B=0, C=0x10000, D=0} foreach(x; X) .... This will be useful to write code with extendable in future enums that doesnt need refactoring
Apr 02 2008