www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - DMD 1.019 and 2.003 releases

reply Walter Bright <newshound1 digitalmars.com> writes:
http://www.digitalmars.com/d/1.0/changelog.html
http://ftp.digitalmars.com/dmd.1.019.zip

http://www.digitalmars.com/d/changelog.html
http://ftp.digitalmars.com/dmd.2.003.zip
Jul 22 2007
next sibling parent reply Robert Fraser <fraserofthenight gmail.com> writes:
Beautiful! Just when I think D can't get better, it does! Thanks for all the
hard work.

May I ask why you put the road there before traits? I know there's a
std.traits, but perhaps a different keyword entirely or just a single
underscore might be more appropriate...? It looks a bit like a
compiler-specific extension to me...

Walter Bright Wrote:

 
 http://www.digitalmars.com/d/1.0/changelog.html
 http://ftp.digitalmars.com/dmd.1.019.zip
 
 http://www.digitalmars.com/d/changelog.html
 http://ftp.digitalmars.com/dmd.2.003.zip

Jul 22 2007
parent reply Walter Bright <newshound1 digitalmars.com> writes:
Robert Fraser wrote:
 May I ask why you put the road there before traits? I know there's a
std.traits, but perhaps a different keyword entirely or just a single
underscore might be more appropriate...? It looks a bit like a
compiler-specific extension to me...

I was thinking they should be buried inside of templates.
Jul 22 2007
parent reply Sean Kelly <sean f4.ca> writes:
Walter Bright wrote:
 Robert Fraser wrote:
 May I ask why you put the road there before traits? I know there's a 
 std.traits, but perhaps a different keyword entirely or just a single 
 underscore might be more appropriate...? It looks a bit like a 
 compiler-specific extension to me...

I was thinking they should be buried inside of templates.

But does that affect what the name should be?
Jul 22 2007
parent reply Walter Bright <newshound1 digitalmars.com> writes:
Sean Kelly wrote:
 Walter Bright wrote:
 Robert Fraser wrote:
 May I ask why you put the road there before traits? I know there's a 
 std.traits, but perhaps a different keyword entirely or just a single 
 underscore might be more appropriate...? It looks a bit like a 
 compiler-specific extension to me...

I was thinking they should be buried inside of templates.

But does that affect what the name should be?

Don't need a prominent keyword for it.
Jul 23 2007
next sibling parent Sean Kelly <sean f4.ca> writes:
Walter Bright wrote:
 Sean Kelly wrote:
 Walter Bright wrote:
 Robert Fraser wrote:
 May I ask why you put the road there before traits? I know there's a 
 std.traits, but perhaps a different keyword entirely or just a 
 single underscore might be more appropriate...? It looks a bit like 
 a compiler-specific extension to me...

I was thinking they should be buried inside of templates.

But does that affect what the name should be?

Don't need a prominent keyword for it.

True enough. I suppose I'm just used to the double-underscore prefix being reserved for compiler extensions. Sean
Jul 23 2007
prev sibling parent reply Robert Fraser <fraserofthenight gmail.com> writes:
Walter Bright Wrote:

 Sean Kelly wrote:
 Walter Bright wrote:
 Robert Fraser wrote:
 May I ask why you put the road there before traits? I know there's a 
 std.traits, but perhaps a different keyword entirely or just a single 
 underscore might be more appropriate...? It looks a bit like a 
 compiler-specific extension to me...

I was thinking they should be buried inside of templates.

But does that affect what the name should be?

Don't need a prominent keyword for it.

Hmmmm.... it just seems to disturb the zen of D (having one keyword with two underscores), and I think it'll be used just as much as some other keywords, whether it's buried in templates or not.
Jul 23 2007
parent Serg Kovrov <sergk mailinator.com> writes:
Robert Fraser wrote:
 Hmmmm.... it just seems to disturb the zen of D (having one keyword with two
underscores), and I think it'll be used just as much as some other keywords,
whether it's buried in templates or not.

I agree. keywords with underscores (no matter where and how many) are just wrong. --serg.
Jul 24 2007
prev sibling next sibling parent reply Kirk McDonald <kirklin.mcdonald gmail.com> writes:
Walter Bright wrote:
 
 http://www.digitalmars.com/d/1.0/changelog.html
 http://ftp.digitalmars.com/dmd.1.019.zip
 
 http://www.digitalmars.com/d/changelog.html
 http://ftp.digitalmars.com/dmd.2.003.zip

In the spec for the new ForeachRangeStatement, it says: "If Foreach is foreach, then the variable is set to LwrExpression, then incremented at the end of each iteration." What does "incremented" mean, exactly? If have a class or struct that defines opAddAssign, would it call foo.opAddAssign(1) (as ++foo does)? Similarly, would the foreach_reverse form call foo.opSubAssign(1)? -- Kirk McDonald http://kirkmcdonald.blogspot.com Pyd: Connecting D and Python http://pyd.dsource.org
Jul 22 2007
parent reply Walter Bright <newshound1 digitalmars.com> writes:
Kirk McDonald wrote:
 In the spec for the new ForeachRangeStatement, it says:
 
 "If Foreach is foreach, then the variable is set to LwrExpression, then 
 incremented at the end of each iteration."
 
 What does "incremented" mean, exactly? If have a class or struct that 
 defines opAddAssign, would it call foo.opAddAssign(1) (as ++foo does)? 
 Similarly, would the foreach_reverse form call foo.opSubAssign(1)?

Right now, it doesn't work with structs/classes, but when it does, it'll be as you wrote.
Jul 22 2007
parent reply BCS <ao pathlink.com> writes:
Reply to Walter,

 Kirk McDonald wrote:
 
 In the spec for the new ForeachRangeStatement, it says:
 
 "If Foreach is foreach, then the variable is set to LwrExpression,
 then incremented at the end of each iteration."
 
 What does "incremented" mean, exactly? If have a class or struct that
 defines opAddAssign, would it call foo.opAddAssign(1) (as ++foo
 does)? Similarly, would the foreach_reverse form call
 foo.opSubAssign(1)?
 

it'll be as you wrote.

what will this do foreach(float f; 1 .. toBigFor1ToIncrement) loop forever?
Jul 23 2007
parent Walter Bright <newshound1 digitalmars.com> writes:
BCS wrote:
 what will this do
 
 foreach(float f; 1 .. toBigFor1ToIncrement)
 
 loop forever?

The same thing as: for (float f = 1; f < toBigFor1ToIncrement; f++) What foreach ranges buy you is: 1) The type of the loop index is automatically inferred 2) The termination condition is evaluated only once While these may seem trivial, they are often a source of bugs.
Jul 23 2007
prev sibling next sibling parent reply Kirk McDonald <kirklin.mcdonald gmail.com> writes:
Walter Bright wrote:
 
 http://www.digitalmars.com/d/1.0/changelog.html
 http://ftp.digitalmars.com/dmd.1.019.zip
 
 http://www.digitalmars.com/d/changelog.html
 http://ftp.digitalmars.com/dmd.2.003.zip

Well, this __traits stuff is certainly going to give me something to think about. One note: the lexical page doesn't seem to list it as a keyword. How many times have I rewritten Pyd? Three? Well, no matter. This should make things interesting again. -- Kirk McDonald http://kirkmcdonald.blogspot.com Pyd: Connecting D and Python http://pyd.dsource.org
Jul 22 2007
next sibling parent Walter Bright <newshound1 digitalmars.com> writes:
Kirk McDonald wrote:
 Well, this __traits stuff is certainly going to give me something to 
 think about. One note: the lexical page doesn't seem to list it as a 
 keyword.
 
 How many times have I rewritten Pyd? Three? Well, no matter. This should 
 make things interesting again.
 

Hey, you asked for it <g>.
Jul 22 2007
prev sibling parent reply Pragma <ericanderton yahoo.removeme.com> writes:
Kirk McDonald wrote:
 Walter Bright wrote:
 http://www.digitalmars.com/d/1.0/changelog.html
 http://ftp.digitalmars.com/dmd.1.019.zip

 http://www.digitalmars.com/d/changelog.html
 http://ftp.digitalmars.com/dmd.2.003.zip

Well, this __traits stuff is certainly going to give me something to think about. One note: the lexical page doesn't seem to list it as a keyword. How many times have I rewritten Pyd? Three? Well, no matter. This should make things interesting again.

