March 19, 2007
On Mon, 19 Mar 2007 11:58:15 +0000 (UTC)
Thomas Kuehne <thomas-dloop@kuehne.cn> wrote:

> Do you use the original Phobos?
> 
> Line 65 checks if Object.toUtf8 is defined wich would indicate that Tango is installed. Failing to import tango.core.Vararg however indicates that Tango isn't installed.

Everything thats installed is from the original dmd.zip from digitalmars.com, I never had tango installed nor a non-standard phobos version or something.

I dont get it seems my rebuild is somehow messed up.
Strange it compiles my phobos code without complains
(and the code uses toString etc...)

Henning

-- 
v4sw7Yhw4ln0pr7Ock2/3ma7uLw5Xm0l6/7DGKi2e6t6ELNSTVXb7AHIMOen5a2Xs5Mr2g5ACPR hackerkey.com
March 19, 2007
On Mon, 19 Mar 2007 11:44:54 +0100, Henning Hasemann wrote:

> 
> I sometimes have some problems with this, as said before: Let SDL return
> a width as uint and have your positions int (because they also can be negative).
> 
> I had this problems with C already. Examples of questions I have often when coding:
> - "Hmm okay. You're a on-screen coordinate. You will be positive.
>   But I might to want to mix you with virtual and potetially negative
>   Coordinates. Also you wont be larger than 32000, as long as screens
>   wont get really big. But I somehow feel I should make you an int..."
> - Hm okay so I have these few things I know of they wont be negative.
>   Should I make them int nevertheless? Would avoid complications and warinings,
>   and the value range wouldnt be a problem.

Well, I think your problems is due to fundamental errors in your programming method. :-)

We all know the ordinary form of Hungarian notation as described in
http://www.duckware.com/bugfreec/chapter3.html#naming
but there is also a stronger form called app-Hungarian notation
where the prefix gives a hint of the purpose for the variable.
Like rowPos for a row position and colPos for a column position.
Now it is easy to spot buggy code like rowPos=colPos etc.

Using a type system we can take the idea a step further.

typedef int ROWPOS;
typedef int COLPOS;

foo
{
  ROWPOS rowPos;
  COLPOS colPos;

  rowPos = colPos; // error at compiler time.
}

So, the fundamental flaw is that you use raw types instead of making a type for each purpose in your code.

Could the compiler do something about it ?
Yes, it could provide a switch called -bugfree
which trows a error every time a non user defined type is
used in the code.

It would also be useful if we could add an invariance to the type instead of have to change it into a class or structure.
March 19, 2007
On Mon, 19 Mar 2007 14:20:31 +0000 (UTC)
Knud Soerensen <4tuu4k002@sneakemail.com> wrote:

> Well, I think your problems is due to fundamental errors in your programming method. :-)
> 
> We all know the ordinary form of Hungarian notation as described in
> http://www.duckware.com/bugfreec/chapter3.html#naming
> but there is also a stronger form called app-Hungarian notation
> where the prefix gives a hint of the purpose for the variable.
> Like rowPos for a row position and colPos for a column position.
> Now it is easy to spot buggy code like rowPos=colPos etc.

I always name my variables like this. Personally I event tend to
not use such shortcut-names as they sometimes tend do be misleading
and hard to read. (row is clear, but later you might come to a point
where you or someone in your project uses column because he thinks its
short enough and so on).
Also this has nothing to do with my problems, because my problem is
not that I adding things together that have nothing to do with
each other, but adding things together that *have* to do with
each other but are often of different signedness.

> Using a type system we can take the idea a step further.
> 
> typedef int ROWPOS;
> typedef int COLPOS;
> 
> foo
> {
>   ROWPOS rowPos;
>   COLPOS colPos;
> 
>   rowPos = colPos; // error at compiler time.
> }

Yeah sometimes I tend to this too,
but not for preventig errors like rowPos = colPos (as the
naming you suggested helps me enough).
But I also try to be careful
not to have too much typedefs and/or aliases (yes I know the difference)
to trivial types such as int as it might confuse a reader
that assumes something special or magical beyond this.

