digitalmars.D.bugs - [Issue 9065] New: Please consider adding these std.traits
- d-bugmail puremagic.com (30/30) Nov 23 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (11/12) Nov 24 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (8/12) Nov 24 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (12/12) Nov 24 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (14/17) Nov 24 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (9/15) Nov 24 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (21/21) Nov 24 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (16/30) Nov 24 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (9/10) Nov 24 2012 It's interesting to note that in your very first reply you were confused...
- d-bugmail puremagic.com (7/10) Nov 24 2012 std.traits operates on types, so I would not expect isSomeFunction!bar t...
- d-bugmail puremagic.com (8/10) Nov 25 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (60/60) Nov 26 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (16/17) Nov 26 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (11/11) Nov 26 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (38/51) Nov 26 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (9/17) Nov 26 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (22/33) Nov 26 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (16/46) Nov 26 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (11/21) Nov 26 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (7/24) Nov 26 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (21/23) Nov 26 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (12/37) Nov 26 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (13/17) Nov 26 2012 I don't know if isManifestConstant is the best name, but it's the offici...
- d-bugmail puremagic.com (10/26) Nov 26 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (32/68) Nov 27 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (8/15) Nov 27 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (16/18) Nov 27 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (8/10) Nov 27 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (8/11) Nov 27 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (37/52) Nov 27 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (10/18) Nov 27 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (13/14) Nov 27 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (25/33) Nov 27 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (16/54) Nov 27 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (21/21) Nov 27 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (13/13) Nov 27 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (12/22) Nov 27 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (10/42) Nov 27 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (7/9) Nov 27 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (13/15) Nov 27 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (11/27) Nov 27 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (39/41) Nov 27 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (18/35) Nov 27 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (15/43) Nov 28 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (19/30) Nov 28 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (24/35) Nov 28 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (8/10) Nov 28 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (12/18) Nov 28 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (12/26) Nov 28 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (30/36) Nov 28 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (14/14) Nov 28 2012 http://d.puremagic.com/issues/show_bug.cgi?id=9065
- d-bugmail puremagic.com (23/24) Nov 28 2012 This is not true at all in D. An enum can be any type which can be compa...
http://d.puremagic.com/issues/show_bug.cgi?id=9065 Summary: Please consider adding these std.traits Product: D Version: D2 Platform: All OS/Version: All Status: NEW Severity: enhancement Priority: P2 Component: Phobos AssignedTo: nobody puremagic.com ReportedBy: turkeyman gmail.com I'm constantly writing static logic code where I have no real idea what I'm really doing, and when I finally get it working, it's unreadable. This usually involves lots of careful is()-ing and __traits-ing. I'd really appreciate these templates added to std.traits: Tell me if T is a variable; ie, has a value, has an address (not an enum), ... template isVariable(alias T) { ... } Tell me if T is a function definition, not just if I can call it. I can easily find if something is a function pointer/delegate, or a method, or virtual, or abstract, or various other function related details, but surprisingly, not if T is just a function definition or not. template isFunctionDefinition(alias T) { ... } I want to know if I is an instance of some template T. template isInstanceOf(alias T, I) { ... } Perhaps like this: http://dpaste.dzfl.pl/fedac944 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 23 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065 Andrej Mitrovic <andrej.mitrovich gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |andrej.mitrovich gmail.com 09:59:20 PST ---template isInstanceOf(alias T, I) { ... }That one is now in Phobos: http://d.puremagic.com/issues/show_bug.cgi?id=9064 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 24 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065Sweet. Any chance of the other 2? I'd really like to delete all my unreadable fail code asap. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------template isInstanceOf(alias T, I) { ... }That one is now in Phobos: http://d.puremagic.com/issues/show_bug.cgi?id=9064
Nov 24 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065 David Nadlinger <code klickverbot.at> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |code klickverbot.at PST --- For the second point, what about is(T == function)? The is() syntax is not very popular (rightfully so), but I am not sure if we have a decision to replicate even its most basic use cases in std.traits yet. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 24 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065For the second point, what about is(T == function)? The is() syntax is not very popular (rightfully so), but I am not sure if we have a decision to replicate even its most basic use cases in std.traits yet.Does that not test if T is some sort of function pointer? ...actually, that's some sort of special case overloaded meaning of the function keyword in conjunction with 'is' isn't it? I think I remember running into that like, a year ago. I recall being very confused at the time. Will that only pass in function definitions? Will exclude function pointers? The first point is by far the most important, it's the one I really have no idea how to do properly myself. I have templates that kinda work, but seem to break in some cases, and I use it constantly. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 24 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065 PST ---Does that not test if T is some sort of function pointer? ...actually, that's some sort of special case overloaded meaning of the function keyword in conjunction with 'is' isn't it? I think I remember running into that like, a year ago. I recall being very confused at the time. Will that only pass in function definitions? Will exclude function pointers?Yes, this is one of the ugliest parts of the is() syntax. You are probably right, the fact alone that "function" has a different meaning here than in the rest of the language probably warrants inclusion of an isFunction() trait… -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 24 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065 Jonathan M Davis <jmdavisProg gmx.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jmdavisProg gmx.com PST --- is(T == function) actually tests whether T is the type of a function, not whether it's a function pointer. This stackoverflow question discusses the differences between is(T == function), isFunctionPointer!T, isDelegate!T, and isSomeFunction!T: http://stackoverflow.com/questions/11067972/functions-versus-function-pointers-whats-the-difference We may want to add more of these to std.traits, but we should probably think carefully about exactly what we should add, especially because is expressions do most (all?) of it already, and often fairly cleanly. It's just that they're complicated enough in general and not understood well enough, that many people don't have a clue what they can do. It still may be worth adding stuff like isVariable to std.traits though. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 24 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065is(T == function) actually tests whether T is the type of a function, not whether it's a function pointer. This stackoverflow question discusses the differences between is(T == function), isFunctionPointer!T, isDelegate!T, and isSomeFunction!T: http://stackoverflow.com/questions/11067972/functions-versus-function-pointers-whats-the-differenceLooking at that link, what's with all the typeof(bar) stuff? Do those tempaltes not work by alias? Surely I should be able to say isSomeFunction!bar, not requiring isSomeFunction!(typeof(bar)) ? Using typeof() like that makes generic code harder, because 'bar' could be anything, and if it doesn't have a typeof, then it is a different compile error and I have to produce even more logic prior to eliminate that case. Surely that could be encapsulated?We may want to add more of these to std.traits, but we should probably think carefully about exactly what we should add, especially because is expressions do most (all?) of it already, and often fairly cleanly. It's just that they're complicated enough in general and not understood well enough, that many people don't have a clue what they can do. It still may be worth adding stuff like isVariable to std.traits though.In my experience, code to the effect of isVariable is actually rather non-trivial. It would be very useful. Ideally, written by someone who knows what they're doing ;) (I clearly don't) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 24 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065It's interesting to note that in your very first reply you were confused by is(T == function) too. I really think isFunction! should be added. It seems there is significant evidence to support it. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 24 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065 PST ---Looking at that link, what's with all the typeof(bar) stuff? Do those tempaltes not work by alias? Surely I should be able to say isSomeFunction!bar, not requiring isSomeFunction!(typeof(bar)) ?std.traits operates on types, so I would not expect isSomeFunction!bar to ever work. You need to pass it a type. That's how everything in that module works. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 24 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065 PST ---std.traits operates on types, so I would not expect isSomeFunction!bar to ever work. You need to pass it a type. That's how everything in that module works.This is definitely not true. Just have a look at isSomeFunction/isCallable resp. their unit tests. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 25 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065 Okay, I've worked my templates a little more, consider these: // test if something is a type template isType( alias T ) { enum isType = is( T ); } template isType( T ) { enum isType = is( T ); } // test if something is a function // wrap this up, 'function' is an overloaded term, confusing for newbies template isFunction( alias T ) { enum isFunction = is( typeof( T ) == function ); } template isFunction( T ) { enum isFunction = is( T == function ); } // test if something is an enum (used by isVariable) template isEnum( alias T ) { template knownAtCompileTime( alias T ) { // enum knownAtCompileTime = is( typeof( { enum e = T; } ) ); // immutable breaks this check enum knownAtCompileTime = !__traits(compiles, ( ref typeof( T ) x ) {}( T ) ); // hack to see if we can pass it by ref } enum isEnum = is( typeof( T ) == enum ) || knownAtCompileTime!T; } template isEnum( T ) { enum isEnum = is( T == enum ); } // test if something is a variable; has a value, has an address template isVariable( alias T ) { enum isVariable = !is( T ) && is( typeof( T ) ) // if it is not a type, and does have a type, it starts to look like a variable && !isFunction!T // reject function definitions, they can't be assigned to && !isEnum!T // reject enum's && !is( typeof( T ) == void ); // reject modules, which appear as a variable of type 'void' } template isVariable( T ) { enum isVariable = false; // types aren't variables } This seems to be working for me now (caught a few more edge cases that would fail on occasion). I'd really like to see all of these in std.traits. It would be ideal if is() was a rare occurrence, it produces bracket spam, and most I work with barely understand it past expressions like: is(T == int) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 26 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065 ---Okay, I've worked my templates a little more, consider these:[snip] 1. I would never agree with isFunction. They introduce huge confusion but has no benefit. Blending traits about type and symbol is not a purpose of std.traits. 2. isEnum should be separated to isEnumType and isManifestConstant (with better name). Blending traits is very poor design. And, there is no use case. if you propose an enhancement, you should show one or more use cases in order to claim its usefulness. (I always doubt the reason like "for the newbie". Increase of language newbies is not worth than an increase of the design confusion in the standard library.) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 26 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065 Turns out this is still incomplete: isEnum fails in some situations. Using 'compiles' like that is not reliable with various levels of aliases/templates. Also, that implementation of isVariable marks getter-properties as if they are variables, which they are not. Back to the drawing board... -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 26 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065You would never agree with a std.traits to wrap is(x == function)? Why? It confuses everyone. Nobody expects that overload of meaning.Okay, I've worked my templates a little more, consider these:[snip] 1. I would never agree with isFunction. They introduce huge confusion but has no benefit. Blending traits about type and symbol is not a purpose of std.traits.2. isEnum should be separated to isEnumType and isManifestConstant (with better name). Blending traits is very poor design.I've never heard this term 'manifest constant' before today. Here's a line of code: enum i = 10; I (and I presume any sane person) would say "that's an enum!". I appreciate there is a distinction between an enum type and an enum value, but they are both called enums, and I doubt any non-D-compiler-developer would presume otherwise. I don't care if they are separated, just that the terminology should make sense.And, there is no use case. if you propose an enhancement, you should show one or more use cases in order to claim its usefulness.I work in a studio on highly sensitive proprietary code. Isolating examples out of context is often difficult, annoying, and very time consuming. I don't have the time to convince you in this case. However, if there wasn't a use case, rest assured I wouldn't be posting here, and I wouldn't be wasting consecutive days of my time on it. I need to know these things, D doesn't provide this information; it should. Perhaps this will help: foreach(m; __traits(allMembers, something)) { // What on earth is m? // I think think you can argue this is unconventional code. // I need to know all sorts of things about m in this context, and I have absolutely no prior information. // 'is' traits shouldn't make me jump through bunches of hoops to gather information. }(I always doubt the reason like "for the newbie". Increase of language newbies is not worth than an increase of the design confusion in the standard library.)Confusion? Surely you mean simplification? Having 'function' mean 2 to different things in 2 contexts is confusing. Having enum mean 2 different things in almost precisely the same context is confusing. std.traits is meant to simplify my code and save me time. In my experience to date, it's severely lacking. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 26 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065Turns out this is still incomplete: isEnum fails in some situations. Using 'compiles' like that is not reliable with various levels of aliases/templates. Also, that implementation of isVariable marks getter-properties as if they are variables, which they are not. Back to the drawing board...I've become convinced I also need to add template isProperty(T) { ... } I can't find any sensible way to do this, and I'm also blocked without it. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 26 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065 Jacob Carlborg <doob me.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |doob me.comPerhaps this will help: foreach(m; __traits(allMembers, something)) { // What on earth is m? // I think think you can argue this is unconventional code. // I need to know all sorts of things about m in this context, and I have absolutely no prior information. // 'is' traits shouldn't make me jump through bunches of hoops to gather information. }I agree with you in general but what's wrong with that example? Sure, the double underscore prefix doesn't look that nice but except from that. What would the alternative be? Something like this: foreach (m; allMembers!(somethnig)) { // What on earth is m? } What's better with that code? The "allMembers" trait is clearly documented here: http://dlang.org/traits.html#allMembers "m" would be a string, since __traits(allMembers, something) returns a tuple of strings. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 26 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065*sigh* Sorry, I take no issue with allMembers. My point has nothing to do with allMembers except that it's a common source of symbols that you have no idea what they are. ** "what on earth is mixin(m)?" If you don't know what something is you need to query details about it, and with all the traits as britle and scarce as they are, chances are that leads to many compile errors and consequently rubbish code scattered to protect it against such errors, when rather, such 'is' traits should just produce 'false' instead of compile errors. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------Perhaps this will help: foreach(m; __traits(allMembers, something)) { // What on earth is m? // I think think you can argue this is unconventional code. // I need to know all sorts of things about m in this context, and I have absolutely no prior information. // 'is' traits shouldn't make me jump through bunches of hoops to gather information. }I agree with you in general but what's wrong with that example? Sure, the double underscore prefix doesn't look that nice but except from that. What would the alternative be? Something like this: foreach (m; allMembers!(somethnig)) { // What on earth is m? } What's better with that code? The "allMembers" trait is clearly documented here: http://dlang.org/traits.html#allMembers "m" would be a string, since __traits(allMembers, something) returns a tuple of strings.
Nov 26 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065 PST ---Here's a line of code: enum i = 10; I (and I presume any sane person) would say "that's an enum!". I appreciate there is a distinction between an enum type and an enum value, but they are both called enums, and I doubt any non-D-compiler-developer would presume otherwise. I don't care if they are separated, just that the terminology should make sense.Yes, but the correct answer to this is to not overload the word "enum" with two different meanings. Unfortunately, this ship has long sailed, but this still doesn't mean that we should repeat this mistake in the standard library, further adding confusion. If you don't like the term manifest constant, maybe isEnumConstant/isEnumType? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 26 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065Sure, just as long as something useful is added to std.traits. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------Here's a line of code: enum i = 10; I (and I presume any sane person) would say "that's an enum!". I appreciate there is a distinction between an enum type and an enum value, but they are both called enums, and I doubt any non-D-compiler-developer would presume otherwise. I don't care if they are separated, just that the terminology should make sense.Yes, but the correct answer to this is to not overload the word "enum" with two different meanings. Unfortunately, this ship has long sailed, but this still doesn't mean that we should repeat this mistake in the standard library, further adding confusion. If you don't like the term manifest constant, maybe isEnumConstant/isEnumType?
Nov 26 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065 ---OK. I understood that Manu says. And my yesterday comment was completely wrong. Sorry for my misunderstanding. Certainly, isFunction is an important template which lacks in std.traits. Existing other function traits, isSomeFunction, isCallble, FunctionTypeOf, return true even if given function pointer or delegate. I can agree with the behavior is sometimes obstacle.Blending traits about type and symbol is not a purpose of std.traits.And more, mixing symbol and type is *a design* of std.traits. I had misunderstood at the point. isSomeFunction is an example. /** Detect whether >>symbol or type<< $(D T) is a function, a function pointer or a delegate. */ template isSomeFunction(T...) { ... } I challenged implementing proposed template isVariable. Is this what you want? https://gist.github.com/4152297 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 26 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065It looks good, although I can't test it now. Does isVariable deal with properties (which I would say are NOT variables). And how about an isProperty? That's really hard to detect... I'm not sold on the term isManifestConstant, I'm sure no non-compiler developer would have ever heard that term before. I've never seen it in any docs before, and they're declared with 'enum', that's what most people will call it. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------OK. I understood that Manu says. And my yesterday comment was completely wrong. Sorry for my misunderstanding. Certainly, isFunction is an important template which lacks in std.traits. Existing other function traits, isSomeFunction, isCallble, FunctionTypeOf, return true even if given function pointer or delegate. I can agree with the behavior is sometimes obstacle.Blending traits about type and symbol is not a purpose of std.traits.And more, mixing symbol and type is *a design* of std.traits. I had misunderstood at the point. isSomeFunction is an example. /** Detect whether >>symbol or type<< $(D T) is a function, a function pointer or a delegate. */ template isSomeFunction(T...) { ... } I challenged implementing proposed template isVariable. Is this what you want? https://gist.github.com/4152297
Nov 26 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065 PST ---I'm not sold on the term isManifestConstant, I'm sure no non-compiler developer would have ever heard that term before. I've never seen it in any docs before, and they're declared with 'enum', that's what most people will call it.I don't know if isManifestConstant is the best name, but it's the official term, and I'm sure that a large portion of the regular newsgroup goers know what it is, not just the compiler devs. I don't know how many outside that group would know it however. Still, given that it's the official name, and that we don't really _have_ another name, I think that I'd still be in favor of isManifestConstant. And if we have isManifestConstant and isEnumType and no isEnum, then we avoid all of the confusion surrounding what exactly an enum is. And it's not like it will be hard for the docs to explain the terms. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 26 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065 ---Added isPropertyFunction (isProperty is a bit ambiguous name to me). I think it's a trait derived from isFunction.I challenged implementing proposed template isVariable. Is this what you want? https://gist.github.com/4152297It looks good, although I can't test it now. Does isVariable deal with properties (which I would say are NOT variables). And how about an isProperty? That's really hard to detect...I'm not sold on the term isManifestConstant, I'm sure no non-compiler developer would have ever heard that term before. I've never seen it in any docs before, and they're declared with 'enum', that's what most people will call it.http://dlang.org/features2.htmlExtended enums to allow declaration of manifest constants.http://dlang.org/enum.htmlManifest Constants If there is only one member of an anonymous enum, the { } can be omitted: [snip] Such declarations are not lvalues, meaning their address cannot be taken.-- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 26 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065There is another name, it's called an 'enum', as clearly stated by the syntax: enum x = 10; Using any term other than that seems crazy by my measure. The user base aren't compiler developers. I don't even know what manifest means. I don't think the distinction isEnumType, isEnumValue is at all confusing, in fact, the function names alone document the important detail that there IS a distinction, and what it is.I'm not sold on the term isManifestConstant, I'm sure no non-compiler developer would have ever heard that term before. I've never seen it in any docs before, and they're declared with 'enum', that's what most people will call it.I don't know if isManifestConstant is the best name, but it's the official term, and I'm sure that a large portion of the regular newsgroup goers know what it is, not just the compiler devs. I don't know how many outside that group would know it however. Still, given that it's the official name, and that we don't really _have_ another name, I think that I'd still be in favor of isManifestConstant. And if we have isManifestConstant and isEnumType and no isEnum, then we avoid all of the confusion surrounding what exactly an enum is. And it's not like it will be hard for the docs to explain the terms.This highlights another conflict in terminology, currently a property is NOT recognised as a function (at least in my crappy tests). I really think isFunction!someProperty should be true. It's a function, exactly like any other, I can take pointers/delegates of it, it just has a particular usage semantic. Effectively a subset, not a different concept. So I suggest isFunction! should give true for a property function definition.Added isPropertyFunction (isProperty is a bit ambiguous name to me). I think it's a trait derived from isFunction.I challenged implementing proposed template isVariable. Is this what you want? https://gist.github.com/4152297It looks good, although I can't test it now. Does isVariable deal with properties (which I would say are NOT variables). And how about an isProperty? That's really hard to detect...This clearly implies that 'manifest constant' is in fact some kind of enum.I'm not sold on the term isManifestConstant, I'm sure no non-compiler developer would have ever heard that term before. I've never seen it in any docs before, and they're declared with 'enum', that's what most people will call it.http://dlang.org/features2.htmlExtended enums to allow declaration of manifest constants.http://dlang.org/enum.htmlAgain, referring to 'anonymous enum', it's not distancing its self from the enum terminology. ... I just asked 2 other programmers in the room what enum x = 10; is, they said it's an enum, not a manifest constant ;) None of them could tell me what a manifest constant it, or that they'd ever heard of such a thing before. But I don't actually care at the end of the day, I'm just trying to give a voice of reason. What the compiler calls stuff internally has no bearing on what users of the language will call things. The user facing library should endeavour to match the terminology used by the users IMO. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------Manifest Constants If there is only one member of an anonymous enum, the { } can be omitted: [snip] Such declarations are not lvalues, meaning their address cannot be taken.
Nov 27 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065This highlights another conflict in terminology, currently a property is NOT recognised as a function (at least in my crappy tests). I really think isFunction!someProperty should be true. It's a function, exactly like any other, I can take pointers/delegates of it, it just has a particular usage semantic. Effectively a subset, not a different concept. So I suggest isFunction! should give true for a property function definition.Sorry! I just saw your unit test asserts isFunction! is true for property functions. I didn't see that behaviour with is(X==function) in my tests. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 27 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065 04:14:28 PST ---What the compiler calls stuff internally has no bearing on what users of the language will call things.It's not an internal thing, that declaration is not an enum declaration, period. enum is used as a keyword for more than one thing, which is bad, but it's too late to change it now. We shouldn't name things in Phobos based on what people might think is right or looks right, but based on what the things really are. It's a shame we don't have a 'manifest' keyword of some sort, it would help avoid confusion. I guess 'enum' was used to cut back on having too many keywords in the language. Anyway it's documented behavior, see "manifest constants" here (it's at the bottom): http://dlang.org/enum.html -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 27 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065 04:15:48 PST ---Anyway it's documented behavior, see "manifest constants" here (it's at the bottom): http://dlang.org/enum.htmlActually it's poorly documented, it speaks about "anon" enums but it shouldn't really mention them at all imo. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 27 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065It's a shame we don't have a 'manifest' keyword of some sort, it would help avoid confusion. I guess 'enum' was used to cut back on having too many keywords in the language.Isn't the whole problem that the compiler and/or linker isn't capable of stripping out symbols that are only used at compile time. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 27 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065I couldn't disagree more. Firstly, what it is clearly documented as, is being some subset of enum. That's what it 'really is'. More importantly, if I look at the top of std.traits for something I presume to be called isEnum, and I see isEnumValue, I'll realise that's actually what I'm looking for immediately, use it, and save myself time. If I see something called isEnum, and it doesn't seem to work because it only reports true for enum TYPES (not values), then I'll declare it broken and report a bug. If I scan through everything in std.traits, and find nothing that looks like what I want, I'll get frustrated the thing I need is missing. If I see isManifestConstant, there is _NO WAY_ I would have even read what that is, it's clearly not what I'm looking for, I'm trying to identify if my thing is an enum...What the compiler calls stuff internally has no bearing on what users of the language will call things.It's not an internal thing, that declaration is not an enum declaration, period. enum is used as a keyword for more than one thing, which is bad, but it's too late to change it now. We shouldn't name things in Phobos based on what people might think is right or looks right, but based on what the things really are.It's a shame we don't have a 'manifest' keyword of some sort, it would help avoid confusion. I guess 'enum' was used to cut back on having too many keywords in the language.I honestly don't even know what manifest means. The terminology used in the syntax and the documentation is correct; it's a kind of enum.Anyway it's documented behavior, see "manifest constants" here (it's at the bottom): http://dlang.org/enum.htmlAnd every place it appears, it is clearly defined as being some subset of enum. Again, if I go looking for isEnum, and find a suite of more specific enum related traits (isEnumType, isEnumValue), I can easily conclude which is the one I'm looking for. If the name is completely unrelated and uses terminology most programmers have never heard before, they'll never spot it. As a side point, what do you call X in: enum E { X = 10 } ? Consider: enum E { X = 10 } enum Y = 10; E.X and Y are both identical as far as I can tell. I would presume: isEnumType!E == true, and isEnumValue!(E.X) == isEnumValue!Y == true. You can tweak the names, but I think traits to that effect are a) useful, b) what (I presume) most typical users will expect. E.X and Y are identical. I think this specialised term 'manifest constant' that only applies to Y can only result in confusion. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 27 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065It's also one of the things that D got absolutely right! I never questioned this design for a moment, it makes perfect sense to me, but as of yesterday my concept of what an enum is has been thrown up in the air for absolutely no good reason other than terminology used by the D developers. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------It's a shame we don't have a 'manifest' keyword of some sort, it would help avoid confusion. I guess 'enum' was used to cut back on having too many keywords in the language.Isn't the whole problem that the compiler and/or linker isn't capable of stripping out symbols that are only used at compile time.
Nov 27 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065https://gist.github.com/4152297I am seeing a few error cases: enum j { k = 10 } pragma(msg, isFunction!(j.k)); pragma(msg, isManifestConstant!(j.k)); pragma(msg, isPropertyFunction!(j.k)); pragma(msg, isVariable!(j.k)); These all throw errors. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 27 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065 06:25:56 PST ---As a side point, what do you call X in: enum E { X = 10 } ? Consider: enum E { X = 10 } enum Y = 10; E.X and Y are both identical as far as I can tell.Run typeid() on them.And every place it appears, it is clearly defined as being some subset of enum.Well it wouldn't be the first time the docs lie. :) "enum Y = 10;" is a special case which the compiler checks for and then parses this as a manifest constant, it does not parse it as an enum. "Y" is not an enum value of any sort, Y is a VarDeclaration with storage class STCmanifest. Here: enum E { X = 10 } X is an EnumMember. Just to make this clear, these two are different: enum { X = 10 } enum Y = 10; X is an enum value, whereas Y is a manifest constant and is not associated with enums at all in any way. The issue here is that the "enum" keyword can be a lie. It can mean two things depending on the declaration. It also seems that internally the idea of a manifest keyword was thought about, there's a bunch of commented out lines like so: //case TOKmanifest: stc = STCmanifest; goto Lstc; I wonder who put that in and why it wasn't used.. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 27 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065That's not really how the doc describes it: "If there is only one member of an anonymous enum, the { } can be omitted:" Either way, it's a perfectly reasonably way to visualise it as a user. As I said before, I couldn't care less about internal compiler terminology, it looks like an anonymous enum value, and the doc even says it's an anonymous enum value. It must be so. The doc is correct as far as I'm concerned, it makes perfect sense, the language shouldn't be defined by implementation details of DMD.As a side point, what do you call X in: enum E { X = 10 } ? Consider: enum E { X = 10 } enum Y = 10; E.X and Y are both identical as far as I can tell.Run typeid() on them.And every place it appears, it is clearly defined as being some subset of enum.Well it wouldn't be the first time the docs lie. :) "enum Y = 10;" is a special case which the compiler checks for and then parses this as a manifest constant, it does not parse it as an enum. "Y" is not an enum value of any sort, Y is a VarDeclaration with storage class STCmanifest. Here: enum E { X = 10 } X is an EnumMember. Just to make this clear, these two are different: enum { X = 10 } enum Y = 10; X is an enum value, whereas Y is a manifest constant and is not associated with enums at all in any way.The issue here is that the "enum" keyword can be a lie. It can mean two things depending on the declaration. It also seems that internally the idea of a manifest keyword was thought about, there's a bunch of commented out lines like so: //case TOKmanifest: stc = STCmanifest; goto Lstc; I wonder who put that in and why it wasn't used..I'll bet it was realised during implementation that it is actually syntactic sugar for an anonymous enum, and the enum keyword was completely appropriate :) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 27 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065 Kenji: I'm getting an error when using your new isFunction, here's the case: struct S { static string func(alias Class)() { foreach(m; __traits(allMembers, Class)) { pragma(msg, m); static if( isFunction!( mixin( m ) ) ) bool b = true; } } enum nothing = func!(typeof(this))(); mixin(nothing); } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 27 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065 I've just this afternoon encountered another one that I can't work out a nice way to discover: struct S { static int x; } bool b = isStatic!(S.x); // <- I can't think of a nice clean way to prove this other than trying to assign to it, which is horrible. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 27 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065 Dmitry Olshansky <dmitry.olsh gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |dmitry.olsh gmail.com 07:16:39 PST ---I've just this afternoon encountered another one that I can't work out a nice way to discover: struct S { static int x; } bool b = isStatic!(S.x); // <- I can't think of a nice clean way to prove this other than trying to assign to it, which is horrible.Trying to take the address should do the trick. is(typeof(&S.x)) that is. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 27 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065 ---Fixed.https://gist.github.com/4152297I am seeing a few error cases: enum j { k = 10 } pragma(msg, isFunction!(j.k)); pragma(msg, isManifestConstant!(j.k)); pragma(msg, isPropertyFunction!(j.k)); pragma(msg, isVariable!(j.k)); These all throw errors.Kenji: I'm getting an error when using your new isFunction, here's the case: struct S { static string func(alias Class)() { foreach(m; __traits(allMembers, Class)) { pragma(msg, m); static if( isFunction!( mixin( m ) ) ) bool b = true; } } enum nothing = func!(typeof(this))(); mixin(nothing); }This is a compiler bug, not an issue of isFunction template. I filed new bug 9083. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 27 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065Trying to take the address should do the trick. is(typeof(&S.x)) that is.That won't work for methods, but that might not be the use case. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 27 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065Trying to take the address should do the trick. is(typeof(&S.x)) that is.And if I have: S s; bool b = isStatic!(s.x); That solution doesn't work if 's' is an instance. I'm sick of writing really brittle code, I'm just saying that is another important std.traits. There's no trivial way to do this for an _anything_ that I can work out. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 27 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065That won't work for methods, but that might not be the use case.Yeah, if it were in std.traits, I would expect it to work on methods too.Huzzah!I am seeing a few error cases: enum j { k = 10 } pragma(msg, isFunction!(j.k)); pragma(msg, isManifestConstant!(j.k)); pragma(msg, isPropertyFunction!(j.k)); pragma(msg, isVariable!(j.k)); These all throw errors.Fixed.This is a compiler bug, not an issue of isFunction template. I filed new bug 9083.Amazing! You sir are awesome! :) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 27 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065This is a compiler bug, not an issue of isFunction template. I filed new bug 9083.I found another one, probably a compiler bug too, but I'll paste it here since it depends on your new isVariable trait: Boiled down as much as I could... class Test { void func() { void templateFunc( T )( ref const T obj ) { foreach( m; __traits( allMembers, T ) ) { pragma(msg, m); static if( isVariable!( __traits(getMember, T, m) ) ) { //... } } } templateFunc( this ); } // some class members int x; } isVariable throws lots of errors when considering the class members. Note: __traits(allMembers, T) and __traits(getMember, T, m) These should also work with class instances, not just types, eg: __traits(allMembers, obj) and __traits(getMember, obj, m) And these combinations should also work: __traits(allMembers, T) and __traits(getMember, obj, m) __traits(allMembers, obj) and __traits(getMember, T, m) All these configurations throw errors, and the errors are different for each configuration. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 27 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065 Rob T <alanb ucora.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |alanb ucora.comAs far as I was concerned, these are anonymous enum members in the case where there's only one member and the { } were omitted. I understood it in this way by reading the specification here: http://dlang.org/enum.html. It actual made some sense to me. The use of "manifest constant" terminology elsewhere will likely cause a lot of confusion. Why not term it as an "anonymous enum constant", or "enum manifest constant" if that suits the usage better. Term it anything so long as "enum" is in there so as to avoid the inevitable confusion elsewhere. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------What the compiler calls stuff internally has no bearing on what users of the language will call things.It's not an internal thing, that declaration is not an enum declaration, period. enum is used as a keyword for more than one thing, which is bad, but it's too late to change it now. We shouldn't name things in Phobos based on what people might think is right or looks right, but based on what the things really are. It's a shame we don't have a 'manifest' keyword of some sort, it would help avoid confusion. I guess 'enum' was used to cut back on having too many keywords in the language. Anyway it's documented behavior, see "manifest constants" here (it's at the bottom): http://dlang.org/enum.html
Nov 27 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065The history of this was: In D1, const XXX = YYY; declared a manifest constant. You couldn't take the address of it. With the change to const in D2, this no longer worked. I argued that we needed a way of doing manifest constants. Walter started implementing it as 'manifest'. Andrei argued for it to reuse 'enum' to reduce the number of keywords. Almost everybody was angry about overloading 'enum' and there was a huge fight, but Andrei won in the end. Yes it causes confusion. They are not enums, there is nothing enumerated about them. It's just an overloaded keyword. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------As far as I was concerned, these are anonymous enum members in the case where there's only one member and the { } were omitted. I understood it in this way by reading the specification here: http://dlang.org/enum.html. It actual made some sense to me. The use of "manifest constant" terminology elsewhere will likely cause a lot of confusion. Why not term it as an "anonymous enum constant", or "enum manifest constant" if that suits the usage better. Term it anything so long as "enum" is in there so as to avoid the inevitable confusion elsewhere.What the compiler calls stuff internally has no bearing on what users of the language will call things.It's not an internal thing, that declaration is not an enum declaration, period. enum is used as a keyword for more than one thing, which is bad, but it's too late to change it now. We shouldn't name things in Phobos based on what people might think is right or looks right, but based on what the things really are. It's a shame we don't have a 'manifest' keyword of some sort, it would help avoid confusion. I guess 'enum' was used to cut back on having too many keywords in the language. Anyway it's documented behavior, see "manifest constants" here (it's at the bottom): http://dlang.org/enum.html
Nov 28 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065The history of this was: In D1, const XXX = YYY; declared a manifest constant. You couldn't take the address of it. With the change to const in D2, this no longer worked. I argued that we needed a way of doing manifest constants. Walter started implementing it as 'manifest'. Andrei argued for it to reuse 'enum' to reduce the number of keywords. Almost everybody was angry about overloading 'enum' and there was a huge fight, but Andrei won in the end. Yes it causes confusion. They are not enums, there is nothing enumerated about them. It's just an overloaded keyword.Andrei was absolutely correct, as far as any user is concerned: enum E { K = 10 } // named enum enum { K = 10 } // anonymous enum enum K = 10; // obvious sugar to save bracket spam As said previously, I give exactly zero shits how it's implemented internally, or the history of it. The way it's documented now and the syntax chosen makes perfect sense, and any attempt to make K be somehow distinct in any of these cases is a mistake which will only lead to confusion. If E is an enum type, then K is an enum value, or an enum constant... (i like enum value better; 'constant' is verbose is implicit) Why would any normal user reasonably expect the term 'manifest' (which I still have no idea what it means) to appear in this context? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 28 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065The history of this was: In D1, const XXX = YYY; declared a manifest constant. You couldn't take the address of it. With the change to const in D2, this no longer worked. I argued that we needed a way of doing manifest constants. Walter started implementing it as 'manifest'. Andrei argued for it to reuse 'enum' to reduce the number of keywords. Almost everybody was angry about overloading 'enum' and there was a huge fight, but Andrei won in the end. Yes it causes confusion. They are not enums, there is nothing enumerated about them. It's just an overloaded keyword.Interesting history, but the thing is that from a D users POV, it is a member of an anonymous enum, and that does not change however it may be internally represented, or historically thought of. I look at it this way enum { a = 2 } // anonymous enum set to 2 with one member enum a = 2; // anonymous enum set to 2 with one member and optional {} removed enum a; // anonymous enum unset with one member and optional {} removed How is this not what the specification says it is? How it may be internally represented is invisible to the user, what the user sees is only what is seen in terms of how the language represents the concept. This is an enum, and if it is not, then that only matters if it does not behave like all the other enum members, otherwise it may as well be viewed as if it is an enum member. I suspect this was Andrei's argument, because it actually does fit nicely into place. If I'm going to get mentally confabulated again because it does not work as I would expect an enum to work, then I'll be up in arms about it for sure, so I'm interested in knowing exactly how it is not like an enum, not internally, not historically, but in terms of usage from a programmers POV? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 28 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065 03:06:54 PST ---interested in knowing exactly how it is not like an enum, not internally, not historically, but in terms of usage from a programmers POV?It doesn't enumerate anything? Enumerations are collections of items, aren't they? How is one element a collection? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 28 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065Then you need to disallow assigning explicit values to enum keys, that's not strictly an enumeration either. It just so happens that anonymous enums containing only a single value have a nice little sugar such that you don't need to write the brackets. This is because, in practise, this turns out to be a surprisingly common usage case so the little sugar is nice. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------interested in knowing exactly how it is not like an enum, not internally, not historically, but in terms of usage from a programmers POV?It doesn't enumerate anything? Enumerations are collections of items, aren't they? How is one element a collection?
Nov 28 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065I believe the similarity you've listed is false. An enumerated type must be integral (it must be countable!) A manifest constant, however, can be anything - a struct literal, for example. I think what has happened is that C had a very sloppy enum design, where it mixed integral manifest constants with enumerated types. Instead of tightening up 'enum', we used the existing sloppiness as an excuse to make it worse. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------Then you need to disallow assigning explicit values to enum keys, that's not strictly an enumeration either. It just so happens that anonymous enums containing only a single value have a nice little sugar such that you don't need to write the brackets. This is because, in practise, this turns out to be a surprisingly common usage case so the little sugar is nice.interested in knowing exactly how it is not like an enum, not internally, not historically, but in terms of usage from a programmers POV?It doesn't enumerate anything? Enumerations are collections of items, aren't they? How is one element a collection?
Nov 28 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065I believe the similarity you've listed is false. An enumerated type must be integral (it must be countable!) A manifest constant, however, can be anything - a struct literal, for example.... really? But D supports typing enums: enum E : string { X = "hello", Y = "world" } I tried: enum E : string { X = "hello", Y } Sure, this would normally try and increment by one, but since it's not integral I got this error: incompatible types for (("hello") + (1)): 'S' and 'int' Makes perfect sense to me, apparently you just lose the auto-increment behaviour if the enums are not an integeral type? (although the error message could be clearer) So perhaps you mean, "must be integral if you want auto-increment behaviour"? Often enough you don't even want auto-increment, you want a collection of meaningful pre-defined values, I think that's just as good a definition of the term 'enumeration', auto-increment is not fundamental to this enumerated type concept in my mind. In fact, I think I might even use all-explicit values more often than auto-incremented ones in my code.I think what has happened is that C had a very sloppy enum design, where it mixed integral manifest constants with enumerated types. Instead of tightening up 'enum', we used the existing sloppiness as an excuse to make it worse.Worse? It's perfect... >_< -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 28 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065 Can I just add, we've derailed my actual bug thread here >_< This is an extremely important issue for me, which has been lost in the meaning of enum and whether 'manifest constant' is a stupid name or not. Any word on isStatic!(), good/bad one to have (I don't know how to do it manually)? These traits are of critical importance to me to help a bunch of non-D programmers feel that the language is awesome and intuitive; ie, 'can understand it when they read the code', and assure it is maintainable going forward. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 28 2012
http://d.puremagic.com/issues/show_bug.cgi?id=9065 PST ---An enumerated type must be integral (it must be countable!)This is not true at all in D. An enum can be any type which can be compared and can be use to directly initialize a variable at compile time. On top of that including built-in types like strings, TDPL specifically talks about declaring enums which are structs - and that's enums with a list of values, not manifest constants. It's incredibly valuable to be able to have enumerated lists of user-defined tpes rather than just integral values. I have no problem whatsoever calling enums which are manifest constants manifest constants rather than enums, but at the same time, the only differences between them and normal enums are the fact that they don't have a separate enum type and there's only one of them. Practically speaking, there's really no other difference. Neither have addresses. They're just values that get copy-pasted when used. So, while I have no problem with the term manifest constant, I don't think that it would cause any real problem to refer to them as anonymous enums instead. I do kind of wish that we'd gone with the keyword manifest over enum to better separate the two concepts, because manifest constants are actually enumerated, but from a pratical point of view, it's really a non-issue IMHO. If anything, normal enums are simply an enumeration of manifest constants. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 28 2012