Kirk, I saw your blog post regarding this. Congrats. Looks like you had a bumper-crop of code reductions! -- - EricAnderton at yahoo
Jul 24 2007
parent reply Kirk McDonald <kirklin.mcdonald gmail.com> writes:
Pragma wrote:
 Kirk McDonald wrote:
 
 Walter Bright wrote:

 http://www.digitalmars.com/d/1.0/changelog.html
 http://ftp.digitalmars.com/dmd.1.019.zip

 http://www.digitalmars.com/d/changelog.html
 http://ftp.digitalmars.com/dmd.2.003.zip

Well, this __traits stuff is certainly going to give me something to think about. One note: the lexical page doesn't seem to list it as a keyword. How many times have I rewritten Pyd? Three? Well, no matter. This should make things interesting again.

Kirk, I saw your blog post regarding this. Congrats. Looks like you had a bumper-crop of code reductions!

The linked-to changeset was from last November, when D got tuples. I haven't committed anything using __traits, yet. -- Kirk McDonald http://kirkmcdonald.blogspot.com Pyd: Connecting D and Python http://pyd.dsource.org
Jul 24 2007
parent Pragma <ericanderton yahoo.removeme.com> writes:
Kirk McDonald wrote:
 Pragma wrote:
 Kirk McDonald wrote:

 Walter Bright wrote:

 http://www.digitalmars.com/d/1.0/changelog.html
 http://ftp.digitalmars.com/dmd.1.019.zip

 http://www.digitalmars.com/d/changelog.html
 http://ftp.digitalmars.com/dmd.2.003.zip

Well, this __traits stuff is certainly going to give me something to think about. One note: the lexical page doesn't seem to list it as a keyword. How many times have I rewritten Pyd? Three? Well, no matter. This should make things interesting again.

Kirk, I saw your blog post regarding this. Congrats. Looks like you had a bumper-crop of code reductions!

The linked-to changeset was from last November, when D got tuples. I haven't committed anything using __traits, yet.

D'oh. Shoulda read more carefully... ;) -- - EricAnderton at yahoo
Jul 24 2007
prev sibling next sibling parent Jascha Wetzel <"[firstname]" mainia.de> writes:
Walter Bright wrote:
 
 http://www.digitalmars.com/d/1.0/changelog.html
 http://ftp.digitalmars.com/dmd.1.019.zip
 
 http://www.digitalmars.com/d/changelog.html
 http://ftp.digitalmars.com/dmd.2.003.zip

new toys! neat! thanks :)
Jul 22 2007
prev sibling next sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Walter Bright" <newshound1 digitalmars.com> wrote in message 
news:f80p2n$2k7a$1 digitalmars.com...
 http://www.digitalmars.com/d/1.0/changelog.html
 http://ftp.digitalmars.com/dmd.1.019.zip

 http://www.digitalmars.com/d/changelog.html
 http://ftp.digitalmars.com/dmd.2.003.zip

You're really making it hard for me not to switch to D2.0. __traits looks absolutely amazing. Just remove const-ness and I'll switch ;)
Jul 22 2007
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message 
news:f817c6$a1o$1 digitalmars.com...

 You're really making it hard for me not to switch to D2.0.  __traits looks 
 absolutely amazing.  Just remove const-ness and I'll switch ;)

A question -- many of the descriptions of the __traits functions say that "an array is returned." But some of the samples look like tuples are being used: alias typeof(__traits(getVirtualFunctions, D, "foo")) b; foreach (t; b) writefln(typeid(t)); If this really did return an array, the typeof() it would be a single item, not a list, and you wouldn't be able to foreach over it. So does this return a tuple instead?
Jul 22 2007
parent Walter Bright <newshound1 digitalmars.com> writes:
Jarrett Billingsley wrote:
 A question -- many of the descriptions of the __traits functions say that 
 "an array is returned."  But some of the samples look like tuples are being 
 used:
 
 alias typeof(__traits(getVirtualFunctions, D, "foo")) b;
 foreach (t; b)
     writefln(typeid(t));
 
 If this really did return an array, the typeof() it would be a single item, 
 not a list, and you wouldn't be able to foreach over it.  So does this 
 return a tuple instead? 

getVirtualFunctions returns a tuple of expressions.
Jul 22 2007
prev sibling next sibling parent reply Max Samukha <samukha voliacable.com.removethis> writes:
On Sun, 22 Jul 2007 16:26:28 -0700, Walter Bright
<newshound1 digitalmars.com> wrote:

http://www.digitalmars.com/d/1.0/changelog.html
http://ftp.digitalmars.com/dmd.1.019.zip

http://www.digitalmars.com/d/changelog.html
http://ftp.digitalmars.com/dmd.2.003.zip

Thanks for 1300! There is a typo in the example for hasMember trait: 'm' struct member should be 'x'.
Jul 22 2007
parent Walter Bright <newshound1 digitalmars.com> writes:
Max Samukha wrote:
 There is a typo in the example for hasMember trait: 'm' struct member
 should be 'x'.  

Got it.
Jul 23 2007
prev sibling next sibling parent Aarti_pl <aarti interia.pl> writes:
Thank you! Great release!

---

I just would wish, that you don't use so much ugly underscores in front 
and in the middle of nice D keywords.

It's just a cosmetical issue, but nevertheless why to loose points here 
if it should be rather easy to change it? Good chance to change it in 
2.0 branch...

Probably it should also include __LINE__, __FILE__ and other Special 
Tokens,  which essentially *are* compile time reflections.

Regards
Marcin Kuszczak


Walter Bright pisze:
 
 http://www.digitalmars.com/d/1.0/changelog.html
 http://ftp.digitalmars.com/dmd.1.019.zip
 
 http://www.digitalmars.com/d/changelog.html
 http://ftp.digitalmars.com/dmd.2.003.zip

Jul 23 2007
prev sibling next sibling parent reply Christian Kamm <kamm.incasoftware shift-at-left-and-remove-this.de> writes:
Thanks for fixing bug 668!

With the new __traits, the documentation for getVirtualFunctions states that
it gets the "virtual overloads". What does that mean? If I make some of the
methods final, it lists them anyway.

Does it just get all overloads (and should be named getFunctionOverloads),
or is there some limitation?
Jul 23 2007
parent Walter Bright <newshound1 digitalmars.com> writes:
Christian Kamm wrote:
 Thanks for fixing bug 668!
 
 With the new __traits, the documentation for getVirtualFunctions states that
 it gets the "virtual overloads". What does that mean? If I make some of the
 methods final, it lists them anyway.

Final functions are still virtual (since the super classes are still calling it).
 Does it just get all overloads (and should be named getFunctionOverloads),
 or is there some limitation?

No, just the virtual functions.
Jul 23 2007
prev sibling next sibling parent reply Don Clugston <dac nospam.com.au> writes:
Walter Bright wrote:
 
 http://www.digitalmars.com/d/1.0/changelog.html
 http://ftp.digitalmars.com/dmd.1.019.zip
 
 http://www.digitalmars.com/d/changelog.html
 http://ftp.digitalmars.com/dmd.2.003.zip

2.0 suddenly becomes very appealing ... I'm having trouble understanding the difference between "isScalar", "isArithmetic", and "isIntegral". Is this table correct? int uint real wchar Y Y Y N isArithmetic N N Y N isFloating Y Y N Y isIntegral Y Y Y Y isScalar N Y N N isUnsigned ----------------
Jul 23 2007
parent reply Walter Bright <newshound1 digitalmars.com> writes:
Don Clugston wrote:
 I'm having trouble understanding the difference between "isScalar", 
 "isArithmetic", and "isIntegral". Is this table correct?
 
 int uint real wchar
 Y   Y    Y    N     isArithmetic
 N   N    Y    N     isFloating
 Y   Y    N    Y     isIntegral
 Y   Y    Y    Y     isScalar
 N   Y    N    N     isUnsigned
 
 ----------------

wchar is arithmetic and unsigned.
Jul 23 2007
next sibling parent reply Don Clugston <dac nospam.com.au> writes:
Walter Bright wrote:
 Don Clugston wrote:
 I'm having trouble understanding the difference between "isScalar", 
 "isArithmetic", and "isIntegral". Is this table correct?

 int uint real wchar
 Y   Y    Y    N     isArithmetic
 N   N    Y    N     isFloating
 Y   Y    N    Y     isIntegral
 Y   Y    Y    Y     isScalar
 N   Y    N    N     isUnsigned

 ----------------