> So, the fundamental flaw is that you use raw types instead of making a type for each purpose in your code.

Are you really sure it is a good idea to have a typedef for each purpose? So a point struct would look like this for you:

typedef int COORD;
struct Point {
  COORD x, y;
}

right?

Dont get me wrong, I dont want to criticize this way of doing things
its just I never done it so much before because I am not sure
it is such a good idea.

> Could the compiler do something about it ?
> Yes, it could provide a switch called -bugfree
> which trows a error every time a non user defined type is
> used in the code.

C'mon, that would be silly.

> It would also be useful if we could add an invariance to the type instead of have to change it into a class or structure.

You mean something like
typedef ubyte DiceResult;

DiceResult.invariant {
   assert(1 <= value);
   assert(value <= 6);
}

... would be handy sometimes, I agree.

Henning

-- 
v4sw7Yhw4ln0pr7Ock2/3ma7uLw5Xm0l6/7DGKi2e6t6ELNSTVXb7AHIMOen5a2Xs5Mr2g5ACPR hackerkey.com
March 19, 2007
Thomas Kuehne wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Henning Hasemann schrieb am 2007-03-19:
> 
> <snip>
> 
>> 2.)
>> Another thing would be easy support for stack traced exceptions.
>> I tried flectioned last weak or so (just for this purpose) but it
>> didnt want to compile with my code (I think I was still on dmd-1.007 so
>> it might have been a bug there). I think STE's are of use
>> to many developers so they should be put into phobos or so.
> 
> Exactly what problems did you encounter?

Here's one I got testing flectioned with Tango.  Notice that fnB is missing from the trace:

C:\code\src\d\test\flectioned>test
Uh-oh!
----------------
0x0012FE24      0x004020BA D4glue12traceHandlerFPvZC5tango4core9Exception19
TracedExceptionInfo15FlectionedTrace5_ctorMFPvZC4glue12traceHandlerFPvZC5tango4c
ore9Exception19TracedExceptionInfo15FlectionedTrace
0x0012FE40      0x00402081      object.ClassInfo glue.traceHandler(void*)
0x0012FE64      0x00409068      object.ClassInfo tango.core.Exception.traceConte
xt(void*)
0x0012FE6C      0x00402018      void test.fnA()
0x0012FE74      0x00402054      int main(char[][])

C:\code\src\d\test\flectioned>type test.d
import tango.core.Exception;
import glue;

void fnA()
{
    fnB();
}

void fnB()
{
    throw new TracedException( "Uh-oh!" );
}

void main()
{
    fnA();
}

C:\code\src\d\test\flectioned>
March 19, 2007
On Mon, 19 Mar 2007 16:02:04 +0100, Henning Hasemann wrote:

> On Mon, 19 Mar 2007 14:20:31 +0000 (UTC)
> Knud Soerensen <4tuu4k002@sneakemail.com> wrote:
> 
>> Well, I think your problems is due to fundamental errors in your programming method. :-)
>> 
>> We all know the ordinary form of Hungarian notation as described in
>> http://www.duckware.com/bugfreec/chapter3.html#naming
>> but there is also a stronger form called app-Hungarian notation
>> where the prefix gives a hint of the purpose for the variable.
>> Like rowPos for a row position and colPos for a column position.
>> Now it is easy to spot buggy code like rowPos=colPos etc.
> 
> I always name my variables like this. Personally I event tend to
> not use such shortcut-names as they sometimes tend do be misleading
> and hard to read. (row is clear, but later you might come to a point
> where you or someone in your project uses column because he thinks its
> short enough and so on).
> Also this has nothing to do with my problems, because my problem is
> not that I adding things together that have nothing to do with
> each other, but adding things together that *have* to do with
> each other but are often of different signedness.

well in your talk about adding a unsigned position with a signed width to get a new position.

Idealy I would do
typedef int WIDTH;
typedef int POSITION;
POSITION.invariant {
 assert(0 <= value);
}

void main()
{
	POSITION pos=10;
	WIDTH wid=-2;
	pos=cast(POSITION)(pos+wid);
}

First it encapsulates the problem in the typedef,
the cast help to make it clear what is happening
and invariant allow us to test for runtime errors.