wchar is arithmetic and unsigned.

OK. Then is there any difference between scalar and arithmetic ?
Jul 23 2007
next sibling parent Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Don Clugston wrote:
 Walter Bright wrote:
 Don Clugston wrote:
 I'm having trouble understanding the difference between "isScalar", 
 "isArithmetic", and "isIntegral". Is this table correct?

 int uint real wchar
 Y   Y    Y    N     isArithmetic
 N   N    Y    N     isFloating
 Y   Y    N    Y     isIntegral
 Y   Y    Y    Y     isScalar
 N   Y    N    N     isUnsigned

 ----------------

wchar is arithmetic and unsigned.

OK. Then is there any difference between scalar and arithmetic ?

I haven't checked DMDs handling of this, but if I understand the terms correctly then the difference should be in the handling of complex types (cfloat & friends) which should be arithmetic types but not scalar ones.
Jul 23 2007
prev sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Don Clugston wrote:
 Walter Bright wrote:
 Don Clugston wrote:
 I'm having trouble understanding the difference between "isScalar", 
 "isArithmetic", and "isIntegral". Is this table correct?

 int uint real wchar
 Y   Y    Y    N     isArithmetic
 N   N    Y    N     isFloating
 Y   Y    N    Y     isIntegral
 Y   Y    Y    Y     isScalar
 N   Y    N    N     isUnsigned

 ----------------

wchar is arithmetic and unsigned.

OK. Then is there any difference between scalar and arithmetic ?

scalar includes pointers.
Jul 23 2007
parent reply Derek Parnell <derek psych.ward> writes:
On Mon, 23 Jul 2007 12:22:32 -0700, Walter Bright wrote:

 Don Clugston wrote:
 Walter Bright wrote:
 Don Clugston wrote:
 I'm having trouble understanding the difference between "isScalar", 
 "isArithmetic", and "isIntegral". Is this table correct?

 int uint real wchar
 Y   Y    Y    N     isArithmetic
 N   N    Y    N     isFloating
 Y   Y    N    Y     isIntegral
 Y   Y    Y    Y     isScalar
 N   Y    N    N     isUnsigned

 ----------------

wchar is arithmetic and unsigned.

OK. Then is there any difference between scalar and arithmetic ?

scalar includes pointers.

And yet one can do (some) arithmetic on pointers ... !? import std.stdio; void main() { int i; int* p; p = &i; p += 2; writefln("%s %s", &i, p); } -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Jul 23 2007
parent Walter Bright <newshound1 digitalmars.com> writes:
Derek Parnell wrote:
 On Mon, 23 Jul 2007 12:22:32 -0700, Walter Bright wrote:
 
 Don Clugston wrote:
 Walter Bright wrote:
 Don Clugston wrote:
 I'm having trouble understanding the difference between "isScalar", 
 "isArithmetic", and "isIntegral". Is this table correct?

 int uint real wchar
 Y   Y    Y    N     isArithmetic
 N   N    Y    N     isFloating
 Y   Y    N    Y     isIntegral
 Y   Y    Y    Y     isScalar
 N   Y    N    N     isUnsigned

 ----------------




And yet one can do (some) arithmetic on pointers ... !?

Yes. These definitions of integral, arithmetic, and scalar are common in C derived languages (and is defined in the C standard, too).
Jul 23 2007
prev sibling parent reply Derek Parnell <derek psych.ward> writes:
On Mon, 23 Jul 2007 09:45:57 -0700, Walter Bright wrote:

 Don Clugston wrote:
 I'm having trouble understanding the difference between "isScalar", 
 "isArithmetic", and "isIntegral". Is this table correct?
 
 int uint real wchar
 Y   Y    Y    N     isArithmetic
 N   N    Y    N     isFloating
 Y   Y    N    Y     isIntegral
 Y   Y    Y    Y     isScalar
 N   Y    N    N     isUnsigned
 
 ----------------

wchar is arithmetic and unsigned.

Are you serious??? Why are we allowed to do mathematics with characters? dchar r = power( 'a' * 'b' + 'd' * '€') / '$'; Doesn't make sense so why is wchar arithmetic? If you insist in this wart, then we also need an 'isCharacter' trait to distinguish characters from numbers. -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Jul 23 2007
parent reply BCS <ao pathlink.com> writes:
Reply to Derek,

 Are you serious??? Why are we allowed to do mathematics with
 characters?
 

I have done this a few times char c; int v = (c - '0')
Jul 23 2007
parent reply James Dennett <jdennett acm.org> writes:
BCS wrote:
 Reply to Derek,
 
 Are you serious??? Why are we allowed to do mathematics with
 characters?

I have done this a few times char c; int v = (c - '0')

Perfectly reasonable, as is character +/- integer, but character + character is nonsense, just as it makes sense to subtract two points yielding a vector, or add a vector to a point (yielding a point) but no sense to "add" two points in a mere affine space. -- James
Jul 23 2007
next sibling parent reply Derek Parnell <derek nomail.afraid.org> writes:
On Mon, 23 Jul 2007 21:25:31 -0700, James Dennett wrote:

 BCS wrote:
 Reply to Derek,
 
 Are you serious??? Why are we allowed to do mathematics with
 characters?

I have done this a few times char c; int v = (c - '0')

Perfectly reasonable, as is character +/- integer, but character + character is nonsense, just as it makes sense to subtract two points yielding a vector, or add a vector to a point (yielding a point) but no sense to "add" two points in a mere affine space.

I'm sorry. I am a bit of a pedantic bastard at times. I use ... char c; int v = (cast(int)c - '0') To me it the same as assuming that boolean values are integers. -- Derek (skype: derek.j.parnell) Melbourne, Australia 24/07/2007 3:13:04 PM
Jul 23 2007
next sibling parent reply 0ffh <spam frankhirsch.net> writes:
Derek Parnell wrote:
 I use ...
 
  char c;
  int v = (cast(int)c - '0')
 
 To me it the same as assuming that boolean values are integers.

You suggest writing things like for (int c=0x100;c!=0;--c) {...} or for (int c=0x100;cast(bool)c;--c) {...} ? UGH! :-) Maybe another example what systems programming language might mean: A language that encourages the programmer to know what is going on behind the scenes, after compilation, and allows her to make use of that knowledge. If I know that testing a condition is nothing but comparing a number to zero, writing "if (number!=0)" just becomes redundant. Regards, Frank
Jul 23 2007
next sibling parent Derek Parnell <derek nomail.afraid.org> writes:
On Tue, 24 Jul 2007 08:39:49 +0200, 0ffh wrote:

 Derek Parnell wrote:
 I use ...
 
  char c;
  int v = (cast(int)c - '0')
 
 To me it the same as assuming that boolean values are integers.

You suggest writing things like for (int c=0x100;c!=0;--c) {...} or for (int c=0x100;cast(bool)c;--c) {...} ?

Yep. That's how I tend to do my non-assembler coding, but with a lot more white space, less 'jargon', and avoid magic numbers :-) const MaxWidgetCount = 256; for (int lRemaining = MaxWidgetCount; lRemaining != 0; lRemaining--) { ... }
 UGH! :-)

 Maybe another example what systems programming language might mean:
 A language that encourages the programmer to know what is going on
 behind the scenes, after compilation, and allows her to make use of
 that knowledge.
 If I know that testing a condition is nothing but comparing a number
 to zero, writing "if (number!=0)" just becomes redundant.

I'm different. I write code so other people can read it with as little effort as possible ... and sometimes I even succeed <G> -- Derek (skype: derek.j.parnell) Melbourne, Australia 24/07/2007 4:53:26 PM
Jul 24 2007
prev sibling parent reply BCS <ao pathlink.com> writes:
Reply to 0ffh,

 If I know that testing a condition is nothing but comparing a number
 to zero, writing "if (number!=0)" just becomes redundant.

actually ASM usually has built in >, < and = comparisons, some times these implicitly use 0 for the other side, but it still it is not /just/ a zero test.
Jul 24 2007
parent reply 0ffh <spam frankhirsch.net> writes:
BCS wrote:
 Reply to 0ffh,
 
 If I know that testing a condition is nothing but comparing a number
 to zero, writing "if (number!=0)" just becomes redundant.

actually ASM usually has built in >, < and = comparisons, some times these implicitly use 0 for the other side, but it still it is not /just/ a zero test.

Forgive me if I am being thick, but given C (or even D), when does "if (x!=0)" (or "if (x!=null)") ever give a different result from "if (x)"? I am naturally speaking integral types and pointers, for floating point numbers the resulting code will obviously depend on the specific format used (though compilers will usually make it to act as expected, but I know I have to /know/, not assume). As to why "if (x)" is (at least historically) a Good Thing (tm): If "x" is any kind of calculation, that calculation will usually implicitly set (or clear) the zero flag of the CPU, doing away with the need for any kind of comparison at all. On some machines just loading the value of a memory location into a register will work the zero flag. On many, doing something like OR or AND of the register against itself will do the trick a bit faster than actually comparing against any number (including zero). On the x86, at some point of time, TESTing a memory location was faster than CMPing it (with a very pinch-of-salty IIRC). Especially "while" does usually gain some benefit from those cases. (And of cause a good back end optimisation will still exploit those because it knows that the "(x!=0)" is the same special case as the "(x)", granted.) So my defense is reduced to it being a good and useful convention, as I cherish every keystroke I don't have to execute, and it's really easy to learn and get used to... and, above all else, it /looks/ better! ;-) Regards, Frank
Jul 24 2007
parent reply BCS <ao pathlink.com> writes:
Reply to 0ffh,

 BCS wrote:
 
 Reply to 0ffh,
 
 If I know that testing a condition is nothing but comparing a number
 to zero, writing "if (number!=0)" just becomes redundant.
 

these implicitly use 0 for the other side, but it still it is not /just/ a zero test.

"if (x!=0)" (or "if (x!=null)") ever give a different result from "if (x)"?

Never to my understanding. However this is a good reason to do the more verbose one in that the compiler gets more info and then can use that for optimization (maybe). That however is more of a general rule rather than just for this case.
Jul 24 2007
parent reply 0ffh <spam frankhirsch.net> writes:
BCS wrote:
 Reply to 0ffh,
 BCS wrote:
 Reply to 0ffh,
 [...]



verbose one in that the compiler gets more info and then can use that for optimization (maybe).

Well, if we agree the semantics are identical, then so is the info the compiler has (phew, I'm glad that this works both ways...).
 That however is more of a general rule rather than just for this case.

I accept it as a general rule. =) Kind regards, Frank
Jul 24 2007
parent reply Robert Fraser <fraserofthenight gmail.com> writes:
0ffh Wrote:

 BCS wrote:
 Reply to 0ffh,
 BCS wrote:
 Reply to 0ffh,
 [...]



verbose one in that the compiler gets more info and then can use that for optimization (maybe).

Well, if we agree the semantics are identical, then so is the info the compiler has (phew, I'm glad that this works both ways...). > That however is more of a general rule rather than just for this case. I accept it as a general rule. =) Kind regards, Frank

There was a discussion of this on digitalmars.D recently. While that syntax works fine for most cases, it doesn't work in (non-static) asserts for aggregate types with invariants: assert(obj) runs the object's invariant() method, which will segfault if the object is null instead of giving a nice assertion failure. "if(x != 0)" is just more explicit than "if(x)", but not many people use "if(b != false)" (unless you're that guy where I wrote who wrote "while(m_userSubscribed == Boolean.FALSE.booleanValue())", which I sincerely hope wasn't sincere), so being concise isn't bad as long as you're meaning is clear. I think it looks ugly in for loops, though: for(int i = 100; i; i--) // Takes a second to mentally figure out what's going on
Jul 24 2007
next sibling parent reply Derek Parnell <derek psyc.ward> writes:
On Tue, 24 Jul 2007 20:55:41 -0400, Robert Fraser wrote:

 for(int i = 100; i; i--) // Takes a second to mentally figure out what's going
on

I'm still not explaining myself I guess. Yes, it doesn't take much to work out what the compiler is going to generate for that code. But that is not the issue I'm addressing. If one see's a line of code like that one has trouble recognising that what was written may not have been what was intended to be written. How do we know that the code shouldn't have been ... for(int i = 100; i>1; i--) and the coder made a small typo out of (bad?) habits. If however, one gets used to typing 'i>0' or similar fully specified comparisions, we all have a better confidence level that the code is written as intended to be written. Of course, it is not a way to prevent all errors, but just a technique to reduce coding errors. And a good compiler can still optimise such constructions without us having to hold its hand it all the way to the machine-code. I write program code for humans not for computers. It's the compiler's job to prepare it for the computer. Sorry that this sounds so pompous and self-righteous. That is not how I'm trying to sound. -- Derek Parnell Melbourne, Australia "Down with mediocrity!"
Jul 25 2007
next sibling parent Regan Heath <regan netmail.co.nz> writes:
Derek Parnell wrote:
 On Tue, 24 Jul 2007 20:55:41 -0400, Robert Fraser wrote:
 
 for(int i = 100; i; i--) // Takes a second to mentally figure out what's going
on

I'm still not explaining myself I guess. Yes, it doesn't take much to work out what the compiler is going to generate for that code. But that is not the issue I'm addressing. If one see's a line of code like that one has trouble recognising that what was written may not have been what was intended to be written. How do we know that the code shouldn't have been ... for(int i = 100; i>1; i--)

Well.. I'd say that is unlikely. The more likely meaning was: for(int i = 100; i > 0; i--) But! (to support your side of the argument here) the short form: for(int i = 100; i; i--) actually means: for(int i = 100; i != 0; i--) which is subtly different in the case where i is (mistakenly) set to a negative value inside the loop! So, in this case I would have to agree that "i > 0" has a different meaning to plain "i" and prevents a bug as well. In general, where the meaning is the same (i.e. "i == 0") I favour "if (i)" and have no trouble reading either form (which I think is a benefit we should all acquire you never know whose code you'll be reading next!) Regan
Jul 25 2007
prev sibling parent reply 0ffh <spam frankhirsch.net> writes:
Derek Parnell wrote:
 On Tue, 24 Jul 2007 20:55:41 -0400, Robert Fraser wrote:
 
 for(int i = 100; i; i--) // Takes a second to mentally figure out what's going
on

I'm still not explaining myself I guess. Yes, it doesn't take much to work out what the compiler is going to generate for that code. But that is not the issue I'm addressing.

I think maybe you wanted to address me here, not Robert. A second is a looonng time! :)
 If however, one gets used to typing 'i>0' or similar fully specified
comparisions,
 we all have a better confidence level that the code is written as intended to
be written.
 Of course, it is not a way to prevent all errors, but just a technique to
 reduce coding errors.

I know the argument well. I use it myself to argue for fully braced expressions instead of relying on operator precedence (apart from the usual exceptions). Also, braces will actually help me parsing. BUT there is a huge difference here: I'll repeat it this once before stopping to do this (I don't believe in reiteration contests): Using integers or pointers as bools is 1. /Easy/ to understand and use correctly 2. /Shorter/ - less to type and less to take in - and therefore 3. /Faster/ to parse mentally (once you're used to it), also it's 4. Not obligatory for those who feel uncomfortable with it, but 5. Looks one darn hell better than having a detrimental tumour of nop characters attached.
 I write program code for humans not for computers. It's the compiler's job
 to prepare it for the computer.

Source code is for humans, machine code for computers, so far we agree. But source code is for a /subclass/ of humans only: Those who are knowledgeable in the programming language that was used. If I don't know Miranda I will sure as heck not complain to Miranda programmers about their unreadable code, because it is /my friggin fault/. If I code in Miranda and I produce a bug because I do not understand the mechanisms involved, it is still /my friggin fault/.
 Sorry that this sounds so pompous and self-righteous. That is not how I'm
 trying to sound.

Blast, don't kick yourself! I'll do that! :) Regards, Frank The Eternally Distracted
Jul 25 2007
parent James Dennett <jdennett acm.org> writes:
0ffh wrote:
 Derek Parnell wrote:
 On Tue, 24 Jul 2007 20:55:41 -0400, Robert Fraser wrote:

 for(int i = 100; i; i--) // Takes a second to mentally figure out
 what's going on