>> Using a type system we can take the idea a step further.
>> 
>> typedef int ROWPOS;
>> typedef int COLPOS;
>> 
>> foo
>> {
>>   ROWPOS rowPos;
>>   COLPOS colPos;
>> 
>>   rowPos = colPos; // error at compiler time.
>> }
> 
> Yeah sometimes I tend to this too,
> but not for preventig errors like rowPos = colPos (as the
> naming you suggested helps me enough).
> But I also try to be careful
> not to have too much typedefs and/or aliases (yes I know the difference)
> to trivial types such as int as it might confuse a reader
> that assumes something special or magical beyond this.

Well, it can also be used as a help:

typedef float RADIANS;
main
{
  2dshape box;
  ...
  box.rotate(cast(RADIANS)1.54);
}
Here it makes the code more readable and less confusing.



>> So, the fundamental flaw is that you use raw types instead of making a type for each purpose in your code.
> 

Remember we are talking about writing complete bug free programs here. That means that we ideally should be able to catch every conceivable bug early.

> Are you really sure it is a good idea to have a typedef for each purpose? So a point struct would look like this for you:
> 
> typedef int COORD;
> struct Point {
>   COORD x, y;
> }
> 
> right?
No, like.
typedef int XCOORD;
typedef int YCOORD;
struct Point {
 XCOORD x; YCOORD y;
}
 Or else your might get x and y confused :-)

> 
> Dont get me wrong, I dont want to criticize this way of doing things
> its just I never done it so much before because I am not sure
> it is such a good idea.
> 
>> Could the compiler do something about it ?
>> Yes, it could provide a switch called -bugfree
>> which trows a error every time a non user defined type is
>> used in the code.
> 
> C'mon, that would be silly.

Well the idea with the -bugfree switch was to be able to catch every conceivable bug at compiler time, not to go easy on the programmer :-)

> 
>> It would also be useful if we could add an invariance to the type instead of have to change it into a class or structure.
> 
> You mean something like
> typedef ubyte DiceResult;
> 
> DiceResult.invariant {
>    assert(1 <= value);
>    assert(value <= 6);
> }
> 

Exactly.

> ... would be handy sometimes, I agree.
> 
> Henning
>
March 19, 2007
I also had problems with Flectioned and DMD 1.007.
Please see the post on http://www.dsource.org/forums/viewtopic.php?t=2512
from March 6.

Luís

Thomas Kuehne wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Henning Hasemann schrieb am 2007-03-19:
>> On Mon, 19 Mar 2007 08:41:48 +0000 (UTC)
>> Thomas Kuehne <thomas-dloop@kuehne.cn> wrote:
>>
>>>> 2.)
>>>> Another thing would be easy support for stack traced exceptions.
>>>> I tried flectioned last weak or so (just for this purpose) but it
>>>> didnt want to compile with my code (I think I was still on dmd-1.007 so
>>>> it might have been a bug there). I think STE's are of use
>>>> to many developers so they should be put into phobos or so.
>>> Exactly what problems did you encounter?
>> It does not correctly recognise that I'm on phobos I guess because
>> when compiling I get:
>>
>> flectioned.d(78): module Vararg cannot read file 'tango/core/Vararg.d'
>>
>> I use dmd-1.009 and rebuild-0.12 for compiling. OS is linux.
>> dmd -c flectioned.d runs fine, so maybe rebuild is the real problem?
> 
> Do you use the original Phobos?
> 
> Line 65 checks if Object.toUtf8 is defined wich would indicate that
> Tango is installed. Failing to import tango.core.Vararg however
> indicates that Tango isn't installed.
> 
> Thomas
> 
> -----BEGIN PGP SIGNATURE-----
> 
> iD8DBQFF/ocSLK5blCcjpWoRAsoEAJwM1dz8BdczPa1pM++8Trx/bWpipQCgpfpx
> z8H3iAh1LAKbRrsKiF8BJxE=
> =eoj2
> -----END PGP SIGNATURE-----
March 19, 2007
Henning Hasemann wrote:
> I just start a few little things.
> 
> 1.)
[...]
> Of course, because here myFoo is default initialised to null this always gives
> a segfault where myFoo is first being used in such a way,
> so it is very easy to track down (if you use a debugger at least).
[...]
> 2.)
> Another thing would be easy support for stack traced exceptions.
> I tried flectioned last weak or so (just for this purpose) but it
> didnt want to compile with my code (I think I was still on dmd-1.007
> so it might have been a bug there). I think STE's are of use
> to many developers so they should be put into phobos or so.
>