I'm still not explaining myself I guess. Yes, it doesn't take much to work out what the compiler is going to generate for that code. But that is not the issue I'm addressing.

I think maybe you wanted to address me here, not Robert. A second is a looonng time! :)
 If however, one gets used to typing 'i>0' or similar fully specified
 comparisions,
 we all have a better confidence level that the code is written as
 intended to be written.
 Of course, it is not a way to prevent all errors, but just a technique to
 reduce coding errors.

I know the argument well. I use it myself to argue for fully braced expressions instead of relying on operator precedence (apart from the usual exceptions). Also, braces will actually help me parsing. BUT there is a huge difference here: I'll repeat it this once before stopping to do this (I don't believe in reiteration contests): Using integers or pointers as bools is 1. /Easy/ to understand and use correctly 2. /Shorter/ - less to type and less to take in - and therefore 3. /Faster/ to parse mentally (once you're used to it), also it's 4. Not obligatory for those who feel uncomfortable with it, but 5. Looks one darn hell better than having a detrimental tumour of nop characters attached.

And, with a similar amount of evidence, I claim that being explicit about comparisons with zero or null is 1. Easier to understand and use correctly; 2. More explicit - less to fill in implicitly, and therefore 3. Faster to parse mentally (once you're used to rigor), also it's 4. Not obligatory for those who feel uncomfortable with it, but 5. Looks one darn hell better than having expressions that are morally, if not technically, type errors left in code. I suspect, but cannot prove, that it's also less error-prone. However, without evidence, the debate is pointless. -- James
Jul 25 2007
prev sibling parent reply 0ffh <spam frankhirsch.net> writes:
Robert Fraser wrote:
 0ffh Wrote:
 "if(x != 0)" is just more explicit than "if(x)", but not many people use "if(b
!= false)" (unless you're that guy
 where I wrote who wrote "while(m_userSubscribed ==
Boolean.FALSE.booleanValue())", which I sincerely hope wasn't
 sincere), so being concise isn't bad as long as you're meaning is clear. I
think it looks ugly in for loops, though: 

So help me glod I did not, but I consider that code line to be sarcastic humour! :)
 for(int i = 100; i; i--) // Takes a second to mentally figure out what's going
on

Funny! I claim my brain parses the "i" /faster/ without the "=!0"! "if (x)" takes me half a glance to parse and understand. "if (x!=0)" takes at least three quarters of a glance. Maybe it's just a matter of being used to use this construct? Regards, Frank
Jul 25 2007
parent reply James Dennett <jdennett acm.org> writes:
0ffh wrote:
 Robert Fraser wrote:
 0ffh Wrote:
 "if(x != 0)" is just more explicit than "if(x)", but not many people
 use "if(b != false)" (unless you're that guy
 where I wrote who wrote "while(m_userSubscribed ==
 Boolean.FALSE.booleanValue())", which I sincerely hope wasn't
 sincere), so being concise isn't bad as long as you're meaning is
 clear. I think it looks ugly in for loops, though: 

So help me glod I did not, but I consider that code line to be sarcastic humour! :)
 for(int i = 100; i; i--) // Takes a second to mentally figure out
 what's going on

Funny! I claim my brain parses the "i" /faster/ without the "=!0"! "if (x)" takes me half a glance to parse and understand. "if (x!=0)" takes at least three quarters of a glance. Maybe it's just a matter of being used to use this construct?

No; you'll find that many of those who advocate the explicit approach are very used to both. It's best not to assume that people whose opinions differ from our own are less informed. -- James
Jul 25 2007
parent reply 0ffh <spam frankhirsch.net> writes:
James Dennett wrote:
 0ffh wrote:
 Maybe it's just a matter of being used to use this construct?

approach are very used to both. It's best not to assume that people whose opinions differ from our own are less informed.

I assume if you really, really tried, you could spot the difference between offering a noncommittal hypothesis and making an assumption.
Jul 26 2007
parent reply 0ffh <spam frankhirsch.net> writes:
Well, I suppose my last posting in this thread was
a bit emotional. I took offence and couldn't help
the urge to give some in return. I agologise.

Regards, Frank
Jul 27 2007
parent James Dennett <jdennett acm.org> writes:
0ffh wrote:
 
 Well, I suppose my last posting in this thread was
 a bit emotional. I took offence and couldn't help
 the urge to give some in return. I agologise.
 
 Regards, Frank

Apology accepted; we've all done similarly (and those who haven't, likely will one day). I'll offer my apology that my wording in previous posts may have seemed abrasive. It wasn't intended to be so, but I do tend to use a style some may perceive as adversarial. (I hope people try not to take me too seriously. I know I don't.) -- James
Jul 27 2007
prev sibling parent reply James Dennett <jdennett acm.org> writes:
Derek Parnell wrote:
 On Mon, 23 Jul 2007 21:25:31 -0700, James Dennett wrote:
 
 BCS wrote:
 Reply to Derek,

 Are you serious??? Why are we allowed to do mathematics with
 characters?

char c; int v = (c - '0')

character + character is nonsense, just as it makes sense to subtract two points yielding a vector, or add a vector to a point (yielding a point) but no sense to "add" two points in a mere affine space.

I'm sorry. I am a bit of a pedantic bastard at times.

You're in good company.
 I use ...
 
  char c;
  int v = (cast(int)c - '0')
 
 To me it the same as assuming that boolean values are integers.

Subtracting a char from an int, as you appear to be doing above, also makes no sense... or do casts in D bind insanely loosely? Subtracting one char from another actually makes more sense (see analogy above to affine geometry). It's a reasonable question to ask "which offset must I add to this char to get to this other char", but not "what's the difference between the number 27 and the character 'o'?". (And yes, I feel guilty/contaminated if I ever treat a boolean value as an integer, or vice versa.) -- James
Jul 24 2007
parent reply BCS <ao pathlink.com> writes:
Reply to James,

 (And yes, I feel guilty/contaminated if I ever treat a boolean value
 as an integer, or vice versa.)
 

a while ago I wrote a peice of C++ like this start: /// goto {&&start, &&stop}[!!i + 2 * !j]; stop: but then again it was for a bad code contest
Jul 24 2007
parent Paul Findlay <r.lph50+d gmail.com> writes:
 goto {&&start, &&stop}[!!i + 2 * !j];

- Paul
Jul 24 2007
prev sibling parent reply 0ffh <spam frankhirsch.net> writes:
James Dennett wrote:
 BCS wrote:
 char c;
 int v = (c - '0')

character + character is nonsense, just as it makes sense to subtract two points yielding a vector, or add a vector to a point (yielding a point) but no sense to "add" two points in a mere affine space.

So we get: char +/- int : okay int +/- char : okay char - char : okay char + char : baddie! I Look at this this way: Nobody in his right mind is gonna try to put into the compiler, which kinds of calculation make "sense" and which don't; that would be just insane. Also, in C at least a char is just another kind of number that just happens to be about the right size for an ASCII value, at least that's the way I look at it... ;-) Regards, Frank
Jul 23 2007
parent reply Walter Bright <newshound1 digitalmars.com> writes:
0ffh wrote:
 So we get:
 
   char +/- int  : okay
   int  +/- char : okay
   char  -  char : okay
   char  +  char : baddie!
 
 I Look at this this way: Nobody in his right mind is gonna
 try to put into the compiler, which kinds of calculation
 make "sense" and which don't; that would be just insane.

But I do things like: c += 'a' - 'A'; // to lower case The problem with explicit casts is that they are a brute force method, and subvert static type checking. A well designed systems allows a balance between implicit casting and strong type checking so that explicit casts are rarely needed in properly written programs.
Jul 24 2007
next sibling parent James Dennett <jdennett acm.org> writes:
Walter Bright wrote:
 0ffh wrote:
 So we get:

   char +/- int  : okay
   int  +/- char : okay
   char  -  char : okay
   char  +  char : baddie!

 I Look at this this way: Nobody in his right mind is gonna
 try to put into the compiler, which kinds of calculation
 make "sense" and which don't; that would be just insane.

But I do things like: c += 'a' - 'A'; // to lower case

Which is fine according to the above rules: it uses char-char (giving int, I hope), and then char+int (giving char, with risk of overflow/wraparound in more general contexts but not in this case).
 The problem with explicit casts is that they are a brute force method,
 and subvert static type checking. A well designed systems allows a
 balance between implicit casting and strong type checking so that
 explicit casts are rarely needed in properly written programs.

That's why I like the rules above. They permit all sane uses of arithmetic on characters while disallowing many erroneous uses, and with no need for casts. Not that I'm actually seriously suggesting changing D in this direction. This just isn't worth going against what most programmers with C/C++/Java-like backgrounds expect. -- James
Jul 24 2007
prev sibling next sibling parent reply BCS <ao pathlink.com> writes:
Reply to Walter,

 
 c += 'a' - 'A';   // to lower case

this is safer and faster (Ihink) c |= 0b0010_0000;
Jul 24 2007
next sibling parent reply James Dennett <jdennett acm.org> writes:
BCS wrote:
 Reply to Walter,
 
 c += 'a' - 'A';   // to lower case

this is safer and faster (Ihink) c |= 0b0010_0000;

Walter's version works on any platform where upper and lower case letters have the same arrangement, including any gaps; yours is pretty much tied to ASCII and extensions thereof. (On the other hand, yours is idempotent, whereas Walter's depends on knowing that c started as upper case.) -- James
Jul 24 2007
next sibling parent reply BCS <ao pathlink.com> writes:
Reply to James,

 Walter's version works on any platform where upper and lower case
 letters have the same arrangement, including any gaps; yours is pretty
 much tied to ASCII and extensions thereof.

good point, OTOH how often are non ASCII derived systems used (I've heard of a few but never run into any)
 (On the other hand, yours is idempotent, whereas Walter's depends on
 knowing that c started as upper case.)
 

Jul 24 2007
next sibling parent reply James Dennett <jdennett acm.org> writes:
BCS wrote:
 Reply to James,
 
 Walter's version works on any platform where upper and lower case
 letters have the same arrangement, including any gaps; yours is pretty
 much tied to ASCII and extensions thereof.

good point, OTOH how often are non ASCII derived systems used (I've heard of a few but never run into any)

With D, at present, probably none. Some mainframes and some embedded environments are the only remaining ones I know about (though my knowledge is, of course, a long long way from being encyclopedic.) -- James
Jul 24 2007
next sibling parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
James Dennett wrote:
 BCS wrote:
 Reply to James,

 Walter's version works on any platform where upper and lower case
 letters have the same arrangement, including any gaps; yours is pretty
 much tied to ASCII and extensions thereof.

heard of a few but never run into any)

With D, at present, probably none. Some mainframes and some embedded environments are the only remaining ones I know about (though my knowledge is, of course, a long long way from being encyclopedic.)

But both simple schemes for lowercasing will fail on things like accented characters. Seeing tricks like that just to avoid calling tolower() makes me cringe. --bb
Jul 24 2007
parent renoX <renosky free.fr> writes:
Bill Baxter a écrit :
 James Dennett wrote:
 BCS wrote:
 Reply to James,

 Walter's version works on any platform where upper and lower case
 letters have the same arrangement, including any gaps; yours is pretty
 much tied to ASCII and extensions thereof.

heard of a few but never run into any)

With D, at present, probably none. Some mainframes and some embedded environments are the only remaining ones I know about (though my knowledge is, of course, a long long way from being encyclopedic.)

But both simple schemes for lowercasing will fail on things like accented characters. Seeing tricks like that just to avoid calling tolower() makes me cringe. --bb

True, it only work for real ASCII which has no accentuated characters. renoX
Jul 24 2007
prev sibling parent reply Russell Lewis <webmaster villagersonline.com> writes:
James Dennett wrote:
 With D, at present, probably none.  Some mainframes and
 some embedded environments are the only remaining ones
 I know about (though my knowledge is, of course, a long
 long way from being encyclopedic.)

IBM still builds some machines which use EBCDIC, but with EBCDIC, things are even worse: the characters aren't even arranged contiguously in the space! So in EBCDIC char c; int i = c - 'a'; won't work! But you're right, I don't think that D is running on any of those...unless GDC is portable to one...
Jul 25 2007
parent BCS <BCS pathlink.com> writes:
Russell Lewis wrote:
 James Dennett wrote:
 
 With D, at present, probably none.  Some mainframes and
 some embedded environments are the only remaining ones
 I know about (though my knowledge is, of course, a long
 long way from being encyclopedic.)

IBM still builds some machines which use EBCDIC, but with EBCDIC, things are even worse: the characters aren't even arranged contiguously in the space! So in EBCDIC char c; int i = c - 'a'; won't work!

a-f and A-F are sequential so that works (after case conversion) and also a & A are different by only one bit so: c |= 'a' ^ 'A' c &= ~('a' ^ 'a') works, as does c += ('a' - 'A')
Jul 25 2007
prev sibling parent Walter Bright <newshound1 digitalmars.com> writes:
BCS wrote:
 Reply to James,
 
 Walter's version works on any platform where upper and lower case
 letters have the same arrangement, including any gaps; yours is pretty
 much tied to ASCII and extensions thereof.

good point, OTOH how often are non ASCII derived systems used (I've heard of a few but never run into any)

D kind of explicitly abandons things like EBCDIC anyway.
 
 (On the other hand, yours is idempotent, whereas Walter's depends on
 knowing that c started as upper case.)


Jul 24 2007
prev sibling parent reply 0ffh <spam frankhirsch.net> writes:
James Dennett wrote:
 BCS wrote:
 [...]

(On the other hand, yours is idempotent, whereas Walter's depends on knowing that c started as upper case.)

Wow, idempotent! I last read that word studying fuzzy logic! ;-))) Regards, Frank
Jul 24 2007
parent reply Georg Wrede <georg nospam.org> writes:
0ffh wrote:
 James Dennett wrote:
 
 BCS wrote:

 [...]

[...] (On the other hand, yours is idempotent, whereas Walter's depends on knowing that c started as upper case.)

Wow, idempotent! I last read that word studying fuzzy logic! ;-)))

Yes, a fancy word, indeed. OTOH, it's as important as "equivalence" and "implies".
Jul 24 2007
parent Pragma <ericanderton yahoo.removeme.com> writes:
Georg Wrede wrote:
 0ffh wrote:
 James Dennett wrote:

 BCS wrote:

 [...]

[...] (On the other hand, yours is idempotent, whereas Walter's depends on knowing that c started as upper case.)

Wow, idempotent! I last read that word studying fuzzy logic! ;-)))

Yes, a fancy word, indeed.

Indeed. It's a perfectly cromulent word. :)
 
 OTOH, it's as important as "equivalence" and "implies".

-- - EricAnderton at yahoo
Jul 25 2007
prev sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
BCS wrote:
 Reply to Walter,
 
 c += 'a' - 'A';   // to lower case

this is safer and faster (Ihink) c |= 0b0010_0000;

On modern processors, there is no speed difference between the two. I prefer the former only because I can't remember which bit it is <g>.
Jul 24 2007
next sibling parent Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Walter Bright wrote:
 BCS wrote:
 Reply to Walter,

 c += 'a' - 'A';   // to lower case

this is safer and faster (Ihink) c |= 0b0010_0000;

On modern processors, there is no speed difference between the two. I prefer the former only because I can't remember which bit it is <g>.

Well, that's easy: --- c |= 'a' ^ 'A'; --- :P Of course, then you'd have to remember whether the bit should be 1 or 0... And of course both methods will screw up for a lot of characters that aren't latin letters.
Jul 24 2007
prev sibling parent reply BCS <ao pathlink.com> writes:
Reply to Walter,

 BCS wrote:
 
 Reply to Walter,
 
 c += 'a' - 'A';   // to lower case
 

c |= 0b0010_0000;

prefer the former only because I can't remember which bit it is <g>.

Odd, I use \dmd\html\d\ascii-table.html to rememeber
Jul 24 2007
parent Walter Bright <newshound1 digitalmars.com> writes:
BCS wrote:
 Odd, I use \dmd\html\d\ascii-table.html to rememeber

I wrote that because I was tired of googling for "ascii table" and then getting one filled with popups.
Jul 24 2007
prev sibling parent reply Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
Walter Bright wrote:
 The problem with explicit casts is that they are a brute force method, 
 and subvert static type checking. A well designed systems allows a 
 balance between implicit casting and strong type checking so that 
 explicit casts are rarely needed in properly written programs.