I have found a handy way to catch seg-v's is by catching SIGSEGV with a function that throws an exception, that way I can get a stack trace using my DIY stack tracing. The first line in each function I write is:

scope(failure) writef("Backtrace@"__FILE__":"~itoa!(__LINE__)~\n);

it works just fine as long as you don't ever throw exceptions in normal code paths

March 20, 2007
Henning Hasemann wrote:
> [...]
> Are you really sure it is a good idea to have a typedef for each purpose?
> So a point struct would look like this for you:
> 
> typedef int COORD;
> struct Point {
>   COORD x, y;
> }
> 
> right?
> [...]

Absolutely.  90% of what programmers call builtin "types" are really *representations*.  That is, they are classifications of bit patterns that have nothing to do with "types".  In fact, if it's builtin, you can be pretty much guaranteed it's not a type.  For instance, "int" is only a type when every value that an int can take on has a semantically valid meaning for that variable, *and* when those values can be mixed with any other instance of "int" in a meaningful way.  In the vast majority of cases, that's not true.

Of course, the reason most people don't make proper types is A) they are lazy, and B) it implies additional cost.  However, as programs become bigger and correctness becomes more difficult to prove, using proper types becomes more important.  It's not easy to illustrate in a 100 line program, but it becomes perfectly obvious in a 100,000 line codebase.

Dave
March 20, 2007
Henning Hasemann wrote:
> 
> Are you really sure it is a good idea to have a typedef for each purpose?

Maybe not a typedef for each purpose, but more generally, a type for each concept.  I'm currently reading "Prefactoring" by Ken Pugh and he distills it nicely by saying "don't throw away information."  Most data have associated constraints, etc, and even if this doesn't seem important at the outset, it's far easier to refine an existing type later on than it is to try and figure out which instances of 'int' in your application represent a person's age, for example.


Sean
March 20, 2007

David B. Held wrote:
> Henning Hasemann wrote:
>> [...]
>> Are you really sure it is a good idea to have a typedef for each purpose?
>> So a point struct would look like this for you:
>>
>> typedef int COORD;
>> struct Point {
>>   COORD x, y;
>> }
>>
>> right?
>> [...]
> 
> Absolutely.  90% of what programmers call builtin "types" are really *representations*.  That is, they are classifications of bit patterns that have nothing to do with "types".  In fact, if it's builtin, you can be pretty much guaranteed it's not a type.  For instance, "int" is only a type when every value that an int can take on has a semantically valid meaning for that variable, *and* when those values can be mixed with any other instance of "int" in a meaningful way.  In the vast majority of cases, that's not true.
> 
> Of course, the reason most people don't make proper types is A) they are lazy, and B) it implies additional cost.  However, as programs become bigger and correctness becomes more difficult to prove, using proper types becomes more important.  It's not easy to illustrate in a 100 line program, but it becomes perfectly obvious in a 100,000 line codebase.
> 
> Dave

I agree with you; for instance, in my research project, I made heaps of typedefs to ensure that I never accidentally got my wires crossed.

The *massive* problem with this, however, is that it breaks *everything*.  You can't toString a typedefed type, you can't use writefln with it... you've basically got to start from scratch again. Which is a massive pain if you don't have access to the source :P  You end up just casting them back to their base type all the time, which kinda defeats the purpose of having them.

Eventually, I ended up using structs for all of my "typedefs" because that way I can actually make them useful.  It would be a *god send* if we could get type extensions.

	-- Daniel

-- 
int getRandomNumber()
{
    return 4; // chosen by fair dice roll.
              // guaranteed to be random.
}

v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP  http://hackerkey.com/