I agree, but on a side note, shouldn't D's cast() operator be used exclusively to subvert *static* type checking? (Since currently it's also used to check the runtime type of class, instead of a separate construct like Java's 'instanceof', C#'s 'is', or C++'s 'dynamic_cast') -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Jul 25 2007
parent reply Walter Bright <newshound1 digitalmars.com> writes:
Bruno Medeiros wrote:
 I agree, but on a side note, shouldn't D's cast() operator be used 
 exclusively to subvert *static* type checking?
 (Since currently it's also used to check the runtime type of class, 
 instead of a separate construct like Java's 'instanceof', C#'s 'is', or 
 C++'s 'dynamic_cast')

I could argue it either way.
Jul 25 2007
parent Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
Walter Bright wrote:
 Bruno Medeiros wrote:
 I agree, but on a side note, shouldn't D's cast() operator be used 
 exclusively to subvert *static* type checking?
 (Since currently it's also used to check the runtime type of class, 
 instead of a separate construct like Java's 'instanceof', C#'s 'is', 
 or C++'s 'dynamic_cast')

I could argue it either way.

Some other interesting examples. --- Ruby obj.is_a? Class # Considers all ancestor classes obj.instanceof? Class # Only considers immediate class obj.class == Class # Same as above, naturally --- PHP is_a(obj, 'Class') The terms 'is' and 'is a' seem to be everywhere. (But I'm actually perfectly fine with the cast() style.) -- Chris Nicholson-Sauls
Jul 25 2007
prev sibling next sibling parent reply Don Clugston <dac nospam.com.au> writes:
Walter Bright wrote:
 
 http://www.digitalmars.com/d/1.0/changelog.html
 http://ftp.digitalmars.com/dmd.1.019.zip
 
 http://www.digitalmars.com/d/changelog.html
 http://ftp.digitalmars.com/dmd.2.003.zip

extern(System) works on 2.003, but on 1.019, it prints: xxx.d(13): valid linkage identifiers are D, C, C++, Pascal, Windows
Jul 23 2007
parent Walter Bright <newshound1 digitalmars.com> writes:
Don Clugston wrote:
 extern(System) works on 2.003, but on 1.019, it prints:
 xxx.d(13): valid linkage identifiers are D, C, C++, Pascal, Windows

Oh crud, looks like I didn't fold that one in right.
Jul 23 2007
prev sibling next sibling parent reply Christian Kamm <kamm.incasoftware shift-at-left-and-remove-this.de> writes:
Content-Type: text/plain; charset=iso-8859-15
Content-Transfer-Encoding: 8Bit

The extended compile time reflection opens the door for all kinds of cool
things! Here's an RTTI-Visitor, for instance. 

It uses compile-time foreach to build a sequence of if-statements that check
the classinfo and call the matching method.

Regards,
Christian
Jul 23 2007
next sibling parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Christian Kamm" <kamm.incasoftware shift-at-left-and-remove-this.de> wrote 
in message news:f823if$1seh$1 digitalmars.com...
 The extended compile time reflection opens the door for all kinds of cool
 things! Here's an RTTI-Visitor, for instance.

 It uses compile-time foreach to build a sequence of if-statements that 
 check
 the classinfo and call the matching method.

 Regards,
 Christian

That looks like multimethods. :D
Jul 23 2007
prev sibling next sibling parent reply "Craig Black" <cblack ara.com> writes:
"Christian Kamm" <kamm.incasoftware shift-at-left-and-remove-this.de> wrote 
in message news:f823if$1seh$1 digitalmars.com...
 The extended compile time reflection opens the door for all kinds of cool
 things! Here's an RTTI-Visitor, for instance.

 It uses compile-time foreach to build a sequence of if-statements that 
 check
 the classinfo and call the matching method.

 Regards,
 Christian

Cool, but it would be better to implement double dispatch than the Visitor pattern. It is ultimately more efficient and more flexible. -Craig
Jul 23 2007
parent Christian Kamm <kamm.incasoftware shift-at-left-and-remove-this.de> writes:
 Cool, but it would be better to implement double dispatch than the Visitor
 pattern.  It is ultimately more efficient and more flexible.

It is simple to implement multiple dispatch using the same method as for the single dispatch example. The overhead is the same: two virtual function calls and some ifs doing address comparisons. Might get less efficient or more complicated if you want to call the closest match instead of raising an error if there's no exact match. Christian
Jul 23 2007
prev sibling parent Robert Fraser <fraserofthenight gmail.com> writes:
Christian Kamm Wrote:

 The extended compile time reflection opens the door for all kinds of cool
 things! Here's an RTTI-Visitor, for instance. 
 
 It uses compile-time foreach to build a sequence of if-statements that check
 the classinfo and call the matching method.
 
 Regards,
 Christian
 // released into the public domain
 
 import std.stdio;
 
 class A
 {}
 
 class B : A
 {}
 
 class C : A
 {}
 
 class Dispatcher
 {
   void foo(A a)
 	{
 		writefln("A");
 	}
 	
 	void foo(B b)
 	{
 		writefln("B");
 	}	
 	
 	mixin Dispatch!("foo");
 }
 
 class ExDispatcher : Dispatcher
 {
 	alias Dispatcher.foo foo;
 	
 	override void foo(B b)
 	{
 		writefln("B override");
 	}
 	
 	void foo(C c)
 	{
 		writefln("C");
 	}
 	
 	mixin Dispatch!("foo");
 }
 
 void main()
 {
 	auto disp = new Dispatcher;	
 	disp.dispatch(new A); // calls disp.foo(A)
 	disp.dispatch(new B); // calls disp.foo(B)
 	
 	Dispatcher exdisp = new ExDispatcher;
 	exdisp.dispatch(new A); // calls disp.foo(A)
 	exdisp.dispatch(new B); // calls exdisp.foo(B)
 	exdisp.dispatch(new C); // calls exdisp.foo(C)
 }
 
 
 class MethodNotFoundException : Exception
 {
 	this(string msg) { super(msg); }
 }
 
 template Dispatch(string fname)
 {
 	mixin("alias typeof(" ~ fname ~ ") fsym;");
 	static if(is(fsym arg_types == function) && is(fsym return_type == return))
 	{
 		return_type dispatch(Object o, arg_types[1..$] params)
 		{
 			alias typeof(__traits(getVirtualFunctions, typeof(this), fname)) funcs;
 			foreach(i, func; funcs)
 			{
 				static if(is(func it_arg_types == function) && is(func it_return_type ==
return))
 				{
 					static assert(is(arg_types[1..$] == it_arg_types[1..$]) && is(return_type
== it_return_type), 
 						"Except for the first argument, the signature of all functions must be
identical.");
 					static assert(is(it_arg_types[0] == class), "First argument must be a
class type.");
 					
 					if(it_arg_types[0].classinfo is o.classinfo)
 						return __traits(getVirtualFunctions, this,
fname)[i](cast(it_arg_types[0]) o, params);
 				}
 				else
 					static assert(false, fname ~ " is not a function");
 			}
 			
 			throw new MethodNotFoundException("No matching method '" ~ fname ~ "' found
in " ~ this.classinfo.name ~ " for class " ~ o.classinfo.name);
 		}
 	}
 	else
 		static assert(false, fname ~ " is not a function");
 }
 
 

Awesome! My first thought was generating hash functions for arbitrary structures, which would make using classes in AAs much easier. But there's still a niche for runtime reflection!
Jul 23 2007
prev sibling next sibling parent Bastiaan Veelo <Bastiaan Veelo.net> writes:
Congratulations!

With "signals and slots" and now traits it looks like D is ready for a 
GUI toolkit to be written for it, complete with drag-and-drop GUI 
builder á la Qt Designer[1].

I can't wait to see that happen :-)

Bastiaan.

[1] http://trolltech.com/products/qt/features/designer


Walter Bright wrote:
 
 http://www.digitalmars.com/d/1.0/changelog.html
 http://ftp.digitalmars.com/dmd.1.019.zip
 
 http://www.digitalmars.com/d/changelog.html
 http://ftp.digitalmars.com/dmd.2.003.zip

Jul 23 2007
prev sibling next sibling parent reply "Craig Black" <cblack ara.com> writes:
Very nice Walter!  Question about traits.  I'm guessing allMembers returns 
both functions and fields?  Is there an isField or isFunction to 
differentiate?

-Craig 
Jul 23 2007
parent reply Walter Bright <newshound1 digitalmars.com> writes:
Craig Black wrote:
 Very nice Walter!  Question about traits.  I'm guessing allMembers returns 
 both functions and fields?  Is there an isField or isFunction to 
 differentiate?

You can look at the types to see if they are data or functions. But probably more traits need to be added - I thought I'd wait on that to see just what was required, rather than throw in a lot of useless geegaws. It's hard to predict in advance.
Jul 23 2007
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Walter Bright" <newshound1 digitalmars.com> wrote in message 
news:f82mav$2t9v$4 digitalmars.com...
 Craig Black wrote:
 Very nice Walter!  Question about traits.  I'm guessing allMembers 
 returns both functions and fields?  Is there an isField or isFunction to 
 differentiate?

You can look at the types to see if they are data or functions. But probably more traits need to be added - I thought I'd wait on that to see just what was required, rather than throw in a lot of useless geegaws. It's hard to predict in advance.

If you had class A { void function() f; void delegate() g; void foo() {} } What would be f's type, g's type, and foo's type?
Jul 23 2007
parent reply Walter Bright <newshound1 digitalmars.com> writes:
Jarrett Billingsley wrote:
 If you had
 
 class A
 {
     void function() f;
     void delegate() g;
     void foo() {}
 }
 
 What would be f's type, g's type, and foo's type? 

f: pointer to function returning void g: delegate returning void foo: function returning void
Jul 23 2007
parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Walter Bright" <newshound1 digitalmars.com> wrote in message 
news:f82v81$cvb$2 digitalmars.com...
 f: pointer to function returning void
 foo: function returning void

Ahh.. there's the distinction.
Jul 23 2007
prev sibling next sibling parent reply Carlos Santander <csantander619 gmail.com> writes:
Walter Bright escribió:
 
 http://www.digitalmars.com/d/1.0/changelog.html
 http://ftp.digitalmars.com/dmd.1.019.zip
 
 http://www.digitalmars.com/d/changelog.html
 http://ftp.digitalmars.com/dmd.2.003.zip

How can we check specific overloads with __traits? For example, class A { abstract void foo(); int foo(int i) { return i; } } void main () { auto isvirtual = __traits(isAbstractFunction, A.foo); // what is it? } BTW, the documentation for __traits has isVirtualFunction in the example for isAbstractFunction. -- Carlos Santander Bernal
Jul 23 2007
parent reply Walter Bright <newshound1 digitalmars.com> writes:
Carlos Santander wrote:
 Walter Bright escribió:
 http://www.digitalmars.com/d/1.0/changelog.html
 http://ftp.digitalmars.com/dmd.1.019.zip

 http://www.digitalmars.com/d/changelog.html
 http://ftp.digitalmars.com/dmd.2.003.zip

How can we check specific overloads with __traits? For example, class A { abstract void foo(); int foo(int i) { return i; } } void main () { auto isvirtual = __traits(isAbstractFunction, A.foo); // what is it? }

You'll need to split them apart with getVirtualFunctions, or cast the A.foo.
 BTW, the documentation for __traits has isVirtualFunction in the example 
 for isAbstractFunction.

Fixed.
Jul 23 2007
parent reply Carlos Santander <csantander619 gmail.com> writes:
Walter Bright escribió:
 Carlos Santander wrote:
 How can we check specific overloads with __traits? For example,

 class A
 {
     abstract void foo();
     int foo(int i) { return i; }
 }

 void main ()
 {
     auto isvirtual = __traits(isAbstractFunction, A.foo); // what is it?
 }

You'll need to split them apart with getVirtualFunctions, or cast the A.foo.

As for getVirtualFunctions, I'm guessing abstract foo would not be virtual, and the other one would. Am I right? As for casting, cast A.foo to what? -- Carlos Santander Bernal
Jul 24 2007
parent reply Walter Bright <newshound1 digitalmars.com> writes:
Carlos Santander wrote:
 Walter Bright escribió:
 Carlos Santander wrote:
 How can we check specific overloads with __traits? For example,

 class A
 {
     abstract void foo();
     int foo(int i) { return i; }
 }

 void main ()
 {
     auto isvirtual = __traits(isAbstractFunction, A.foo); // what is it?
 }

You'll need to split them apart with getVirtualFunctions, or cast the A.foo.

As for getVirtualFunctions, I'm guessing abstract foo would not be virtual, and the other one would. Am I right?

Abstractness is orthogonal to virtualness - in this case, they're still virtual.
 
 As for casting, cast A.foo to what?
 

To the type signature of the particular overload you want.
Jul 24 2007
parent Carlos Santander <csantander619 gmail.com> writes:
Walter Bright escribió:
 Carlos Santander wrote:
 Walter Bright escribió:
 Carlos Santander wrote:
 How can we check specific overloads with __traits? For example,

 class A
 {
     abstract void foo();
     int foo(int i) { return i; }
 }

 void main ()
 {
     auto isvirtual = __traits(isAbstractFunction, A.foo); // what is 
 it?
 }

You'll need to split them apart with getVirtualFunctions, or cast the A.foo.

As for getVirtualFunctions, I'm guessing abstract foo would not be virtual, and the other one would. Am I right?

Abstractness is orthogonal to virtualness - in this case, they're still virtual.

Lost me here. If both of them are still virtual, how could I "split them apart with getVirtualFunctions"?
 As for casting, cast A.foo to what?

To the type signature of the particular overload you want.

__traits(isAbstractFunction, cast (int delegate (int) ) A.foo) ? -- Carlos Santander Bernal
Jul 25 2007
prev sibling next sibling parent Robert Fraser <fraserofthenight gmail.com> writes:
Walter Bright Wrote:

 
 http://www.digitalmars.com/d/1.0/changelog.html
 http://ftp.digitalmars.com/dmd.1.019.zip
 
 http://www.digitalmars.com/d/changelog.html
 http://ftp.digitalmars.com/dmd.2.003.zip

BTW, is extern(System) mentioned in the docs (it's there under the list of available externs but it doesn't explain exactly what it does). I understand from the discussions before that it means extern(Windows) on Windows and extern(C) on Linux, but is there a generalized definition? What would it mean on Mac or Solaris? (extern(C), I'm guessing....)
Jul 23 2007
prev sibling next sibling parent Lutger <lutger.blijdestijn gmail.com> writes:
Wonderful, thank you very much!

On the subject of traits, would it be possible / helpful to have a trait 
to enumerate all members of a module?
Jul 24 2007
prev sibling next sibling parent reply "Lionello Lunesu" <lionello lunesu.remove.com> writes:
"Walter Bright" <newshound1 digitalmars.com> wrote in message 
news:f80p2n$2k7a$1 digitalmars.com...
 http://www.digitalmars.com/d/1.0/changelog.html
 http://ftp.digitalmars.com/dmd.1.019.zip

 http://www.digitalmars.com/d/changelog.html
 http://ftp.digitalmars.com/dmd.2.003.zip

Oww, I was quitely hoping that extern (System) would allow one to write extern (System) char[] bzip2(char[]); and that the compiler would then insert the necessary code to redirect stdin/out to the strings... Oh well.. Still a great release ; ) L.
Jul 26 2007
parent Daniel Keep <daniel.keep.lists gmail.com> writes:
Lionello Lunesu wrote:
 Oww, I was quitely hoping that extern (System) would allow one to write
 
 extern (System) char[] bzip2(char[]);
 
 and that the compiler would then insert the necessary code to redirect 
 stdin/out to the strings...

I'd have been annoyed if it had... all that work writing a bzip2 binding... :P -- Daniel
Jul 26 2007
prev sibling parent dennis luehring <dl.soluz gmx.net> writes:
Walter Bright schrieb:
 
 http://www.digitalmars.com/d/1.0/changelog.html
 http://ftp.digitalmars.com/dmd.1.019.zip
 
 http://www.digitalmars.com/d/changelog.html
 http://ftp.digitalmars.com/dmd.2.003.zip

great language, thx walter but some traits are missing :) isArray (true on static/dynamic or assoz arrays) and isDynamicArray and a clean way to get the value/keytype from arrays ciao dennis
Aug 05 2007