www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - simple display (from: GUI library for D)

reply Adam D. Ruppe <destructionator gmail.com> writes:
We discussed this first in the GUI library thread, but since it
meandered so much, I decided to split off into a new subject. Much
of what I say here will be old to anyone who saw the previous thread.
There's some new stuff nearer to the bottom though.

I, with input from others, have started writing a little module
for simple uses of a display. You can write to a bitmap, display it
to a window, and handle events all in an easy way. The basics are
cross platform, but you can use native function calls too.

http://arsdnet.net/dcode/simpledisplay.d

It's still very much in progress, but I think it's now at the point
where the direction I'm taking it is clear.

First, the simplest usage:

====
import simpledisplay;

void main() {
	auto image = new Image(255, 255);

	foreach(a; 0..255)
	foreach(b; 0..255)
		image.putPixel(a, b, Color(a, b, ((a + b) % 16) * 16));

	image.display();
}
===

Compile: dmd test.d simpledisplay.d


When run, it will pop up a window with a gradient thing with little
bars through it. Press any key and the window closes, exiting the
program.

On Windows, it uses GDI functions. On other systems, it tries to
use X Windows. Linux is the only one I've personally tested, but it
should work on OSX and FreeBSD too (without changing the code).


If you are making some data, then just want to display it, this
works. But, what if you want some interactivity?

Here's a simple HSL color picker:
http://arsdnet.net/dcode/simpledisplay_test2.d

Use these keys to pick your color: q/a change hue. s/w changes S.
e/d changes L. Press ESC to exit. Your color in rgb is printed to
stdout.


Here's the relevant parts of the code:

void main() {
	auto image = new Image(255, 255);
	auto win = new SimpleWindow(image);
	win.eventLoop(0,
		(dchar c) {
			writeln("Got a char event: ", c);

			if(c == 'q')
				h += 15;
                        // ...snip...

			foreach(a; 0..255)
			foreach(b; 0..255)
				image.putPixel(a, b, fromHsl(h, s, l));

			win.image = image;
		},
		(int key) {
			writeln("Got a keydown event: ", key);
			if(key == KEY_ESCAPE) {
				auto color = fromHsl(h, s, l);
				writefln("%02x%02x%02x", color.r, color.g, color.b);
				win.close();
			}
		});
}

First, we create an image. Then, a window based on that image. At
line two, your window will show up on the screen, just like
image.display() did above. But, here, instead of blocking, it
moves on to a user specified event loop.

SimpleWindow.eventLoop was inspired by std.concurrency.receive.
The first parameter is a pulse timer amount (not yet implemented).
If you set one, you'll get one of your delegates called at the
requested interval. The idea there is to make animations or games
easy to get started.

After that comes a list of delegates. They are matched to different
events by their signature. (dchar c) {} means a key was pressed,
and it passes you the character corresponding to that key.

(int c) {} is almost certain to change, but right now it matches
to key press events, and passes the platform-specific keycode. I'm
planning to put symbolic constants in with the same name across
platform to make that easier to use, but the values themselves are
likely to be platform-specific.



When we get a key event here, the image is redrawn with a new
color. win.image = image tells it you want the image redrawn with
the new image. It's a blunt instrument, but a simple and fairly
effective one.



The advantage of this approach is you can just have fun with
those pixels and handle keys, all right there inside main() - no
need to do subclasses just for a simple program. At the same time,
you can move those event handlers around easily enough, or even
change them at runtime, simply by using named delegates and assignment.

I plan to add more event possibilities so you can actually
make this do some good work for you. Ultimately, they'll also
be an (XEvent) {} and (HWND, LPARAM, WPARAM) event for when what
I provide isn't good enough, so you can always build more off it.
It's meant to be simple, but not horribly limiting.


======


Since last time I posted, I've reorganized the code inside
simpledisplay.d quite a bit. Instead of version Windows vs version
linux, it's now Windows and X11, reflecting the fact that X is
available on many operating systems. (Including Windows, actually,
but meh).

The Color struct is now rgba, but it doesn't use a. I like the
suggestion to template on different color spaces, but haven't gotten
around to that yet.

Next, Image and SimpleWindow are done pretty differently than before.
Now, the platform specific parts are put into a separate mixin
template: NativeImageImplementation!() and NativeSimpleWindowImpl...().
The public methods forward to those.

The reason for this is three fold:

a) It makes the public code a lot easier on the eyes. It was getting
into spaghetti version territory for a bit there... now it's nice
and clean.

b) The implementations can now be moved to their own modules. I haven't
simply because a single file is easier to distribute and play with,
but the final thing probably should split it up, and now it can.

c) It should be more obvious when something isn't implemented for an
operating system, while keeping the public ddoc all in one place.
versions


Before, Image was simply a byte array in a single format, meaning
to get to the native OS format for blitting, it had to be copied. Now,
the actual format is hidden inside impl. I'll add operator overloads
or structs (I really like Nick's idea of a fast vs cropped access
point) to hide it.

In the mean time though, the putPixel function forwards to the OS
implementation, which writes right to the image format expected there.

It's still not ultimately efficient, but it's better than copying
it twice every time we make a change.

I still like the idea of a set binary format being available so
we can save as a file, but that will be made a conversion function
instead of the default use. Actually, probably some kind of forward
range. Then the file save functions can accept those ranges and
translate them into .bmp or .png files as it streams in. (probably
image.byScanLine would be pretty useful for this!)

My HSL -> RGB converter is also in simpledisplay.d. It's actually
less than 500 lines, excluding the bindings pasted in at the bottom.
Not too bad.
Apr 08 2011
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Adam D. Ruppe:

 I, with input from others, have started writing a little module
 for simple uses of a display. You can write to a bitmap, display it
 to a window, and handle events all in an easy way. The basics are
 cross platform, but you can use native function calls too.
I'd like something like this in Phobos, or if this is not possible, a cabal-install-like command away. I sometimes use Python PyGame or Processing.
 import simpledisplay;
 
 void main() {
 	auto image = new Image(255, 255);
 
 	foreach(a; 0..255)
 	foreach(b; 0..255)
 		image.putPixel(a, b, Color(a, b, ((a + b) % 16) * 16));
 
 	image.display();
 }
Instead of: image.putPixel(a, b, Color(a, b, ((a + b) % 16) * 16)); I suggest something simpler like: image[a, b] = std.typecons.tuple(a, b, ((a + b) % 16) * 16); Instead of: image.display(); I suggest something like this, to swap the two image buffers: image.flip(); Plus maybe some image.event(); reader with callbacks... Bye, bearophile
Apr 08 2011
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
bearophile wrote:
 I'd like something like this in Phobos
Me too. It's still pretty far from good enough right now, but that's where I want ultimately want it. My only concern is I don't want Phobos to depend on Xlib unless the module is actually imported. I don't think it will be a problem, but if it means a hello world won't run on a text only machine, that won't be ok.
 I suggest something simpler like:
Yeah, moving to opIndex is something I plan to do. But, I don't really like using a tuple for this - a regular struct makes it a little clearer what's going on, and can be made more efficient. (In the other thread, Nick suggested making it a simple uint internally, using property functions to emulate other outside faces. I like that.) A struct might also have accessors with different color types too.
 I suggest something like this, to swap the two image buffers
That's not really what you're doing there - display actually pops up a new window and waits for the user to close it.
 Plus maybe some image.event(); reader with callbacks...
What would it do?
Apr 08 2011
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Adam D. Ruppe:

 My only concern is I don't want Phobos to depend on Xlib unless
 the module is actually imported. I don't think it will be a problem,
 but if it means a hello world won't run on a text only machine, that
 won't be ok.
I agree.
 But, I don't
 really like using a tuple for this - a regular struct makes it
 a little clearer what's going on, and can be made more efficient.
OK. (But for this module I think usage simplicity is more important than raw speed. Users that need more performance or more features are going to use something else and better. The idea here is to keep simple the things that are simple).
 (In the other thread, Nick suggested making it a simple uint
 internally, using property functions to emulate other outside
 faces. I like that.)
OK.
 I suggest something like this, to swap the two image buffers
That's not really what you're doing there - display actually pops up a new window and waits for the user to close it.
Indeed, I was suggesting to open the window at the top of the program, and at the bottom of the program to swap the two buffers and show the drawn one.
 Plus maybe some image.event(); reader with callbacks...
What would it do?
Read the events, like window closing, key pressed, mouse movements, etc. Take a look at Processing API, for ideas. There are many situations where a simple built-in graphics is useful. Beside the example of Processing (that has anti-aliasing), there are many programs/small games that need just some 2D graphics: http://rosettacode.org/wiki/Animate_a_pendulum Bye, bearophile
Apr 08 2011
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
bearophile wrote:
 OK. (But for this module I think usage simplicity is more
 important than raw speed.
The struct is at least equal in simplicity: image[x, y] = Color(r, g, b); vs image[x, y] = tuple(r, g, b);
 Indeed, I was suggesting to open the window at the top of the
 program, and at the bottom of the program to swap the two buffers
 and show the drawn one.
Sure, that's what happens in my second example. Right now it uses "window.image = newImage;" to flip it but I think I want to change that.
 Read the events, like window closing, key pressed, mouse
 movements, etc. Take a look at Processing API, for ideas.
Yes, my window object does this too. See the example here: http://arsdnet.net/dcode/simpledisplay_test2.d win.eventLoop() does it.
 http://rosettacode.org/wiki/Animate_a_pendulum
Heh, I think D will be winning that by Monday!
Apr 08 2011
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Adam D. Ruppe:

 The struct is at least equal in simplicity:
 
 image[x, y] = Color(r, g, b);
 
 vs
 
 image[x, y] = tuple(r, g, b);
A tuple is simpler, there is no new name to remember and use, new type to define, and 3-tuples come out of other generic computations, like zip: foreach (col; zip(reds, greens, blues)) image[x, y] = col; Generally D programmers probably need to learn to use tuples a bit more seriously and often :-)
 Yes, my window object does this too. See the example here:
 http://arsdnet.net/dcode/simpledisplay_test2.d
 
 win.eventLoop() does it.
I see. But those lambdas are a bit too much large put there. I suggest true named function moved elsewhere. Some other notes to your code: - generic imports like stdio are probably better before the most specific ones (this is done in well written Python code); - Inside the (dchar c) {} a switch seems better. - In Wrapped struct why are you using a checkLimits() instead of an invariant()?
 http://rosettacode.org/wiki/Animate_a_pendulum
Heh, I think D will be winning that by Monday!
Good, but Rosettacode site isn't a competition :-) Bye, bearophile
Apr 08 2011
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
bearophile wrote:
 http://rosettacode.org/wiki/Animate_a_pendulum
Here's the D version using the direct to screen functions. I === import std.math; import simpledisplay; void main() { auto win = new SimpleWindow(512, 512); real angle = PI / 2; real angleVelocity = 0; immutable real dt = 0.1; int length = 150; win.eventLoop(50, () { auto anchorX = win.width / 2 - 12; auto anchorY = win.height / 4; auto ballX = anchorX + cast(int) (sin(angle) * length); auto ballY = anchorY + cast(int) (cos(angle) * length); auto angleAcceleration = -9.81 / length * sin(angle); angleVelocity += angleAcceleration * dt; angle += angleVelocity * dt; auto painter = win.draw(); painter.fillColor = Color(255, 255, 255); painter.drawRectangle(0, 0, win.width, win.height); painter.outlineColor = Color(0, 0, 0); painter.drawLine(anchorX, anchorY, ballX, ballY); painter.fillColor = Color(0, 0, 0); painter.drawEllipse(anchorX - 3, anchorY - 4, anchorX + 3, anchorY + 4); painter.fillColor = fromHsl(30, 0.8, 0.4); painter.drawEllipse(ballX - 7, ballY - 7, ballX + 7, ballY + 7); } ); } === Exit the program by closing the window. Some comments. First, you'll see that the pulse timer is implemented, allowing the animation to easily happen. Then, there's a dozen lines to actually do the drawing, starting with auto painter = win.draw(); win.draw (name might change) returns a ScreenPainter struct, which gives access to the drawing directly in the window, via a handful of native api calls. This struct is necessary to handle some state and cleanup that the native APIs require. (It's destructor does it all for you though, so no need to think about it here.) You can draw images, text, pixels (slowly), lines, rectangles, arcs, and polygons with solid colors for filling and outline. It's the lowest common denominator between Windows GDI and Xlib. I agree with what Michel said earlier about it being a lot of fairly pointless effort to go further than this. Instead, we'll offer a rich set of cross-platform functions to draw to an image, and simply copy those images to the windows when we want to get fancy. (That's easy to do here: painter.drawImage(x, y, image); ) Moving on, I first clear the screen by drawing a large, white rectangle over the window. fillColor and outlineColor are settable properties that are implicitly used in the drawing functions. (This reflects how pens and brushes are tied to the HDC on Windows and foreground and background colors are tied to the GC on X - you don't pass colors to the individual functions on either native API either.) Following Windows' lead, all the functions use the two separate colors, one for the outline of the shape and one for filling it in, hence their names. Note that only outline is used for drawline lines and pixels. If you want to draw a shape without filling it in, first set the fill color to transparent: painter.fillColor = Color.transparent; (Color.transparent is a static method to conveniently return a color with alpha = 0.) Also in there, you can see me using the fromHsl helper function to return a Color specifying HSL values instead of RGB. Finally, I said this draws directly to the screen, but it actually doesn't... it double buffers underneath. No need to call a buffer.flip function though. ScreenPainter's destructor does it for you. You don't have to think about it. The buffer is preserved across calls and used to automatically handle WM_PAINT/Expose messages. ====== There's still a handful of little things and a lot of error checking needed, but I'm pretty happy with this as the screen drawing base. It covers all the easy stuff. The hard stuff will be in platform independent images. Anyway, here's the updated simpledisplay.d: http://arsdnet.net/dcode/simpledisplay.d
Apr 09 2011
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Adam D. Ruppe:

 Here's the D version using the direct to screen functions.
On Windows Vista the window often doesn't close when I hit the close window click at the top right. Probably quite more people will have to comment and think about this module and its API before adopting it. The length=150 too is better to be set as immutable. Most of the auto variables (but "painter") are better set to immutable. The delegate inside eventLoop doesn't need the (). Color(255, 255, 255) ==> Color.white Color(0, 0, 0) ==> Color.black painter.drawRectangle(0, 0, win.width, win.height) painter.clearAll(), or painter.clearAll(Color.white) or something similar. auto win = new SimpleWindow(512, 512); ==> auto win = new SimpleWindow(512, 512, "Pendulum"); win.eventLoop(10, {...}) does this semantics work with more than one window too? auto painter = win.draw(); painter.fillColor = Color(255, 255, 255); ==> sometimes a bit better: auto painter = win.draw(); with (painter) { fillColor = ... ... drawRectangle => rectangle or even "box" drawLine ==> line drawEllipse ==> ellipse circle fillColor ==> filling? outline => pen?
 This struct is necessary to handle some state
 and cleanup that the native APIs require.
This is not so nice...
 I agree with what Michel said earlier about it being a lot of
 fairly pointless effort to go further than this.
Reading keyboard chars, and mouse clicks & movements is very useful. Another useful thing is to plot a matrix of rgb or int or ubyte in grey shades, to speed up some basic usage. In PyGame/Numpy there is surfarray for this. Bye, bearophile
Apr 09 2011
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
bearophile wrote:
 The length=150 too is better to be set as immutable.
Yeah, I made that change after copy/pasting the code into my newsgroup post. win, painter, angle, and angular velocity were the only things left mutable in the end.
 The delegate inside eventLoop doesn't need the ().
I put it there for consistency with other events. While there are no other handlers in this example, there can be, and all the other ones take arguments.
 Color(255, 255, 255) ==> Color.white
 painter.clearAll(Color.white)
 auto win = new SimpleWindow(512, 512, "Pendulum");
Yeah, those are reasonable.
 win.eventLoop(10, {...})  does this semantics work with more than
 one window too?
I believe so, yes, but I haven't tried it and wouldn't mind if it didn't. If you need to use multiple windows at the same time, it'd probably be better to use DFL, DWT, GTK, Qt, etc. etc.
 drawRectangle => rectangle or even "box"
Heh, I used to call it box in my DOS programs. But, the functions it forwards to are called Rectangle() and XDrawRectangle(), so I want to be consistent with them so it's not a surprise to someone already familiar with with the other APIs. The reason I went with drawShape instead of just Shape is that functions are verbs, so generally, I like their names to be verbs too. There's exceptions, of course, but I don't these fit.
 outline => pen?
Pens do more than just color. I guess the real question is how complex should it be able to get? In the underlying APIs, you can make a pen with a color, a width, and a style (solid, dashed, etc). Since they both can do it, I think I will add it. (Some more advanced APIs can even do things like gradient pens. I hope the image manipulation functions we write will eventually be able to do this too, but since plain old X can't, it won't happen for the display painter.) Perhaps: painter.pen = Pen(Color(r, g, b), 1, Pen.Style.solid); (Or maybe new Pen()... have to think about that.) And offer an overload for the simple case where you only care about color. (or keep the current fillColor property.) Then, of course, something similar for Brush, which is used to fill the background. But, here, the idea was to keep it simple, so I went with just color. I guess that might be too simple.
 This is not so nice...
I'm sympathetic, but I don't agree losing the struct would be good. Even if the struct proves to be unnecessary (which it might be - I think you can hold on to a window HDC as long as you like, but it's not something I see often so I think it's discouraged), I'd still keep it. Having an automatic constructor and destructor available gives some flexibility on the implementation side without inconveniencing the user beyond a single function. For example, the implicit double buffering done here. You don't have to think about flipping it. It just works. Better yet, the implementation can disable it at will. BitBlt is slow over Remote Desktop on Windows, making double buffering laggy. But, you, the user, don't really need to know that, since it wasn't your problem in the first place. The ScreenPainter can make it's own decision about it.
 Reading keyboard chars, and mouse clicks & movements is very
 useful.
For that, you can pass other handlers to eventLoop. I still intend to define a few more you can use.
 Another useful thing is to plot a matrix of rgb or int or ubyte
 in grey shades, to speed up some basic usage. In PyGame/Numpy
 there is surfarray for this.
Sounds like what you'd use the Image class for, so I think we're good on that too. ==== A note: since I posted last, I changed my mind on something, and bearophile, I rather doubt you'll like it... Before, it was drawRectangle(int x1, int y2, int width, int height); Now, it is drawRectangle(Point upperLeft, Size size); So, at the usage, you now need to put in some more parenthesis and say what you mean: painter.drawRectangle(Point(0, 0), Size(win.width, win.height)); Why did I do this? Well, consider the following: drawRectangle(int x1, int y1, int x2, int y2); (This is, in fact, the signature in Windows GDI, whereas Xlib user width/height.) The types there are no different than the above, but meaning has changed. I'd be ok with saying "RTFM" to avoid having to use the structs. But, RTFM doesn't let you overload it, whereas the types do. Now, it can offer both drawRectangle(Point upperLeft, Size size); *and* drawRectangle(Point upperLeft, Point lowerRight); I'm sure you were thinking about named arguments for a moment there about width/height vs x2/y2. I did too. But, named arguments don't really exist in D (you can do them via library magic but not without) so it's moot, and I don't believe named arguments would offer the overloading possibilities, which I like. It can save some math while being quite natural. The Point struct also makes drawPolygon look a lot better, so it's of general use.
Apr 09 2011
next sibling parent Cliff Hudson <cliff.s.hudson gmail.com> writes:
One thing to consider, since I was impacted by this when writing a WPF app a
while back, is the difference between a 2-Vector and a Point.  In
particular, Vectors typically have some very useful methods on them, like
addition, rotation, transformations, etc. which frequently are not
associated with the Point type.  I don't know if you have or plan to support
this data type, but at least having simple transforms to/from Vector would
be nice.

- Cliff

On Sat, Apr 9, 2011 at 5:58 PM, Adam D. Ruppe <destructionator gmail.com>wrote:

 bearophile wrote:
 The length=150 too is better to be set as immutable.
Yeah, I made that change after copy/pasting the code into my newsgroup post. win, painter, angle, and angular velocity were the only things left mutable in the end.
 The delegate inside eventLoop doesn't need the ().
I put it there for consistency with other events. While there are no other handlers in this example, there can be, and all the other ones take arguments.
 Color(255, 255, 255) ==> Color.white
 painter.clearAll(Color.white)
 auto win = new SimpleWindow(512, 512, "Pendulum");
Yeah, those are reasonable.
 win.eventLoop(10, {...})  does this semantics work with more than
 one window too?
I believe so, yes, but I haven't tried it and wouldn't mind if it didn't. If you need to use multiple windows at the same time, it'd probably be better to use DFL, DWT, GTK, Qt, etc. etc.
 drawRectangle => rectangle or even "box"
Heh, I used to call it box in my DOS programs. But, the functions it forwards to are called Rectangle() and XDrawRectangle(), so I want to be consistent with them so it's not a surprise to someone already familiar with with the other APIs. The reason I went with drawShape instead of just Shape is that functions are verbs, so generally, I like their names to be verbs too. There's exceptions, of course, but I don't these fit.
 outline => pen?
Pens do more than just color. I guess the real question is how complex should it be able to get? In the underlying APIs, you can make a pen with a color, a width, and a style (solid, dashed, etc). Since they both can do it, I think I will add it. (Some more advanced APIs can even do things like gradient pens. I hope the image manipulation functions we write will eventually be able to do this too, but since plain old X can't, it won't happen for the display painter.) Perhaps: painter.pen = Pen(Color(r, g, b), 1, Pen.Style.solid); (Or maybe new Pen()... have to think about that.) And offer an overload for the simple case where you only care about color. (or keep the current fillColor property.) Then, of course, something similar for Brush, which is used to fill the background. But, here, the idea was to keep it simple, so I went with just color. I guess that might be too simple.
 This is not so nice...
I'm sympathetic, but I don't agree losing the struct would be good. Even if the struct proves to be unnecessary (which it might be - I think you can hold on to a window HDC as long as you like, but it's not something I see often so I think it's discouraged), I'd still keep it. Having an automatic constructor and destructor available gives some flexibility on the implementation side without inconveniencing the user beyond a single function. For example, the implicit double buffering done here. You don't have to think about flipping it. It just works. Better yet, the implementation can disable it at will. BitBlt is slow over Remote Desktop on Windows, making double buffering laggy. But, you, the user, don't really need to know that, since it wasn't your problem in the first place. The ScreenPainter can make it's own decision about it.
 Reading keyboard chars, and mouse clicks & movements is very
 useful.
For that, you can pass other handlers to eventLoop. I still intend to define a few more you can use.
 Another useful thing is to plot a matrix of rgb or int or ubyte
 in grey shades, to speed up some basic usage. In PyGame/Numpy
 there is surfarray for this.
Sounds like what you'd use the Image class for, so I think we're good on that too. ==== A note: since I posted last, I changed my mind on something, and bearophile, I rather doubt you'll like it... Before, it was drawRectangle(int x1, int y2, int width, int height); Now, it is drawRectangle(Point upperLeft, Size size); So, at the usage, you now need to put in some more parenthesis and say what you mean: painter.drawRectangle(Point(0, 0), Size(win.width, win.height)); Why did I do this? Well, consider the following: drawRectangle(int x1, int y1, int x2, int y2); (This is, in fact, the signature in Windows GDI, whereas Xlib user width/height.) The types there are no different than the above, but meaning has changed. I'd be ok with saying "RTFM" to avoid having to use the structs. But, RTFM doesn't let you overload it, whereas the types do. Now, it can offer both drawRectangle(Point upperLeft, Size size); *and* drawRectangle(Point upperLeft, Point lowerRight); I'm sure you were thinking about named arguments for a moment there about width/height vs x2/y2. I did too. But, named arguments don't really exist in D (you can do them via library magic but not without) so it's moot, and I don't believe named arguments would offer the overloading possibilities, which I like. It can save some math while being quite natural. The Point struct also makes drawPolygon look a lot better, so it's of general use.
Apr 09 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On 04/10/2011 02:58 AM, Adam D. Ruppe wrote:
 A note: since I posted last, I changed my mind on something, and
 bearophile, I rather doubt you'll like it...

 Before, it was drawRectangle(int x1, int y2, int width, int height);

 Now, it is drawRectangle(Point upperLeft, Size size);

 So, at the usage, you now need to put in some more parenthesis
 and say what you mean:

 painter.drawRectangle(Point(0, 0), Size(win.width, win.height));


 Why did I do this? Well, consider the following:

 drawRectangle(int x1, int y1, int x2, int y2);

 (This is, in fact, the signature in Windows GDI, whereas Xlib
   user width/height.)


 The types there are no different than the above, but meaning has
 changed. I'd be ok with saying "RTFM" to avoid having to use
 the structs.

 But, RTFM doesn't let you overload it, whereas the types do. Now,
 it can offer both

 drawRectangle(Point upperLeft, Size size);

 *and*

 drawRectangle(Point upperLeft, Point lowerRight);

 I'm sure you were thinking about named arguments for a moment
 there about width/height vs x2/y2. I did too. But, named arguments
 don't really exist in D (you can do them via library magic but not
 without) so it's moot, and I don't believe named arguments would
 offer the overloading possibilities, which I like. It can save
 some math while being quite natural.

 The Point struct also makes drawPolygon look a lot better, so
 it's of general use.
That was about the first change I intended to do on my side, after reading your code :-) In addition to the practical side you describe well, Point (or maybe better Position) is a nearly necessary semantic/conceptual type on the user side. Denis -- _________________ vita es estrany spir.wikidot.com
Apr 10 2011
prev sibling parent spir <denis.spir gmail.com> writes:
On 04/10/2011 03:03 AM, Cliff Hudson wrote:
 One thing to consider, since I was impacted by this when writing a WPF app a
 while back, is the difference between a 2-Vector and a Point.  In
 particular, Vectors typically have some very useful methods on them, like
 addition, rotation, transformations, etc. which frequently are not
 associated with the Point type.  I don't know if you have or plan to support
 this data type, but at least having simple transforms to/from Vector would
 be nice.
Very good remark. Eg a line can be defined by a point and a vector (a single-point one). denis -- _________________ vita es estrany spir.wikidot.com
Apr 10 2011
prev sibling parent spir <denis.spir gmail.com> writes:
On 04/09/2011 11:45 PM, Adam D. Ruppe wrote:

 There's still a handful of little things and a lot of error checking
 needed, but I'm pretty happy with this as the screen drawing base.
 It covers all the easy stuff. The hard stuff will be in platform
 independent images.

 Anyway, here's the updated simpledisplay.d:

 http://arsdnet.net/dcode/simpledisplay.d
That's great, Adam, thank you! Denis -- _________________ vita es estrany spir.wikidot.com
Apr 10 2011
prev sibling parent spir <denis.spir gmail.com> writes:
On 04/09/2011 02:42 AM, Adam D. Ruppe wrote:
 OK. (But for this module I think usage simplicity is more
  important than raw speed.
The struct is at least equal in simplicity: image[x, y] = Color(r, g, b); vs image[x, y] = tuple(r, g, b);
Indeed; and then: image[x, y].g versus image[x, y][1] Denis -- _________________ vita es estrany spir.wikidot.com
Apr 09 2011
prev sibling next sibling parent Michel Fortin <michel.fortin michelf.com> writes:
On 2011-04-08 20:11:10 -0400, Adam D. Ruppe <destructionator gmail.com> said:

 My only concern is I don't want Phobos to depend on Xlib unless
 the module is actually imported. I don't think it will be a problem,
 but if it means a hello world won't run on a text only machine, that
 won't be ok.
I'm concerned by this too. I think you need two modules. One for images images with absolutely no dependencies, and another for everything dealing with windows. Only if you import the window module you need to link with the relevant libraries. That means you'll need to change the image.display() shortcut to something else not a member of image. I don't think it's particularly good that images has such a member anyway, it'd be better as a standalone function in my opinion. (Actually, perhaps we need a third to deal with drawing which might also be dependent on system libraries, especially if needs to draw text.) -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Apr 08 2011
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2011-04-09 02:11, Adam D. Ruppe wrote:
 bearophile wrote:
 I'd like something like this in Phobos
Me too. It's still pretty far from good enough right now, but that's where I want ultimately want it. My only concern is I don't want Phobos to depend on Xlib unless the module is actually imported. I don't think it will be a problem, but if it means a hello world won't run on a text only machine, that won't be ok.
You can always dynamically link to the functions.
 I suggest something simpler like:
Yeah, moving to opIndex is something I plan to do. But, I don't really like using a tuple for this - a regular struct makes it a little clearer what's going on, and can be made more efficient. (In the other thread, Nick suggested making it a simple uint internally, using property functions to emulate other outside faces. I like that.) A struct might also have accessors with different color types too.
 I suggest something like this, to swap the two image buffers
That's not really what you're doing there - display actually pops up a new window and waits for the user to close it.
 Plus maybe some image.event(); reader with callbacks...
What would it do?
-- /Jacob Carlborg
Apr 10 2011
prev sibling next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
simpledisplay.d - line 267:
int lol, wtf;

lol, wtf? :p

Btw, an exception will be thrown on unhandled key events, e.g. just hit CTRL:
object.Exception .\simpledisplay.d(299): GetMessage failed

Not a good thing if you use shortcut keys to move windows around.
Apr 08 2011
parent Adam D. Ruppe <destructionator gmail.com> writes:
Andrej Mitrovic:
 lol, wtf? :p
My brilliant variable names! It reflects my feelings toward parts of the bmp format I forgot about when first writing it. I didn't account for the padding at first, then said "wtf" and added it... then "lol"'ed at myself for not doing it right the first time. You should have saw the original C version though: if(hbmp == NULL) goto fuck; :)
 Btw, an exception will be thrown on unhandled key events, e.g.
 just hit CTRL:
That's weird, I've never seen GetMessage fail... ever. I'll have to try it in real Windows later (I'm on linux / Wine right now).
Apr 08 2011
prev sibling next sibling parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from Adam D. Ruppe (destructionator gmail.com)'s article
 We discussed this first in the GUI library thread, but since it
 meandered so much, I decided to split off into a new subject. Much
 of what I say here will be old to anyone who saw the previous thread.
 There's some new stuff nearer to the bottom though.
 I, with input from others, have started writing a little module
 for simple uses of a display. You can write to a bitmap, display it
 to a window, and handle events all in an easy way. The basics are
 cross platform, but you can use native function calls too.
 http://arsdnet.net/dcode/simpledisplay.d
 It's still very much in progress, but I think it's now at the point
 where the direction I'm taking it is clear.
Can it render text? If so, I'll probably port Plot2kill to it if it becomes part of Phobos at some point. It would be kind of cool to have minimal Plot2kill functionality with zero third-party dependencies. If it's so basic that it can't even do text rendering, then I have my doubts about whether there are very many use cases for something so simple.
Apr 08 2011
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
dsimcha wrote:
 Can it render text?
Not yet, but it's on the list. Anything that's reasonably easy in both Windows API and Xlib should be supported here. At the least, text, lines, rectangles - all the basics.
Apr 08 2011
parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2011-04-08 20:18:03 -0400, Adam D. Ruppe <destructionator gmail.com> said:

 dsimcha wrote:
 Can it render text?
Not yet, but it's on the list. Anything that's reasonably easy in both Windows API and Xlib should be supported here. At the least, text, lines, rectangles - all the basics.
One issue is that different operating system will draw things with slightly different algorithms, which will result in slightly different images, which might introduce glitches from platform to platform. I wonder if it might not be better to implement our own drawing algorithms for geometric shapes, which in addition won't be dependent on any system library. I guess text drawing would need to be left system-dependent however... -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Apr 08 2011
next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Text drawing is as simple as TextDraw or TextOut on Windows. Dunno
about the nixes.
Apr 08 2011
parent Adam D. Ruppe <destructionator gmail.com> writes:
Andrej Mitrovic wrote:
 Text drawing is as simple as TextDraw or TextOut on Windows. Dunno
 about the nixes.
It's XDrawString() - almost the same. Text output is now implemented on my local copy of the module for both systems.
Apr 08 2011
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
Michel Fortin wrote:
 One issue is that different operating system will draw things with
 slightly different algorithms, which will result in slightly different
images, which might introduce glitches from platform to platform.
I actually hit an even bigger problem... Xlib can't actually draw to XImages, and you don't have direct pixel access to XPixmaps (it's the difference between being on the X Server and the client). So, the lowest common denominator, using only system libraries, is actually to allow *only* pixel access to Image, and move other drawing over to the Window. (Specifically, a Painter struct that ties to the window, so it can manage graphics contexts... yeah, it's starting to get complicated again.) What this means is if we want to draw to images, we've got to spin our own algorithms. Which makes the different OS algorithms moot - the direct screen drawing will be different, but the images will all be the same. The downside is their functions will lag a bit since I can't just wrap some C calls.
Apr 08 2011
parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2011-04-08 21:45:20 -0400, Adam D. Ruppe <destructionator gmail.com> said:

 Michel Fortin wrote:
 One issue is that different operating system will draw things with
 slightly different algorithms, which will result in slightly different
 images, which might introduce glitches from platform to platform.
I actually hit an even bigger problem... Xlib can't actually draw to XImages, and you don't have direct pixel access to XPixmaps (it's the difference between being on the X Server and the client). So, the lowest common denominator, using only system libraries, is actually to allow *only* pixel access to Image, and move other drawing over to the Window. (Specifically, a Painter struct that ties to the window, so it can manage graphics contexts... yeah, it's starting to get complicated again.) What this means is if we want to draw to images, we've got to spin our own algorithms. Which makes the different OS algorithms moot - the direct screen drawing will be different, but the images will all be the same. The downside is their functions will lag a bit since I can't just wrap some C calls.
Personally, I wouldn't even bother with direct screen drawing in that case. Direct screen drawing will need a different implementation for each OS, which means a lot of duplicated effort that could be put in implementing dependency-less cross-platform drawing primitives instead. As for text, which library does the X server uses to draw text? Freetype? You could link directly to it when you need to draw text... and on other OS use similar OS services. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Apr 08 2011
next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
Michel Fortin wrote:
 Direct screen drawing will need a different implementation for
 each OS, which means a lot of duplicated effort that could be put in
 implementing dependency-less cross-platform drawing primitives
 instead.
I'd agree if not for one thing: it isn't really much duplicated effort - most the functions are just a few lines long; it wraps C. There's a good chance I'll be able to finish them in the next hour for Win32 and X11.
 As for text, which library does the X server uses to draw text?
I think it's freetype for ttf and for bitmap fonts it's built into it. Linking directly to it is a good idea.
Apr 08 2011
prev sibling parent reply Matthias Pleh <jens konrad.net> writes:
Am 09.04.2011 03:55, schrieb Michel Fortin:
 On 2011-04-08 21:45:20 -0400, Adam D. Ruppe <destructionator gmail.com>
 said:

 Michel Fortin wrote:
 One issue is that different operating system will draw things with
 slightly different algorithms, which will result in slightly different
 images, which might introduce glitches from platform to platform.
I actually hit an even bigger problem... Xlib can't actually draw to XImages, and you don't have direct pixel access to XPixmaps (it's the difference between being on the X Server and the client). So, the lowest common denominator, using only system libraries, is actually to allow *only* pixel access to Image, and move other drawing over to the Window. (Specifically, a Painter struct that ties to the window, so it can manage graphics contexts... yeah, it's starting to get complicated again.) What this means is if we want to draw to images, we've got to spin our own algorithms. Which makes the different OS algorithms moot - the direct screen drawing will be different, but the images will all be the same. The downside is their functions will lag a bit since I can't just wrap some C calls.
Personally, I wouldn't even bother with direct screen drawing in that case. Direct screen drawing will need a different implementation for each OS, which means a lot of duplicated effort that could be put in implementing dependency-less cross-platform drawing primitives instead. As for text, which library does the X server uses to draw text? Freetype? You could link directly to it when you need to draw text... and on other OS use similar OS services.
For the drawingt part. I'm currently working on a rednerer with scanline algorithm. This will be completly OS-independent. It's in a single file with 2kLOC, and rather low level drawing. I just render on a simple ubyte-array, but it already support polygon-rendering, antialiasing and different color-structs. This is how it looks like for now: http://img683.imageshack.us/i/testawa.jpg/ this takes currently 62ms to render, don't know if this is fast enough, but can definitley improved. °Matthias
Apr 08 2011
parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2011-04-08 22:31:11 -0400, Matthias Pleh <jens konrad.net> said:

 For the drawingt part. I'm currently working on a rednerer with 
 scanline algorithm. This will be completly OS-independent. It's in a 
 single file with 2kLOC, and rather low level drawing. I just render on 
 a simple ubyte-array, but it already support polygon-rendering, 
 antialiasing and different color-structs.
Oh! really nice.
 This is how it looks like for now:
 http://img683.imageshack.us/i/testawa.jpg/
 this takes currently 62ms to render, don't know if this is fast enough,
 but can definitley improved.
The important thing is to have an API. Once it works we can concern ourselves with speed. What's the API like? -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Apr 09 2011
parent reply Matthias Pleh <jens konrad.net> writes:
Am 09.04.2011 13:11, schrieb Michel Fortin:
 On 2011-04-08 22:31:11 -0400, Matthias Pleh <jens konrad.net> said:

 For the drawingt part. I'm currently working on a rednerer with
 scanline algorithm. This will be completly OS-independent. It's in a
 single file with 2kLOC, and rather low level drawing. I just render on
 a simple ubyte-array, but it already support polygon-rendering,
 antialiasing and different color-structs.
Oh! really nice.
 This is how it looks like for now:
 http://img683.imageshack.us/i/testawa.jpg/
 this takes currently 62ms to render, don't know if this is fast enough,
 but can definitley improved.
The important thing is to have an API. Once it works we can concern ourselves with speed. What's the API like?
Currntly, it's rather low level API. It looks like this: void draw() { buf = new ubyte[width * height * 3]; // create render buffer, just a ubyte-arrray (no color info) PixelBuffer pixBuff = new PixelBuffer(buf, width, height, width*3); auto ren= new Renderer!(Rgb24)(pixBuff); // -> Rgb24 // manages the correct Color Rasterizer ras = new Rasterizer; // create the path // per primitive min. 3 vertexes needed ras.movTo(20,40); // -> moves the point without drawing ras.lineTo(30,80); // -> moves the point with drawing [...snip...] // finally render it to the PixelBuffer ras.render(ren, Color(255,0,0)); } on this we could add more abstraction to directly render lines, rectangles and circles ... (the posted image is completly renderd whit the API above) I hope, I will find time this weekend, clean it up and post it here. Maybe Adam then could add it to his source. °Matthias
Apr 09 2011
parent Adam D. Ruppe <destructionator gmail.com> writes:
Matthias Pleh:
 I hope, I will find time this weekend, clean it up and post it here.
 Maybe Adam then could add it to his source.
Cool!
Apr 09 2011
prev sibling next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
 foreach (col; zip(reds, greens, blues))
     image[x, y] = col;
With Color is becomes something like: foreach (col; zip(reds, greens, blues)) image[x, y] = Color(col.tupleof); Bye, bearophile
Apr 08 2011
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
bearophile wrote:
 With Color is becomes something like:
 foreach (col; zip(reds, greens, blues))
    image[x, y] = Color(col.tupleof);
That looks perfectly acceptable to me. I might add an overload so opIndex can take a tuple too though, so the zip example is a little easier, but I really prefer the Color struct.
 I see. But those lambdas are a bit too much large put there. I
 suggest true named function moved elsewhere.
 - Inside the (dchar c) {} a switch seems better.
Yeah, that's what happens when an example grows bigger then intended without refactoring :P
 - In Wrapped struct why are you using a checkLimits() instead of
 an invariant()?
It's not a check (poorly chosen name I guess!) - it actually changes the value (wrapping around) when it hits the limit, so user input never leads to crazy values. Besides, invariants are generally to check the program for bugs, rather than external input from the user like used here.
Apr 08 2011
parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 4/9/11, spir <denis.spir gmail.com> wrote:
 I prefere structs to tuples /everywhere/. They have 2 big advantages:
 * explicite: color.red versus color[0]
But Tuples _are_ structs. And you _can_ use explicit names: http://codepad.org/0ZWAtcL1
Apr 09 2011
parent "Nick Sabalausky" <a a.a> writes:
"Andrej Mitrovic" <andrej.mitrovich gmail.com> wrote in message 
news:mailman.3303.1302360951.4748.digitalmars-d puremagic.com...
 On 4/9/11, spir <denis.spir gmail.com> wrote:
 I prefere structs to tuples /everywhere/. They have 2 big advantages:
 * explicite: color.red versus color[0]
But Tuples _are_ structs. And you _can_ use explicit names: http://codepad.org/0ZWAtcL1
struct gives you more control over internal mechanics, which is important for something as low-level as a representation of a pixel.
Apr 09 2011
prev sibling next sibling parent reply Daniel Gibson <metalcaedes gmail.com> writes:
It looks like SDL (1.3) will be under zlib license soon[1] so maybe
using it or parts of it or whatever may be feasible, even in Phobos -
the zlib license should be "free" enough, it says
"If you use this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required."
so there's no binary attribution clause.

Cheers,
- Daniel

[1]
http://slouken.blogspot.com/2011/04/exploring-galaxy.html?showComment=1302234229839#c4323023909103671526
Apr 08 2011
parent Adam D. Ruppe <destructionator gmail.com> writes:
Daniel Gibson wrote:
 It looks like SDL (1.3) will be under zlib license soon
Now, that's pretty cool!
Apr 08 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On 04/09/2011 06:50 AM, Cliff Hudson wrote:
 So is the objective to create a windowing library, or a drawing library for
 (for example) games?  The two are rather different - though you can build a
 windowing library on top of a drawing library, doing so is pointless given
 the plethora of GUI libraries already out there, several with D bindings.
   If the bindings are hard to use, I'd address that directly rather than
 creating a whole new one.

 If you are building a drawing library, I'd definitely co-opt an existing one
 (SDL would be a good place, in particular since its license seems favorable
 and the API is well known.)  In fact, a good game-oriented library for D I
 think would be a fabulous idea.  D has a lot to offer game developers, a
 great mix of the high level and the low.  I don't know if it is popular with
 this crowd, but Microsoft DirectX or the XNA Framework might be a good place
 to go for pattern ideas as well.

 But generally I'd strive to not create new APIs, just new implementations
 (as necessary.)
I guess you are simply missing the point. You should re-read start-of-thread messages. Denis -- _________________ vita es estrany spir.wikidot.com
Apr 09 2011
prev sibling next sibling parent Cliff Hudson <cliff.s.hudson gmail.com> writes:
Yeah, I'm certainly not suggesting you necessarily rip off implementation,
just possibly API design.  But to be fair it has been a while since I used
that API - maybe the design is crap by comparison to others these days.
 OpenGL or DirectX for quick rendering is definitely the way to go under the
covers.

On Sat, Apr 9, 2011 at 8:05 AM, Adam D. Ruppe <destructionator gmail.com>wrote:

 On Fri, Apr 08, 2011 at 09:50:11PM -0700, Cliff Hudson wrote:
 So is the objective to create a windowing library, or a drawing library
for
 (for example) games?
Drawing. I have a windowing library in the works too, but it's much much more effort (even building off existing ones!) so it won't be ready to share for a long time still.
 If you are building a drawing library, I'd definitely co-opt an existing
one
 (SDL would be a good place, in particular since its license seems
favorable
 and the API is well known.)
I actually find SDL's drawing facilities to be almost useless... in my D1 game lib, even doing NES type games, I found it was simply too slow and redid the graphics with OpenGL. It's image loaders and sound/music parts are good though.
 I don't know if it is popular with
 this crowd, but Microsoft DirectX or the XNA Framework might be a good
place
 to go for pattern ideas as well.
I've heard good things about XNA, but I've never used it...
Apr 09 2011
prev sibling next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Adam D. Ruppe:

 Here's the D version using the direct to screen functions.
More little tasks for your module: http://rosettacode.org/wiki/Fractal_tree#Python http://rosettacode.org/wiki/Brownian_tree The JavaScript processing port site has some more examples in the Demos section: http://processingjs.org/exhibition Bye, bearophile
Apr 09 2011
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
bearophile wrote:
 More little tasks for your module:
 http://rosettacode.org/wiki/Fractal_tree#Python
This one's use of recursion caused me to hit what I think is a compiler bug. Not in the recursion itself, but in a struct's copy constructor when it had a significant mixin. I worked around it by declaring a private struct and using a pointer to it rather than mixing in the implementation directly. I believe this will be a net-positive too, since ScreenPainter is now referenced counted. Here's the implementation: ==== import simpledisplay; import std.math; void main() { // auto image = new Image(600, 600); auto window = new SimpleWindow(600, 600, "Fractal Tree"); void drawTree(ScreenPainter p, in int x1, in int y1, in real angle, in int depth) { if(depth == 0) return; immutable x2 = x1 + cast(int) (cos(angle) * depth * 10); immutable y2 = y1 + cast(int) (sin(angle) * depth * 10); p.drawLine(Point(x1, y1), Point(x2, y2)); drawTree(p, x2, y2, angle - 0.35, depth - 1); drawTree(p, x2, y2, angle + 0.35, depth - 1); } drawTree(window.draw, 300, 550, -PI / 2, 9); window.eventLoop(0, (dchar) { window.close(); }); // displayImage(image); } === The reason Image is there, but commented out, is that such things might be better done as images, then displayed once finished. But, since we don't have drawing lines to images yet*, I went direct to screen instead. (well, I do have my implementation of Bresenham's algorithm, but I want to see Mathias' code before falling back on mine. Mine worked well for DOS, but better anti-aliasing is expected nowadays.) DrawTree takes an existing ScreenPainter so I can limit it's scope to only where it's used. The new reference counting under the hood means that while the struct is copied several times here, it isn't wasteful. The eventLoop inline delegate allows you to close the window by pressing any key as well as using the button in the corner. I don't think the Python version on rosetta code would allow this. Comparing to the Python version, mine is a little shorter, primarily due to the much simpler initialization. The Python one took three lines to do what SimpleWindow's constructor does in one. I also put the "get_surface" kind of thing that allows drawing inline to the drawTree line. Like I said above, this was for reasons of scope, but it coincidentally shaves a line too. As does the struct destructor doing the job of display.flip(). The last place where I save a couple lines is the event loop, doing all that in one place instead of a separate function, loop, and fetcher. (Note: the delegate in there is not strictly necessary! It handles quit events sanely by default.) All in all, I'm very happy with this approach so far. It's simple, it's short, it's readable, it's reasonably efficient, and the implementation is moderately lean. Everything I was hoping for!
Apr 09 2011
next sibling parent Matthias Pleh <jens konrad.net> writes:
Am 10.04.2011 04:30, schrieb Adam D. Ruppe:
 bearophile wrote:
 More little tasks for your module:
 http://rosettacode.org/wiki/Fractal_tree#Python
This one's use of recursion caused me to hit what I think is a compiler bug. Not in the recursion itself, but in a struct's copy constructor when it had a significant mixin. I worked around it by declaring a private struct and using a pointer to it rather than mixing in the implementation directly. I believe this will be a net-positive too, since ScreenPainter is now referenced counted. Here's the implementation: ==== import simpledisplay; import std.math; void main() { // auto image = new Image(600, 600); auto window = new SimpleWindow(600, 600, "Fractal Tree"); void drawTree(ScreenPainter p, in int x1, in int y1, in real angle, in int depth) { if(depth == 0) return; immutable x2 = x1 + cast(int) (cos(angle) * depth * 10); immutable y2 = y1 + cast(int) (sin(angle) * depth * 10); p.drawLine(Point(x1, y1), Point(x2, y2)); drawTree(p, x2, y2, angle - 0.35, depth - 1); drawTree(p, x2, y2, angle + 0.35, depth - 1); } drawTree(window.draw, 300, 550, -PI / 2, 9); window.eventLoop(0, (dchar) { window.close(); }); // displayImage(image); } === The reason Image is there, but commented out, is that such things might be better done as images, then displayed once finished. But, since we don't have drawing lines to images yet*, I went direct to screen instead. (well, I do have my implementation of Bresenham's algorithm, but I want to see Mathias' code before falling back on mine. Mine worked well for DOS, but better anti-aliasing is expected nowadays.) DrawTree takes an existing ScreenPainter so I can limit it's scope to only where it's used. The new reference counting under the hood means that while the struct is copied several times here, it isn't wasteful. The eventLoop inline delegate allows you to close the window by pressing any key as well as using the button in the corner. I don't think the Python version on rosetta code would allow this. Comparing to the Python version, mine is a little shorter, primarily due to the much simpler initialization. The Python one took three lines to do what SimpleWindow's constructor does in one. I also put the "get_surface" kind of thing that allows drawing inline to the drawTree line. Like I said above, this was for reasons of scope, but it coincidentally shaves a line too. As does the struct destructor doing the job of display.flip(). The last place where I save a couple lines is the event loop, doing all that in one place instead of a separate function, loop, and fetcher. (Note: the delegate in there is not strictly necessary! It handles quit events sanely by default.) All in all, I'm very happy with this approach so far. It's simple, it's short, it's readable, it's reasonably efficient, and the implementation is moderately lean. Everything I was hoping for!
Ok, this is what I have so far. It's code, I have written one year ago and is based on AntiGrain , which is based on freetype2, which is based on libart? AntiGrain is under the modified BSD-license. To prevent license-issues(if it should go into phobos) and to get a faster version, I'v started form scratch, but this is not finished yet. But you can get an idea, how it should work.
 (well, I do have my implementation of Bresenham's algorithm, but ..
The rasterizer is optimized for polygon-rendering. To just render simple lines, I think Bresenham's algorithm (also anti-aliased) will maybe faster (fewer overhead), but for thicker lines with different caps, you need polygons anyway, so ... In the test.d file is an example, which produce the image (.ppm) I have posted. (note, you need the Color struct form simpledisplay.d) have fun, °Matthias
Apr 09 2011
prev sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Adam D. Ruppe:

 I believe so, yes, but I haven't tried it and wouldn't mind if
 it didn't. If you need to use multiple windows at the same time,
 it'd probably be better to use DFL, DWT, GTK, Qt, etc. etc.
It's better to support multiple windows, otherwise you have to split the single window "manually" if you want a window with a simulation and a window with a graph about the simulation.
 Heh, I used to call it box in my DOS programs. But, the functions
 it forwards to are called Rectangle() and XDrawRectangle(), so
 I want to be consistent with them so it's not a surprise to
 someone already familiar with with the other APIs.
I don't agree. line(), box(), circle(), etc are so easy to remember and common that I don't see the need to keep the names of the functions under them.
 The reason I went with drawShape instead of just Shape is that
 functions are verbs, so generally, I like their names to be
 verbs too. There's exceptions, of course, but I don't these
 fit.
I don't agree. It's _very_ easy to understand that p.line() is to add a line, there is no chance of confusion here, the verb of p.drawLine() is implied.
 But, here, the idea was to keep it simple, so I went with just
 color. I guess that might be too simple.
In this module shaded pens are less important than usage simplicity. I suggest to keep things simple here.
 A note: since I posted last, I changed my mind on something, and
 bearophile, I rather doubt you'll like it...
I think it's acceptable :-) ----------------------------
 This one's use of recursion caused me to hit what I think is a
 compiler bug. Not in the recursion itself, but in a struct's
 copy constructor when it had a significant mixin.
Where is the updated display module? This doesn't seem to be updated yet: http://arsdnet.net/dcode/simpledisplay.d In your little program drawTree() is better "static" (or better, moved out of the main). window.eventLoop(0, (dchar){ window.close(); }); ==> Default arguments? window.eventLoop();
 Comparing to the Python version, mine is a little shorter,
PyGame is also quite more powerful than your simpledisplay module, you can write small video games with it. So its API is a little more complex.
 All in all, I'm very happy with this approach so far. It's simple,
 it's short, it's readable, it's reasonably efficient, and the
 implementation is moderately lean. Everything I was hoping for!
Before freezing the API design I suggest to implement many more quite different examples. Designing APIs is something that can't be done in a hurry :-) Two features are quite important: Mouse position, mouse clicks, keys pressed: http://processingjs.org/learning/topic/pattern Text: http://processingjs.org/learning/topic/tickle --------------- Few more useful features for later: Transparency: http://processingjs.org/learning/topic/follow2 Antialiasing: http://processing.org/learning/topics/penrosetile.html Polygons, curves: http://processing.org/learning/topics/softbody.html Image loading: http://processingjs.org/learning/topic/blur Save screen: http://processing.org/learning/topics/saveoneimage.html Sprites: http://processing.org/learning/topics/unlimitedsprites.html Bye, bearophile
Apr 10 2011
parent Cliff Hudson <cliff.s.hudson gmail.com> writes:
 Heh, I used to call it box in my DOS programs. But, the functions
 it forwards to are called Rectangle() and XDrawRectangle(), so
 I want to be consistent with them so it's not a surprise to
 someone already familiar with with the other APIs.
I don't agree. line(), box(), circle(), etc are so easy to remember and common that I don't see the need to keep the names of the functions under them.
 The reason I went with drawShape instead of just Shape is that
 functions are verbs, so generally, I like their names to be
 verbs too. There's exceptions, of course, but I don't these
 fit.
I don't agree. It's _very_ easy to understand that p.line() is to add a line, there is no chance of confusion here, the verb of p.drawLine() is implied.
I would argue that p.line is inconsistent with an immediate-mode drawing API design (it just strikes me as weird all around actually.) If this were retained mode, something like p.Add(Line(...)) would make sense. But if the action is to draw a line, and the target of that action is object p, then p.drawLine is the most sensible. The objective here is not to relieve the user of typing, but to ensure the code is unambiguously clear. Imagine p.box. What does that mean? Draw a box? Or are we boxing p into some portable format? I agree with Adam's original thought that methods should be verbs. At least to my mind is reads easier. YMMV. - Cliff
Apr 10 2011
prev sibling next sibling parent reply KennyTM~ <kennytm gmail.com> writes:
On Apr 9, 11 04:26, Adam D. Ruppe wrote:
 We discussed this first in the GUI library thread, but since it
 meandered so much, I decided to split off into a new subject. Much
 of what I say here will be old to anyone who saw the previous thread.
 There's some new stuff nearer to the bottom though.

 I, with input from others, have started writing a little module
 for simple uses of a display. You can write to a bitmap, display it
 to a window, and handle events all in an easy way. The basics are
 cross platform, but you can use native function calls too.

 http://arsdnet.net/dcode/simpledisplay.d

 It's still very much in progress, but I think it's now at the point
 where the direction I'm taking it is clear.
[snip] Thanks for the great work! Taking the version on that link, I have ported it to use the native Cocoa/Core Graphics in OS X, instead of X11. You can check out the diff in https://github.com/kennytm/simpledisplay.d/commit/a790. Only Snow Leopard (10.6) is supported. I have only tested that it works on the pendulum example and the HSL picker, so things like drawText and drawPixel may not work properly yet. The implementation part is quite messy right now due to Objective-C. Since dmd does not have "pragma(framework)", you'll need to supply the "-L-framework -LAppKit" options to dmd to link it. And a few things: 1. *Please use spaces instead of tabs.* 2. Color's constructor's arguments should better be "red" "green" "blue" "alpha" rather than "a" "b" "c" "d". 3. The unit of "pulseTimeout" should be documented (milliseconds). 4. In the function "fromHsl", there is a (h is real.nan). However, 'is' on primitives is reduced to '==' and (nan == nan) is false, so (h is real.nan) will always be false. You should use std.math.isNaN(). 5. Why use the ANSI version (LoadIconA, etc.), not the Unicode version (LoadIconW, etc.) of API on Windows? I think the latter is preferred.
Apr 10 2011
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
KennyTM~ wrote:
 Taking the version on that link, I have ported it to use the native
 Cocoa/Core Graphics in OS X, instead of X11
Thanks!
 1. *Please use spaces instead of tabs.*
Spaces are the spawn of Satan! I hate them, but when it comes time to submit to phobos, I'll run a find/replace of them so it's consistent with the prevailing style there. Until then though, I'll write it in my native style... so these early drafts will remain tabs, but spaces will be used in the final copy.
 2. Color's constructor's arguments should better be "red" "green"
 "blue" "alpha" rather than "a" "b" "c" "d".
 3. The unit of "pulseTimeout" should be documented (milliseconds).
Indeed.
  4. In the function "fromHsl", there is a (h is real.nan).
 However, 'is' on primitives is reduced to '==' and (nan == nan)
 is false, so (his real.nan) will always be false. You should use
 std.math.isNaN().
Ah, so that's what it is. I was sure it was some form of "is nan" but it's not something I use often so I assumed it was like null. Changed.
 5. Why use the ANSI version (LoadIconA, etc.), not the Unicode
 version (LoadIconW, etc.) of API on Windows? I think the latter
 is preferred.
Yeah. core.sys.windows.windows is woefully incomplete though, and only defined the A versions. Since I was already sick of copy/pasting headers after Xlib, I took the path of least resistance and aliased to what it had. (Annoyingly though, I still had to copy/paste a bunch of GDI prototypes! Not a big deal - structs and enums are way more painful than functions, but still, aaargh.) I'll fix it up next time I have some time to kill. They're all aliased in one place so it will be easy to find.
Apr 10 2011
next sibling parent KennyTM~ <kennytm gmail.com> writes:
On Apr 11, 11 09:54, Adam D. Ruppe wrote:
 KennyTM~ wrote:
 Taking the version on that link, I have ported it to use the native
 Cocoa/Core Graphics in OS X, instead of X11
Thanks!
 1. *Please use spaces instead of tabs.*
Spaces are the spawn of Satan! I hate them, but when it comes time to submit to phobos, I'll run a find/replace of them so it's consistent with the prevailing style there. Until then though, I'll write it in my native style... so these early drafts will remain tabs, but spaces will be used in the final copy.
OK.
 2. Color's constructor's arguments should better be "red" "green"
 "blue" "alpha" rather than "a" "b" "c" "d".
 3. The unit of "pulseTimeout" should be documented (milliseconds).
Indeed.
   4. In the function "fromHsl", there is a (h is real.nan).
 However, 'is' on primitives is reduced to '==' and (nan == nan)
 is false, so (his real.nan) will always be false. You should use
 std.math.isNaN().
Ah, so that's what it is. I was sure it was some form of "is nan" but it's not something I use often so I assumed it was like null. Changed.
 5. Why use the ANSI version (LoadIconA, etc.), not the Unicode
 version (LoadIconW, etc.) of API on Windows? I think the latter
 is preferred.
Yeah. core.sys.windows.windows is woefully incomplete though, and only defined the A versions. Since I was already sick of copy/pasting headers after Xlib, I took the path of least resistance and aliased to what it had. (Annoyingly though, I still had to copy/paste a bunch of GDI prototypes! Not a big deal - structs and enums are way more painful than functions, but still, aaargh.) I'll fix it up next time I have some time to kill. They're all aliased in one place so it will be easy to find.
I see.
Apr 11 2011
prev sibling parent spir <denis.spir gmail.com> writes:
On 04/11/2011 03:54 AM, Adam D. Ruppe wrote:
 1. *Please use spaces instead of tabs.*
Spaces are the spawn of Satan! I hate them, but when it comes time to submit to phobos, I'll run a find/replace of them so it's consistent with the prevailing style there. Until then though, I'll write it in my native style... so these early drafts will remain tabs, but spaces will be used in the final copy.
Using spaces is confusing model & view, and forcing your preferred indent width over all readers. Tab means "align columns". Using tabs is respectful attitude ;-) I still use spaces only because most email clients do not allow setting tab width :-( Denis -- _________________ vita es estrany spir.wikidot.com
Apr 11 2011
prev sibling next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"KennyTM~" <kennytm gmail.com> wrote in message 
news:int88l$uaf$1 digitalmars.com...
 On Apr 9, 11 04:26, Adam D. Ruppe wrote:
 We discussed this first in the GUI library thread, but since it
 meandered so much, I decided to split off into a new subject. Much
 of what I say here will be old to anyone who saw the previous thread.
 There's some new stuff nearer to the bottom though.

 I, with input from others, have started writing a little module
 for simple uses of a display. You can write to a bitmap, display it
 to a window, and handle events all in an easy way. The basics are
 cross platform, but you can use native function calls too.

 http://arsdnet.net/dcode/simpledisplay.d

 It's still very much in progress, but I think it's now at the point
 where the direction I'm taking it is clear.
[snip] Thanks for the great work! Taking the version on that link, I have ported it to use the native Cocoa/Core Graphics in OS X, instead of X11. You can check out the diff in https://github.com/kennytm/simpledisplay.d/commit/a790. Only Snow Leopard (10.6) is supported. I have only tested that it works on the pendulum example and the HSL picker, so things like drawText and drawPixel may not work properly yet. The implementation part is quite messy right now due to Objective-C. Since dmd does not have "pragma(framework)", you'll need to supply the "-L-framework -LAppKit" options to dmd to link it. And a few things: 1. *Please use spaces instead of tabs.*
What, so that he can force his indentation size on everyone else that works on the code? Or so that using the left/right arrow keys within the indentation zone requires an unnessesaraly large number of keypresses? And frankly, I this strategy renders all the pro-space and pro-tab arguments obsolete, and it's still based on tabs anyway: http://nickgravgaard.com/elastictabstops/ Spaces for indentation are just the worst of all worlds. And it's a total abuse of what space is even for in the first place.
Apr 10 2011
next sibling parent Daniel Gibson <metalcaedes gmail.com> writes:
Am 11.04.2011 07:00, schrieb Nick Sabalausky:
 "KennyTM~" <kennytm gmail.com> wrote in message 
 news:int88l$uaf$1 digitalmars.com...
 On Apr 9, 11 04:26, Adam D. Ruppe wrote:
 We discussed this first in the GUI library thread, but since it
 meandered so much, I decided to split off into a new subject. Much
 of what I say here will be old to anyone who saw the previous thread.
 There's some new stuff nearer to the bottom though.

 I, with input from others, have started writing a little module
 for simple uses of a display. You can write to a bitmap, display it
 to a window, and handle events all in an easy way. The basics are
 cross platform, but you can use native function calls too.

 http://arsdnet.net/dcode/simpledisplay.d

 It's still very much in progress, but I think it's now at the point
 where the direction I'm taking it is clear.
[snip] Thanks for the great work! Taking the version on that link, I have ported it to use the native Cocoa/Core Graphics in OS X, instead of X11. You can check out the diff in https://github.com/kennytm/simpledisplay.d/commit/a790. Only Snow Leopard (10.6) is supported. I have only tested that it works on the pendulum example and the HSL picker, so things like drawText and drawPixel may not work properly yet. The implementation part is quite messy right now due to Objective-C. Since dmd does not have "pragma(framework)", you'll need to supply the "-L-framework -LAppKit" options to dmd to link it. And a few things: 1. *Please use spaces instead of tabs.*
What, so that he can force his indentation size on everyone else that works on the code? Or so that using the left/right arrow keys within the indentation zone requires an unnessesaraly large number of keypresses?
Yeah. Indent with tabs, align with spaces. I find reading code with two or eight spaces for indentation hard to read. However both styles are widely used.. if everybody just indented with tabs and configured his editor to display 2/4/8/42 spaces for a tab everybody could be happy.
 And frankly, I this strategy renders all the pro-space and pro-tab arguments 
 obsolete, and it's still based on tabs anyway:
 
 http://nickgravgaard.com/elastictabstops/
 
Hmm looks neat, but I'm not sure I really need that.
 Spaces for indentation are just the worst of all worlds. And it's a total 
 abuse of what space is even for in the first place.
 
The only thing that is more horrible than indentation with spaces is mixing indentation with spaces and tabs so it's completely broken when your editor uses another tab-width than the authors editor. Cheers, - Danie
Apr 10 2011
prev sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Nick Sabalausky:

 What, so that he can force his indentation size on everyone else that works 
 on the code? Or so that using the left/right arrow keys within the 
 indentation zone requires an unnessesaraly large number of keypresses?
It's a module theoretically meant for Phobos, and the Phobos coding standard are spaces. Bye, bearophile
Apr 10 2011
next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
 Nick Sabalausky:
 What, so that he can force his indentation size on everyone else that
 works on the code? Or so that using the left/right arrow keys within the
 indentation zone requires an unnessesaraly large number of keypresses?
It's a module theoretically meant for Phobos, and the Phobos coding standard are spaces.
Yes. Phobos follows the convention of indenting with spaces and that levels of indentation are 4 spaces. So, anything which goes into Phobos needs to follow this convention. the only way that tabs work is if you use them consistently, which in my experience almost never happens. And pretty much everywhere that I've worked has required that spaces be used and no tabs. When people _have_ used tabs, it's been a mess. Personally, I'm completely against using tabs in source code. Regardless, Phobos doesn't use tabs. So, whatever someone may prefer in their own code, code that they intend to get into Phobos shouldn't use tabs. - Jonathan M Davis
Apr 10 2011
next sibling parent reply Daniel Gibson <metalcaedes gmail.com> writes:
Am 11.04.2011 07:51, schrieb Jonathan M Davis:
 Nick Sabalausky:
 What, so that he can force his indentation size on everyone else that
 works on the code? Or so that using the left/right arrow keys within the
 indentation zone requires an unnessesaraly large number of keypresses?
It's a module theoretically meant for Phobos, and the Phobos coding standard are spaces.
Yes. Phobos follows the convention of indenting with spaces and that levels of indentation are 4 spaces. So, anything which goes into Phobos needs to follow this convention. the only way that tabs work is if you use them consistently, which in my experience almost never happens.
How can people mess that up?
 And pretty much everywhere that I've worked 
 has required that spaces be used and no tabs. When people _have_ used tabs, 
 it's been a mess. Personally, I'm completely against using tabs in source 
 code.
 
 Regardless, Phobos doesn't use tabs. So, whatever someone may prefer in their 
 own code, code that they intend to get into Phobos shouldn't use tabs.
 
 - Jonathan M Davis
Of course there's always the possibility to use a code-beautifier to fix this when you're done writing, like http://uncrustify.sourceforge.net/ which even officially supports D. Cheers, - Daniel
Apr 10 2011
next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
 Am 11.04.2011 07:51, schrieb Jonathan M Davis:
 Nick Sabalausky:
 What, so that he can force his indentation size on everyone else that
 works on the code? Or so that using the left/right arrow keys within
 the indentation zone requires an unnessesaraly large number of
 keypresses?
It's a module theoretically meant for Phobos, and the Phobos coding standard are spaces.
Yes. Phobos follows the convention of indenting with spaces and that levels of indentation are 4 spaces. So, anything which goes into Phobos needs to follow this convention. the only way that tabs work is if you use them consistently, which in my experience almost never happens.
How can people mess that up?
They mix tabs and spaces. On some lines, they use spaces and on others they use tabs. If the tab size isn't set exactly the same on your machine as however it was set up on the other person's machine, then the indentation is totally screwed up. And if multiple people have edited the file, it gets that much worse. On top of that, even if the rule is to use tabs for indentation and spaces elsewhere and people are consistent with tabs for indentation, they'll often use tabs elswhere where they should have used spaces. The only way that using tabs works is if you're completely consistent with them. You use tabs where you're supposed to use tabs and spaces where you're supposed to use spaces, and everyone does the same thing. Odds are, that's not going to happen - _especially_ if the tabs don't show up differently in your editor and you can't see when you've screwed up and used tabs when you're not supposed to or not used them where you are supposed to. Personally, I think that it's _horrible_ to use tabs, and I know plenty of programmers who agree, but as with many stylistic things in programming, there are plenty who would disagree. - Jonathan M Davis
Apr 10 2011
parent reply Kagamin <spam here.lot> writes:
Jonathan M Davis Wrote:

 Personally, I think that it's _horrible_ to use tabs
Why would one fear tabs?
Apr 11 2011
next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
 Jonathan M Davis Wrote:
 Personally, I think that it's _horrible_ to use tabs
Why would one fear tabs?
They change depending on your editor settings. Indenting gets screwed up if tabs and spaces are mixed. It's just plain annoying to have an indentation of multiple spaces which isn't actually multiple spaces. The biggest problem though is that it just totally screws with indentation if tabs and spaces are mixed and that invariably happens. Tabs serve no useful purpose IMHO. - Jonathan M Davis
Apr 11 2011
next sibling parent reply Daniel Gibson <metalcaedes gmail.com> writes:
Am 11.04.2011 10:01, schrieb Jonathan M Davis:
 Jonathan M Davis Wrote:
 Personally, I think that it's _horrible_ to use tabs
Why would one fear tabs?
They change depending on your editor settings. Indenting gets screwed up if tabs and spaces are mixed. It's just plain annoying to have an indentation of multiple spaces which isn't actually multiple spaces. The biggest problem though is that it just totally screws with indentation if tabs and spaces are mixed and that invariably happens. Tabs serve no useful purpose IMHO. - Jonathan M Davis
So tabs are horrible because some people use spaces instead of tabs.
Apr 11 2011
next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
 Am 11.04.2011 10:01, schrieb Jonathan M Davis:
 Jonathan M Davis Wrote:
 Personally, I think that it's _horrible_ to use tabs
Why would one fear tabs?
They change depending on your editor settings. Indenting gets screwed up if tabs and spaces are mixed. It's just plain annoying to have an indentation of multiple spaces which isn't actually multiple spaces. The biggest problem though is that it just totally screws with indentation if tabs and spaces are mixed and that invariably happens. Tabs serve no useful purpose IMHO. - Jonathan M Davis
So tabs are horrible because some people use spaces instead of tabs.
I hate the very concept of tabs to begin with. The fact that they're variable in size is _not_ something that I find to be desirable. Regardless of that however, if you try and use tabs for indentation they invariably get mixed with spaces, totally ruining whatever usefulness the tabs might have had. Code will _always_ contain spaces. You can't reasonably write code with only tabs. However, you _can_ easily and reasonably write code without tabs. Most code editors can be set up such that all tabs are converted to spaces. So, if you use only spaces, you can easily avoid the problem of tabs and spaces being mixed. On the other hand, you _can't_ do the same by using only tabs. So, if you do use tabs, you will end up with mixed tabs and spaces unless everyone involved is very careful, which isn't going to happen. So, I suppose that you could say that tabs are horrible because some people use spaces, but I don't see any value in them to begin with anyway. However, the fact that you invariably end up with mixed tabs and spaces when you try and use tabs makes tabs completely useless. Every place that I've ever worked at has gone for spaces only, and I've only ever heard of one place where it was required that tabs be used for indentation. I'm sure that there are others, but it's rare that I've heard of anyone thinking that using tabs in code was a good idea. - Jonathan M Davis
Apr 11 2011
next sibling parent reply Kagamin <spam here.lot> writes:
Jonathan M Davis Wrote:

 So, if 
 you do use tabs, you will end up with mixed tabs and spaces unless everyone 
 involved is very careful, which isn't going to happen.
If no one is careful, you end up with mixed tabs and spaces, no matter what policies you're trying to enforce.
Apr 11 2011
parent Daniel Gibson <metalcaedes gmail.com> writes:
Am 11.04.2011 17:25, schrieb Kagamin:
 Jonathan M Davis Wrote:
 
 So, if 
 you do use tabs, you will end up with mixed tabs and spaces unless everyone 
 involved is very careful, which isn't going to happen.
If no one is careful, you end up with mixed tabs and spaces, no matter what policies you're trying to enforce.
This is a good point.
Apr 11 2011
prev sibling parent reply Kagamin <spam here.lot> writes:
Jonathan M Davis Wrote:

 Every place that I've ever worked 
 at has gone for spaces only, and I've only ever heard of one place where it 
 was required that tabs be used for indentation. I'm sure that there are 
 others, but it's rare that I've heard of anyone thinking that using tabs in 
 code was a good idea.
People often follow wrong traditions blindly.
Apr 11 2011
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 4/11/11 10:30 AM, Kagamin wrote:
 Jonathan M Davis Wrote:

 Every place that I've ever worked
 at has gone for spaces only, and I've only ever heard of one place where it
 was required that tabs be used for indentation. I'm sure that there are
 others, but it's rare that I've heard of anyone thinking that using tabs in
 code was a good idea.
People often follow wrong traditions blindly.
That is actually very true about tab. It's a straight carryover from typing machines that has no justification today. Andrei
Apr 11 2011
parent Kagamin <spam here.lot> writes:
Andrei Alexandrescu Wrote:

 That is actually very true about tab. It's a straight carryover from 
 typing machines that has no justification today.
If it's useful, it doesn't matter, where it came from.
Apr 11 2011
prev sibling parent "Nick Sabalausky" <a a.a> writes:
"Kagamin" <spam here.lot> wrote in message 
news:inv6q0$1hmi$1 digitalmars.com...
 Jonathan M Davis Wrote:

 Every place that I've ever worked
 at has gone for spaces only, and I've only ever heard of one place where 
 it
 was required that tabs be used for indentation. I'm sure that there are
 others, but it's rare that I've heard of anyone thinking that using tabs 
 in
 code was a good idea.
People often follow wrong traditions blindly.
Especially in corporations.
Apr 11 2011
prev sibling parent reply Ruben <chromium hybridsource.org> writes:
 One of the reasons to switch to FreeBSD was to spend less time
 tinkering with the OS and "just use it".

 I?m not familiar enough with FreeBSD, but the message from the subject
 is what one gets when attempting to install DMD-2 on x86_64, so I
 believe that 32bit executable on 64bit OS is not the right combo on
 FreeBSD.
Let me address this, since I wrote the ldc, dmd, and dmd2 Makefiles in FreeBSD ports, after getting permission from Walter. I simply marked the port as i386 since I read that there wasn't a 64-bit binary: I never tried building dmd as 64-bit. 32-bit binaries will run on FreeBSD amd64, but they might require a bit more work. I read that some people simply compile i386 packages in a 32-bit system or jail and then install them in the 64-bit system. So I'd guess that you should be able to use dmd2 on FreeBSD amd64, but it might take a bit more work.
Apr 11 2011
parent Gour-Gadadhara Dasa <gour atmarama.net> writes:
On Mon, 11 Apr 2011 03:26:26 -0700
Ruben <chromium hybridsource.org> wrote:

 Let me address this, since I wrote the ldc, dmd, and dmd2 Makefiles
 in FreeBSD ports, after getting permission from Walter. =20
Thank you for your work.
 I simply marked the port as i386 since I read that there wasn't a
 64-bit binary:
That's fair.
 32-bit binaries will run on FreeBSD amd64, but they might require a
 bit more work.  I read that some people simply compile i386 packages
 in a 32-bit system or jail and then install them in the 64-bit
 system.  So I'd guess that you should be able to use dmd2 on FreeBSD
 amd64, but it might take a bit more work.
I understand that "it might work"...today I've installed wine on my x86_64, but I simply expect to run 64bit compiler on 64bit OS and therefore hope that gdc2/ldc2 will fill the hole. Sincerely, Gour --=20 =E2=80=9CIn the material world, conceptions of good and bad are all mental speculations=E2=80=A6=E2=80=9D (Sri Caitanya Mahaprabhu) http://atmarama.net | Hlapicina (Croatia) | GPG: 52B5C810
Apr 11 2011
prev sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Jonathan M Davis" <jmdavisProg gmx.com> wrote in message 
news:mailman.3371.1302508910.4748.digitalmars-d puremagic.com...
 Jonathan M Davis Wrote:
 Personally, I think that it's _horrible_ to use tabs
Why would one fear tabs?
They change depending on your editor settings. Indenting gets screwed up if tabs and spaces are mixed. It's just plain annoying to have an indentation of multiple spaces which isn't actually multiple spaces. The biggest problem though is that it just totally screws with indentation if tabs and spaces are mixed and that invariably happens.
You're drawing a completely invalid conclusion from that, because it works the same both ways. If I have a bunch of code indented with spaces, all it takes is a few things to be indented with tabs instead to create the *exact same screwup*. You've chosen tabs as the villian completely arbitrarily. Also I find your argument that the mixup is significantly more likely when tabs are used for indentation to be extremely questionable. You admit yourself that you've rarely come across situations where tabs are the default. So how would you know? Based on that *one* piece of anecdotal evidence? And even that can be suspect, because if you were involved, we know you're accustomed to using spaces for indentation, so that could very well have been the reason for the mixup. I have worked with code that used spaces as indentation on various occasions, and I always did wind up accidentally sticking some tabs in there. So I know first hand that the idea of the mixups not happening with space-indentation is a load of crap. They're equally likely. And as far as needing to use spaces in code anyway: That's not remotely a problem. People know damn well the difference between a space and indentation. Fuck, if MS Word users can figure it out, so can programmers.
 Tabs serve no useful purpose IMHO.
Well, IMO, using spaces for indentation serves no useful purpose. At least tabs actually *mean* alignment and indentation. Spaces don't and never have. Plus, what's the use of being able place the cursor at arbtrary points within the "4 spaces" (or 8 spaces, or whatever)? All it does is make me have to press left/right-arrow-key a whole hell of a lot more (which I really do find to be a PITA). And makes it easier to accidentally end up with a messed up indentation of +/- 1 space somewhere. Spaces for indentation is just a misuse and a kludge to force on each other the idiologies of how large indentation should be.
Apr 11 2011
parent reply Jacob Carlborg <doob me.com> writes:
On 2011-04-11 22:09, Nick Sabalausky wrote:
 "Jonathan M Davis"<jmdavisProg gmx.com>  wrote in message
 news:mailman.3371.1302508910.4748.digitalmars-d puremagic.com...
 Jonathan M Davis Wrote:
 Personally, I think that it's _horrible_ to use tabs
Why would one fear tabs?
They change depending on your editor settings. Indenting gets screwed up if tabs and spaces are mixed. It's just plain annoying to have an indentation of multiple spaces which isn't actually multiple spaces. The biggest problem though is that it just totally screws with indentation if tabs and spaces are mixed and that invariably happens.
You're drawing a completely invalid conclusion from that, because it works the same both ways. If I have a bunch of code indented with spaces, all it takes is a few things to be indented with tabs instead to create the *exact same screwup*. You've chosen tabs as the villian completely arbitrarily. Also I find your argument that the mixup is significantly more likely when tabs are used for indentation to be extremely questionable. You admit yourself that you've rarely come across situations where tabs are the default. So how would you know? Based on that *one* piece of anecdotal evidence? And even that can be suspect, because if you were involved, we know you're accustomed to using spaces for indentation, so that could very well have been the reason for the mixup. I have worked with code that used spaces as indentation on various occasions, and I always did wind up accidentally sticking some tabs in there. So I know first hand that the idea of the mixups not happening with space-indentation is a load of crap. They're equally likely. And as far as needing to use spaces in code anyway: That's not remotely a problem. People know damn well the difference between a space and indentation. Fuck, if MS Word users can figure it out, so can programmers.
 Tabs serve no useful purpose IMHO.
Well, IMO, using spaces for indentation serves no useful purpose. At least tabs actually *mean* alignment and indentation. Spaces don't and never have. Plus, what's the use of being able place the cursor at arbtrary points within the "4 spaces" (or 8 spaces, or whatever)? All it does is make me have to press left/right-arrow-key a whole hell of a lot more (which I really do find to be a PITA). And makes it easier to accidentally end up with a messed up indentation of +/- 1 space somewhere. Spaces for indentation is just a misuse and a kludge to force on each other the idiologies of how large indentation should be.
So true. -- /Jacob Carlborg
Apr 12 2011
parent spir <denis.spir gmail.com> writes:
On 04/12/2011 09:24 AM, Jacob Carlborg wrote:
 Well, IMO, using spaces for indentation serves no useful purpose. At least
 tabs actually *mean* alignment and indentation. Spaces don't and never have.
 Plus, what's the use of being able place the cursor at arbtrary points
 within the "4 spaces" (or 8 spaces, or whatever)? All it does is make me
 have to press left/right-arrow-key a whole hell of a lot more (which I
 really do find to be a PITA). And makes it easier to accidentally end up
 with a messed up indentation of +/- 1 space somewhere. Spaces for
 indentation is just a misuse and a kludge to force on each other the
 idiologies of how large indentation should be.
So true.
Especially "Spaces for indentation is just a misuse". Space are not meant for alignment, have never been, and should never have been used for that. Tabs are intended for that role, & they play it well. Denis -- _________________ vita es estrany spir.wikidot.com
Apr 12 2011
prev sibling parent spir <denis.spir gmail.com> writes:
On 04/11/2011 10:01 AM, Jonathan M Davis wrote:
 Jonathan M Davis Wrote:
  >  Personally, I think that it's _horrible_ to use tabs
Why would one fear tabs?
They change depending on your editor settings.
That's precisely what they are meant for... unlike space-indentation, tab-indentation respects you :-) Using spaces for indent is using *content* to describe *display*. It's messing up model with view, just like using <b> instead of <strong>. Denis -- _________________ vita es estrany spir.wikidot.com
Apr 11 2011
prev sibling next sibling parent Kagamin <spam here.lot> writes:
Daniel Gibson Wrote:

 the only way that tabs work is if you use them consistently, which in my 
 experience almost never happens. 
How can people mess that up?
They're CHAOTIC EVIL programmers! They can mess anything.
 Of course there's always the possibility to use a code-beautifier to fix
 this when you're done writing, like http://uncrustify.sourceforge.net/
 which even officially supports D.
If they can't get tabs right, how can they use beautifiers? They just write and commit.
Apr 11 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On 04/11/2011 08:13 AM, Jonathan M Davis wrote:
 They mix tabs and spaces. On some lines, they use spaces and on others they
 use tabs.
Never seen this, not even once. Messing can only happen when one copy-pastes from modules using spaces. Denis -- _________________ vita es estrany spir.wikidot.com
Apr 11 2011
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 4/10/2011 10:58 PM, Daniel Gibson wrote:
 Am 11.04.2011 07:51, schrieb Jonathan M Davis:
 Yes. Phobos follows the convention of indenting with spaces and that levels of
 indentation are 4 spaces. So, anything which goes into Phobos needs to follow
 this convention.

 the only way that tabs work is if you use them consistently, which in my
 experience almost never happens.
How can people mess that up?
In the beginning, God created tabs. Tab stops were 8 spaces. That was engraved in tty and printer hardware, and there was nothing any user could do about it. And it was good, and there was peace in the land. But then in the 80's satan thought that it would be a good idea to make tabs user settable (soft tabs) in his text editor. Various demons and trolls thought this was a fab idea, and propagated it to every text editor. Unfortunately, text files have no way to specify the tab size expected by the text. Conventions were proffered, noobs were sacrificed, and hymns sung, but nobody could ever agree on what the tab size should be. Bikeshed wars raged and devastated the land. Hence, the use of tabs was utterly, totally and perpetually ruined for everyone. And satan laughed at the folly of programmers.
Jun 03 2011
next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
8 space tabs are the One True Way. All other tabstops are evil.
Jun 03 2011
prev sibling parent Jeff Nowakowski <jeff dilacero.org> writes:
On 06/03/2011 02:48 PM, Walter Bright wrote:
 In the beginning, God created tabs. Tab stops were 8 spaces
It's 2011. The idea that some character means 8 spaces and should be used to layout code is ass-backwards, regardless if everybody actually followed that rule. It was a fine rule for 1960.
Jun 04 2011
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
Jonathan M Davis:

 Yes. Phobos follows the convention of indenting with spaces and that levels of 
 indentation are 4 spaces. So, anything which goes into Phobos needs to follow 
 this convention.
 ...
 Regardless, Phobos doesn't use tabs. So, whatever someone may prefer in their 
 own code, code that they intend to get into Phobos shouldn't use tabs.
If you allow me, I have a stylistic suggestion for your posts, that I usually appreciate: in a single post don't repeat two times most of the things you want to say, once is enough :-) Bye, bearophile
Apr 11 2011
prev sibling next sibling parent reply spir <denis.spir gmail.com> writes:
On 04/11/2011 07:51 AM, Jonathan M Davis wrote:
 the only way that tabs work is if you use them consistently, which in my
 experience almost never happens. And
How so? If you probably set your editor, inconsistency simply cannot happen... The same is true for using spaces, anyway. Denis -- _________________ vita es estrany spir.wikidot.com
Apr 11 2011
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 11 Apr 2011 06:17:58 -0400, spir <denis.spir gmail.com> wrote:

 On 04/11/2011 07:51 AM, Jonathan M Davis wrote:
 the only way that tabs work is if you use them consistently, which in my
 experience almost never happens. And
How so? If you probably set your editor, inconsistency simply cannot happen... The same is true for using spaces, anyway.
Don't want to get too much into this obviously polarized debate, but in my experience, people vary as much as editors. And editors vary quite a bit. In most of the editors I use, the default is to use spaces for indentation. So what happens is someone opens a file that uses tabs for indentation, then adds some lines. However, their editor only uses spaces *for those lines they added*, which results in a hybrid. However, the person editing doesn't notice because it all lines up on their screen. You may have philosophical objections to all of this, but this answers your question straightforwardly -- it happens, all the time, and this is how. The easiest rule to follow is -- always use spaces to indent. Almost all editors support this (and are set to this by default). Almost all editors provide some sort of auto-indentation, or some command to indent a highlighted section of code. The "oh crap, now I have to go back through and convert tabs to spaces" argument just isn't valid anymore. -Steve
Apr 11 2011
parent Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
On 11/04/2011 20:54, Steven Schveighoffer wrote:
 In most of the editors I use, the default is to use spaces for
 indentation.  So what happens is someone opens a file that uses tabs for
 indentation, then adds some lines.  However, their editor only uses
 spaces *for those lines they added*, which results in a hybrid.
 However, the person editing doesn't notice because it all lines up on
 their screen.
Just FYI, in Eclipse, the auto-indentation that happen when you press Enter will use the indentation from the previous line (whether it's spaces, tabs, or even mixed). However, other editing operations that generate lines of code (like code templates, auto-generated code, refactorings like extracting a method, etc.) are not so smart and will indent with according to the default indentation you specify in the settings, they won't look at how the file is already indented. -- Bruno Medeiros - Software Engineer
Apr 13 2011
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
bearophile:
 It's a module theoretically meant for Phobos, and the Phobos coding
 standard are spaces.
Yeah, that's all that matters in the end. "When in Rome..." But it's trivial to do a find and replace all before submitting so really, it's just not a big deal.
Apr 11 2011
next sibling parent spir <denis.spir gmail.com> writes:
On 04/11/2011 05:31 PM, Adam D. Ruppe wrote:
 bearophile:
 It's a module theoretically meant for Phobos, and the Phobos coding
 standard are spaces.
Yeah, that's all that matters in the end. "When in Rome..." But it's trivial to do a find and replace all before submitting so really, it's just not a big deal.
Smart editors actually differentiate between indentation and spacing elsewhere (meaning they won't mess up with spacing inline / in comments / docs / strings). Denis -- _________________ vita es estrany spir.wikidot.com
Apr 11 2011
prev sibling next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Smart editors also allow you to unindent with a single backspace
regardless if you're using tabs or spaces.
Apr 11 2011
parent reply "Nick Sabalausky" <a a.a> writes:
"Andrej Mitrovic" <andrej.mitrovich gmail.com> wrote in message 
news:mailman.3396.1302548836.4748.digitalmars-d puremagic.com...
 Smart editors also allow you to unindent with a single backspace
 regardless if you're using tabs or spaces.
In other words, *some* editors handle space-indentation intelligently (and do so by reinventing *tabs*), while *all* editors handle tab-indentation intelligently.
Apr 11 2011
next sibling parent reply =?UTF-8?B?IkrDqXLDtG1lIE0uIEJlcmdlciI=?= <jeberger free.fr> writes:
Nick Sabalausky wrote:
 "Andrej Mitrovic" <andrej.mitrovich gmail.com> wrote in message=20
 news:mailman.3396.1302548836.4748.digitalmars-d puremagic.com...
 Smart editors also allow you to unindent with a single backspace
 regardless if you're using tabs or spaces.
=20 In other words, *some* editors handle space-indentation intelligently (=
and=20
 do so by reinventing *tabs*), while *all* editors handle tab-indentatio=
n=20
 intelligently.
=20
I have seen editors that would convert a tab to spaces and only delete one space when hitting backspace ;) Jerome --=20 mailto:jeberger free.fr http://jeberger.free.fr Jabber: jeberger jabber.fr
Apr 11 2011
next sibling parent reply David Gileadi <gileadis NSPMgmail.com> writes:
On 4/11/11 1:51 PM, "Jérôme M. Berger" wrote:
 Nick Sabalausky wrote:
 "Andrej Mitrovic"<andrej.mitrovich gmail.com>  wrote in message
 news:mailman.3396.1302548836.4748.digitalmars-d puremagic.com...
 Smart editors also allow you to unindent with a single backspace
 regardless if you're using tabs or spaces.
In other words, *some* editors handle space-indentation intelligently (and do so by reinventing *tabs*), while *all* editors handle tab-indentation intelligently.
I have seen editors that would convert a tab to spaces and only delete one space when hitting backspace ;) Jerome
Eclipse, I'm looking at you!
Apr 11 2011
next sibling parent reply Daniel Gibson <metalcaedes gmail.com> writes:
Am 11.04.2011 23:03, schrieb David Gileadi:
 On 4/11/11 1:51 PM, "Jérôme M. Berger" wrote:
 Nick Sabalausky wrote:
 "Andrej Mitrovic"<andrej.mitrovich gmail.com>  wrote in message
 news:mailman.3396.1302548836.4748.digitalmars-d puremagic.com...
 Smart editors also allow you to unindent with a single backspace
 regardless if you're using tabs or spaces.
In other words, *some* editors handle space-indentation intelligently (and do so by reinventing *tabs*), while *all* editors handle tab-indentation intelligently.
I have seen editors that would convert a tab to spaces and only delete one space when hitting backspace ;) Jerome
Eclipse, I'm looking at you!
By default Eclipse doesn't convert tab to spaces, though.
Apr 11 2011
parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
DigitalMarsTV Headlines:
"Newlines: Why is Microsoft still ignoring the public's demand to
eliminate the carriage return?"
"Breaking News: Police investigators are on the lookout for the
monster lunatic who originally designed the number system layout for
PC-keyboards. As a reminder for the viewers just tuning in, the
suspect is charged with felonies in regards to the following Laws: 1.
By Law, numbers shall always start from digit zero. 2. By Law,
Function Keys shall be vertically aligned against number keys, so as
to have the same order as the number keys. The authorities are asking
for anyone with information on the suspect to come forward and send an
e-mail to protect_our_GNUFreedom gnu.org"
Apr 11 2011
prev sibling next sibling parent Kagamin <spam here.lot> writes:
David Gileadi Wrote:

 	I have seen editors that would convert a tab to spaces and only
 delete one space when hitting backspace ;)

 		Jerome
Eclipse, I'm looking at you!
Also Visual Studio and I don't see the "delete unindents" option.
Apr 12 2011
prev sibling parent Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
On 11/04/2011 22:03, David Gileadi wrote:
 On 4/11/11 1:51 PM, "Jérôme M. Berger" wrote:
 Nick Sabalausky wrote:
 "Andrej Mitrovic"<andrej.mitrovich gmail.com> wrote in message
 news:mailman.3396.1302548836.4748.digitalmars-d puremagic.com...
 Smart editors also allow you to unindent with a single backspace
 regardless if you're using tabs or spaces.
In other words, *some* editors handle space-indentation intelligently (and do so by reinventing *tabs*), while *all* editors handle tab-indentation intelligently.
I have seen editors that would convert a tab to spaces and only delete one space when hitting backspace ;) Jerome
Eclipse, I'm looking at you!
In Eclipse you can press Shift-Tab to reduce the indentation by one level, regardless of whether it's using spaces or tabs. This also works if you have multiple lines of code selected in the editor. (so if you have 4 spaces of indentation and you press Shift-Tab anywhere on the line it will delete those 4 spaces, assuming you configured a level of indentation to be 4 spaces (that's usually the default though)) -- Bruno Medeiros - Software Engineer
Apr 13 2011
prev sibling parent =?UTF-8?B?IkrDqXLDtG1lIE0uIEJlcmdlciI=?= <jeberger free.fr> writes:
J=C3=A9r=C3=B4me M. Berger wrote:
 Nick Sabalausky wrote:
 "Andrej Mitrovic" <andrej.mitrovich gmail.com> wrote in message=20
 news:mailman.3396.1302548836.4748.digitalmars-d puremagic.com...
 Smart editors also allow you to unindent with a single backspace
 regardless if you're using tabs or spaces.
In other words, *some* editors handle space-indentation intelligently =
(and=20
 do so by reinventing *tabs*), while *all* editors handle tab-indentati=
on=20
 intelligently.
I have seen editors that would convert a tab to spaces and only delete one space when hitting backspace ;) =20
Reading myself, I realise that I was not perfectly clear: the editor would accept the tab and insert a tab character, it is only when hitting backspace after a tab that the editor would convert the tab to N-1 space (assuming tabs are equivalent to N spaces). Jerome --=20 mailto:jeberger free.fr http://jeberger.free.fr Jabber: jeberger jabber.fr
Apr 12 2011
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 4/11/2011 1:31 PM, Nick Sabalausky wrote:
 In other words, *some* editors handle space-indentation intelligently (and
 do so by reinventing *tabs*), while *all* editors handle tab-indentation
 intelligently.
There is no way to handle tabs intelligently. Take a source file that has tab characters in it. There is no algorithm in the world that will discern what the tab size is supposed to be. Heck, I've seen plenty of source files that assume a tab size of X in some sections and Y in others, and Z in still others. The only way to win is to not use tabs.
Jun 03 2011
parent reply Daniel Gibson <metalcaedes gmail.com> writes:
Am 03.06.2011 20:54, schrieb Walter Bright:
 On 4/11/2011 1:31 PM, Nick Sabalausky wrote:
 In other words, *some* editors handle space-indentation intelligently
 (and
 do so by reinventing *tabs*), while *all* editors handle tab-indentation
 intelligently.
There is no way to handle tabs intelligently. Take a source file that has tab characters in it. There is no algorithm in the world that will discern what the tab size is supposed to be. Heck, I've seen plenty of source files that assume a tab size of X in some sections and Y in others, and Z in still others. The only way to win is to not use tabs.
If you use tabs for indentation and spaces for alignment the tabsize doesn't matter.
Jun 03 2011
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
Daniel Gibson wrote:
 Am 03.06.2011 20:54, schrieb Walter Bright:
 On 4/11/2011 1:31 PM, Nick Sabalausky wrote:
 In other words, *some* editors handle space-indentation intelligently
 (and
 do so by reinventing *tabs*), while *all* editors handle tab-indentation
 intelligently.
There is no way to handle tabs intelligently. Take a source file that has tab characters in it. There is no algorithm in the world that will discern what the tab size is supposed to be. Heck, I've seen plenty of source files that assume a tab size of X in some sections and Y in others, and Z in still others. The only way to win is to not use tabs.
If you use tabs for indentation and spaces for alignment the tabsize doesn't matter.
http://www.emacswiki.org/emacs/SmartTabs In a perfect world, everyone would do that. But if multiple people are working on the same source, one of them will mess up the formatting...
Jun 03 2011
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
On 03/06/2011 20:15, Timon Gehr wrote:
 Daniel Gibson wrote:
<snip>
 If you use tabs for indentation and spaces for alignment the tabsize
 doesn't matter.
http://www.emacswiki.org/emacs/SmartTabs
Taken the words out of my mouth there. I've been faced with files that are a mishmash of tabs and spaces, and been tidying them up to this style. The problem is that some editors will, when you indent a block of code, change the alignment spaces back into tabs. Though I do find that feature useful as a first step in cleaning up sources that are in a total mess in terms of tab/space indentation. At work we use Visual Studio, but when I find that a source file needs tidying I would open it in Notepad++ as it behaves in this way. I also tend to use its Trim Trailing Space feature quite often.... Stewart.
Jun 03 2011
parent Walter Bright <newshound2 digitalmars.com> writes:
On 6/3/2011 5:14 PM, Stewart Gordon wrote:
 On 03/06/2011 20:15, Timon Gehr wrote:
 Daniel Gibson wrote:
<snip>
 If you use tabs for indentation and spaces for alignment the tabsize
 doesn't matter.
http://www.emacswiki.org/emacs/SmartTabs
Taken the words out of my mouth there. I've been faced with files that are a mishmash of tabs and spaces, and been tidying them up to this style.
Good luck making that work.
Jun 03 2011
prev sibling parent Adam Richardson <simpleshot gmail.com> writes:
On Fri, Jun 3, 2011 at 3:04 PM, Daniel Gibson <metalcaedes gmail.com> wrote:

 Am 03.06.2011 20:54, schrieb Walter Bright:
 On 4/11/2011 1:31 PM, Nick Sabalausky wrote:
 In other words, *some* editors handle space-indentation intelligently
 (and
 do so by reinventing *tabs*), while *all* editors handle tab-indentation
 intelligently.
There is no way to handle tabs intelligently. Take a source file that has tab characters in it. There is no algorithm in the world that will discern what the tab size is supposed to be. Heck, I've seen plenty of source files that assume a tab size of X in some sections and Y in others, and Z in still others. The only way to win is to not use tabs.
If you use tabs for indentation and spaces for alignment the tabsize doesn't matter.
This is my preferred approach, too. Adam
Jun 03 2011
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 4/11/2011 8:31 AM, Adam D. Ruppe wrote:
 Yeah, that's all that matters in the end. "When in Rome..."

 But it's trivial to do a find and replace all before submitting so
 really, it's just not a big deal.
Before I check in, I run tolf and detab on the source files.
Jun 03 2011
prev sibling next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2011-04-10 23:39, KennyTM~ wrote:
 On Apr 9, 11 04:26, Adam D. Ruppe wrote:
 We discussed this first in the GUI library thread, but since it
 meandered so much, I decided to split off into a new subject. Much
 of what I say here will be old to anyone who saw the previous thread.
 There's some new stuff nearer to the bottom though.

 I, with input from others, have started writing a little module
 for simple uses of a display. You can write to a bitmap, display it
 to a window, and handle events all in an easy way. The basics are
 cross platform, but you can use native function calls too.

 http://arsdnet.net/dcode/simpledisplay.d

 It's still very much in progress, but I think it's now at the point
 where the direction I'm taking it is clear.
[snip] Thanks for the great work! Taking the version on that link, I have ported it to use the native Cocoa/Core Graphics in OS X, instead of X11. You can check out the diff in https://github.com/kennytm/simpledisplay.d/commit/a790.
When using objc_msgSend and friends you need to cast the function to the right signature, to the same signature as the method you're calling via objc_msgSend, before calling it. See http://www.dsource.org/projects/dstep/browser/dstep/objc/message.d#L74 If you start passing floats to objc_msgSend you'll soon notice that you get some weird behaviors if you don't cast it to the right signature. You also need to use different versions of objc_msgSend depending on what the return type is and on that platform you're on. If you're returning a struct or an floating point number of some kind you need to use a different version of objc_msgSend. You can have a look at: http://www.dsource.org/projects/dstep/browser/dstep/objc/bridge/Bridge.d#L779 . Also look the function being called: http://www.dsource.org/projects/dstep/browser/dstep/objc/message.d
 Only Snow Leopard (10.6) is supported.

 I have only tested that it works on the pendulum example and the HSL
 picker, so things like drawText and drawPixel may not work properly yet.
 The implementation part is quite messy right now due to Objective-C.

 Since dmd does not have "pragma(framework)", you'll need to supply the
 "-L-framework -LAppKit" options to dmd to link it.

 And a few things:

 1. *Please use spaces instead of tabs.*
 2. Color's constructor's arguments should better be "red" "green" "blue"
 "alpha" rather than "a" "b" "c" "d".
 3. The unit of "pulseTimeout" should be documented (milliseconds).
 4. In the function "fromHsl", there is a (h is real.nan). However, 'is'
 on primitives is reduced to '==' and (nan == nan) is false, so (h is
 real.nan) will always be false. You should use std.math.isNaN().
 5. Why use the ANSI version (LoadIconA, etc.), not the Unicode version
 (LoadIconW, etc.) of API on Windows? I think the latter is preferred.
-- /Jacob Carlborg
Apr 11 2011
parent reply KennyTM~ <kennytm gmail.com> writes:
On Apr 11, 11 15:43, Jacob Carlborg wrote:
 When using objc_msgSend and friends you need to cast the function to the
 right signature, to the same signature as the method you're calling via
 objc_msgSend, before calling it. See
 http://www.dsource.org/projects/dstep/browser/dstep/objc/message.d#L74

 If you start passing floats to objc_msgSend you'll soon notice that you
 get some weird behaviors if you don't cast it to the right signature.

 You also need to use different versions of objc_msgSend depending on
 what the return type is and on that platform you're on. If you're
 returning a struct or an floating point number of some kind you need to
 use a different version of objc_msgSend. You can have a look at:
 http://www.dsource.org/projects/dstep/browser/dstep/objc/bridge/Bridge.d#L779
 . Also look the function being called:
 http://www.dsource.org/projects/dstep/browser/dstep/objc/message.d
Yes I know. Since all objc_msgSend used only operate on integers and pointers and structs and doubles, and they only return pointers or void, I didn't bother to cast them. Anyway, those calls are now updated to handled it properly, please check https://github.com/kennytm/simpledisplay.d/commit/18b6.
Apr 11 2011
parent Jacob Carlborg <doob me.com> writes:
On 2011-04-11 11:41, KennyTM~ wrote:
 On Apr 11, 11 15:43, Jacob Carlborg wrote:
 When using objc_msgSend and friends you need to cast the function to the
 right signature, to the same signature as the method you're calling via
 objc_msgSend, before calling it. See
 http://www.dsource.org/projects/dstep/browser/dstep/objc/message.d#L74

 If you start passing floats to objc_msgSend you'll soon notice that you
 get some weird behaviors if you don't cast it to the right signature.

 You also need to use different versions of objc_msgSend depending on
 what the return type is and on that platform you're on. If you're
 returning a struct or an floating point number of some kind you need to
 use a different version of objc_msgSend. You can have a look at:
 http://www.dsource.org/projects/dstep/browser/dstep/objc/bridge/Bridge.d#L779

 . Also look the function being called:
 http://www.dsource.org/projects/dstep/browser/dstep/objc/message.d
Yes I know. Since all objc_msgSend used only operate on integers and pointers and structs and doubles, and they only return pointers or void, I didn't bother to cast them.
Fair point. But since we are talking about GUI libraries, images and drawing 2D graphics it's most likely floating point numbers will be used eventually, at least somewhere.
 Anyway, those calls are now updated to handled it properly, please check
 https://github.com/kennytm/simpledisplay.d/commit/18b6.
Ok. -- /Jacob Carlborg
Apr 11 2011
prev sibling parent Michel Fortin <michel.fortin michelf.com> writes:
On 2011-04-10 17:39:03 -0400, KennyTM~ <kennytm gmail.com> said:

 On Apr 9, 11 04:26, Adam D. Ruppe wrote:
 We discussed this first in the GUI library thread, but since it
 meandered so much, I decided to split off into a new subject. Much
 of what I say here will be old to anyone who saw the previous thread.
 There's some new stuff nearer to the bottom though.
 
 I, with input from others, have started writing a little module
 for simple uses of a display. You can write to a bitmap, display it
 to a window, and handle events all in an easy way. The basics are
 cross platform, but you can use native function calls too.
 
 http://arsdnet.net/dcode/simpledisplay.d
 
 It's still very much in progress, but I think it's now at the point
 where the direction I'm taking it is clear.
 
[snip] Thanks for the great work! Taking the version on that link, I have ported it to use the native Cocoa/Core Graphics in OS X, instead of X11. You can check out the diff in https://github.com/kennytm/simpledisplay.d/commit/a790.
Nice, you're the second one to do that. :-) (I made a Cocoa port of the earlier version when all there was to do was image.display(), but I didn't release the code.) The major difference between our approaches is that I made it by putting Objective-C code in a separate Objective-C file instead of doing that objc_msgSend boilerplate directly in D.
 Only Snow Leopard (10.6) is supported.
 
 I have only tested that it works on the pendulum example and the HSL 
 picker, so things like drawText and drawPixel may not work properly 
 yet. The implementation part is quite messy right now due to 
 Objective-C.
Ideally we'd be using the extern(Objective-C) syntax I'm working on, but I still have polishing to do on that thing before it's ready to be integrated in mainline DMD (and then it'll probably take some time before Walter reviews and applies the pull request) so it's not an option right now. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Apr 11 2011
prev sibling next sibling parent reply teo <teo.ubuntu yahoo.com> writes:
On Fri, 08 Apr 2011 20:26:07 +0000, Adam D. Ruppe wrote:

 We discussed this first in the GUI library thread, but since it
 meandered so much, I decided to split off into a new subject. Much of
 what I say here will be old to anyone who saw the previous thread.
 There's some new stuff nearer to the bottom though.
 
 I, with input from others, have started writing a little module for
 simple uses of a display. You can write to a bitmap, display it to a
 window, and handle events all in an easy way. The basics are cross
 platform, but you can use native function calls too.
 
 http://arsdnet.net/dcode/simpledisplay.d
 
I admit I didn't read the whole thread... I just wanted to point out the following: - XCB (http://xcb.freedesktop.org/) - aims to replace Xlib - Wayland (http://wayland.freedesktop.org/) - aims to replace the X server A quick look at the source code shows that you are targeting the X server, which might not be the best idea. Please ignore my post, if the above is well known and has already been discussed.
Apr 11 2011
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
teo wrote:
 XCB (http://xcb.freedesktop.org/) - aims to replace Xlib
I've heard of it, but never used it before. Since I wanted to write this quickly I stuck to what I knew (xlib on linux and gdi on windows). Replacing it later, if necessary, won't be hard (the target specific code is only about 300 lines, all straightforward. We were considering changing to DirectX / OpenGL a bit later anyway, so the xlib might actually be secondary in any case). But I doubt xlib is going anywhere any time soon. It's older than I am!
Apr 11 2011
parent teo <teo.ubuntu yahoo.com> writes:
On Mon, 11 Apr 2011 23:08:12 +0000, Adam D. Ruppe wrote:

 teo wrote:
 XCB (http://xcb.freedesktop.org/) - aims to replace Xlib
I've heard of it, but never used it before. Since I wanted to write this quickly I stuck to what I knew (xlib on linux and gdi on windows). Replacing it later, if necessary, won't be hard (the target specific code is only about 300 lines, all straightforward. We were considering changing to DirectX / OpenGL a bit later anyway, so the xlib might actually be secondary in any case).
Yes, it won't be hard, but it is also not that straightforward, because XCB is a bit lower-level compared to Xlib.
 
 But I doubt xlib is going anywhere any time soon. It's older than I am!
Exactly that is the problem. It is old and clumsy (state-of-the-1980s) and I suspect that Wayland will eventually replace it. Xlib and the X server will remain there for legacy applications. Wayland is still alpha, however I would consider at least looking more closer at it. Currently it uses OpenGL ES (will use OpenGL later) and is oriented towards the future of Linux graphics. Two of the leading Linux distributions (Ubuntu and Fedora) stated that they will switch to Wayland in one of the coming releases.
Apr 12 2011
prev sibling parent reply "Nick Sabalausky" <a a.a> writes:
"teo" <teo.ubuntu yahoo.com> wrote in message 
news:io00gq$5rc$1 digitalmars.com...
 On Fri, 08 Apr 2011 20:26:07 +0000, Adam D. Ruppe wrote:

 We discussed this first in the GUI library thread, but since it
 meandered so much, I decided to split off into a new subject. Much of
 what I say here will be old to anyone who saw the previous thread.
 There's some new stuff nearer to the bottom though.

 I, with input from others, have started writing a little module for
 simple uses of a display. You can write to a bitmap, display it to a
 window, and handle events all in an easy way. The basics are cross
 platform, but you can use native function calls too.

 http://arsdnet.net/dcode/simpledisplay.d
I admit I didn't read the whole thread... I just wanted to point out the following: - XCB (http://xcb.freedesktop.org/) - aims to replace Xlib - Wayland (http://wayland.freedesktop.org/) - aims to replace the X server A quick look at the source code shows that you are targeting the X server, which might not be the best idea. Please ignore my post, if the above is well known and has already been discussed.
Even the Wayland site says that it's not going to replace X server anytime soon and that they're going to co-exist for the forseeable future. Don't know anything about XCB though.
Apr 11 2011
parent =?UTF-8?B?IkrDqXLDtG1lIE0uIEJlcmdlciI=?= <jeberger free.fr> writes:
Nick Sabalausky wrote:
 "teo" <teo.ubuntu yahoo.com> wrote in message=20
 news:io00gq$5rc$1 digitalmars.com...
 On Fri, 08 Apr 2011 20:26:07 +0000, Adam D. Ruppe wrote:

 We discussed this first in the GUI library thread, but since it
 meandered so much, I decided to split off into a new subject. Much of=
 what I say here will be old to anyone who saw the previous thread.
 There's some new stuff nearer to the bottom though.

 I, with input from others, have started writing a little module for
 simple uses of a display. You can write to a bitmap, display it to a
 window, and handle events all in an easy way. The basics are cross
 platform, but you can use native function calls too.

 http://arsdnet.net/dcode/simpledisplay.d
I admit I didn't read the whole thread... I just wanted to point out the following: - XCB (http://xcb.freedesktop.org/) - aims to replace Xlib - Wayland (http://wayland.freedesktop.org/) - aims to replace the X se=
rver
 A quick look at the source code shows that you are targeting the X
 server, which might not be the best idea.

 Please ignore my post, if the above is well known and has already been=
 discussed.
=20 Even the Wayland site says that it's not going to replace X server anyt=
ime=20
 soon and that they're going to co-exist for the forseeable future. Don'=
t=20
 know anything about XCB though.
=20
AFAIK, Xlib has already been rewritten on top of XCB, but most "big" GUI toolkits (Gtk, Qt, ...) are staying on Xlib (some of them did take a stab at XCB and dropped it as not worth the trouble). Jerome --=20 mailto:jeberger free.fr http://jeberger.free.fr Jabber: jeberger jabber.fr
Apr 12 2011
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
 On 04/11/2011 10:01 AM, Jonathan M Davis wrote:
 Jonathan M Davis Wrote:
  >  Personally, I think that it's _horrible_ to use tabs
Why would one fear tabs?
They change depending on your editor settings.
That's precisely what they are meant for... unlike space-indentation, tab-indentation respects you :-) Using spaces for indent is using *content* to describe *display*. It's messing up model with view, just like using <b> instead of <strong>.
I don't believe that the model-view issue really applies to code. For that to work, the model and view would have to be truly separate, and they aren't. Editors would have to understand the language and be able to format it based on what you wanted, then you could format code however you liked without affecting anyone else. But things just don't work that way. So, how you format your code matters. Using tabs screws with that unless you're completely consistent, and while a single developer may be consistent, groups of developers rarely are. - Jonathan M Davis
Apr 11 2011
parent Daniel Gibson <metalcaedes gmail.com> writes:
Am 12.04.2011 05:15, schrieb Jonathan M Davis:
 Using tabs screws with that unless you're completely 
 consistent, and while a single developer may be consistent, groups of 
 developers rarely are.
 
 - Jonathan M Davis
Yeah that is why using spaces screws with that: While a single developer may be consistent, groups of developers rarely are. So there may be a developer who uses tabs instead of spaces (maybe because he thinks his editor will convert the tabs to spaces but he forgot to check that option in the editors settings).. And of course then there's that guy who uses two spaces instead of four (or whatever the convention is), at least from a level of 3 indentations on, to save space on the screen. And this other guy who uses eight spaces in his performance critical code because he thinks that'll prevent unnecessary nesting.. So much for consistency. As someone else said before: This argument works for both directions. Cheers, - Daniel
Apr 11 2011
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
 On 04/11/2011 08:13 AM, Jonathan M Davis wrote:
 They mix tabs and spaces. On some lines, they use spaces and on others
 they use tabs.
Never seen this, not even once. Messing can only happen when one copy-pastes from modules using spaces.
As Steve pointed out, it frequently happens when you have multiple developers working on the same code. It may work with one developer who likes using tabs, but as soon as you get a mix of developers, you invariably get a mix of spaces and tabs unless _everyone_ involved is really careful, and that rarely happens. It's just too easy to use spaces without realizing that someone else used tabs or even that you yourself are using spaces, depending on your editor's settings. Using only spaces and no tabs avoids the entire issue and is one of the major reasons (if not _the_ major reason) why it is incredibly common for coding standards to require spaces and prohibit tabs. Obviously, you _can_ use tabs if you're careful - especially if you're the only programmer involved - but it's just simpler to disallow tabs when you're dealing with a group of developers. - Jonathan M Davis
Apr 11 2011
next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Jonathan M Davis" <jmdavisProg gmx.com> wrote in message 
news:mailman.3412.1302578409.4748.digitalmars-d puremagic.com...
 On 04/11/2011 08:13 AM, Jonathan M Davis wrote:
 They mix tabs and spaces. On some lines, they use spaces and on others
 they use tabs.
Never seen this, not even once. Messing can only happen when one copy-pastes from modules using spaces.
As Steve pointed out, it frequently happens when you have multiple developers working on the same code. It may work with one developer who likes using tabs, but as soon as you get a mix of developers, you invariably get a mix of spaces and tabs unless _everyone_ involved is really careful, and that rarely happens. It's just too easy to use spaces without realizing that someone else used tabs or even that you yourself are using spaces, depending on your editor's settings.
That applies the other way around, too.
 Using only spaces and no tabs avoids the entire issue...
It avoid the issue *as well as* using only tabs for indentation.
Apr 11 2011
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
 "Jonathan M Davis" <jmdavisProg gmx.com> wrote in message
 news:mailman.3412.1302578409.4748.digitalmars-d puremagic.com...
 
 On 04/11/2011 08:13 AM, Jonathan M Davis wrote:
 They mix tabs and spaces. On some lines, they use spaces and on others
 they use tabs.
Never seen this, not even once. Messing can only happen when one copy-pastes from modules using spaces.
As Steve pointed out, it frequently happens when you have multiple developers working on the same code. It may work with one developer who likes using tabs, but as soon as you get a mix of developers, you invariably get a mix of spaces and tabs unless _everyone_ involved is really careful, and that rarely happens. It's just too easy to use spaces without realizing that someone else used tabs or even that you yourself are using spaces, depending on your editor's settings.
That applies the other way around, too.
 Using only spaces and no tabs avoids the entire issue...
It avoid the issue *as well as* using only tabs for indentation.
No, because you _always_ have spaces. It's not like you stop using the spacebar just because your tab key is actually inserting tab characters. If you have tabs, then you're still going to have spaces. It's just a question of whether those involved in the project are disciplined enough to avoid ever using spaces for indenting. If, on the other hand, you only allow spaces, then you don't have the same concern about tabs being inserted. True, someone's editor could be set up poorly for either situation and insert spaces where they shouldn't or tabs where they shouldn't, but it's generally trivial to set up an editor to _never_ input tabs that it's easy to make it so that tabs are never used. However, the same can't be said of using tabs, because it's always possible to input spaces with the spacebar. It's true that people occasionally end up inserting tabs in space-only environments, but in my experience, it's fairly rare. It's pretty much a guarantee, however, that _someone_ will insert spaces in an environment where it's supposed to be tabs. There's not much point in arguing the matter. Some folks prefer tabs, and some prefer spaces, but I believe that it's most common for spaces to be preferred as far as style guides go, and they're generally less error-prone simply because it's easy enough to set up editors so that tabs are never used, and you can't do the same with spaces when you're using tabs for indentation. - Jonathan M Davis
Apr 11 2011
prev sibling next sibling parent reply Cliff Hudson <cliff.s.hudson gmail.com> writes:
Spaces *should* only be used within string constants (as needed), or when
the language otherwise requires them.  The editor should format the code
according to user preferences.

Absent that, spaces represent the lowest common denominator of formatting,
so we can all use them and our text shows up as we desire regardless of
editor or setting.

Can we move along now?  This argument was old 30 years ago.  Perhaps we
should do VI vs. EMACS while we are at it.

</snipe>

On Mon, Apr 11, 2011 at 10:13 PM, Jonathan M Davis <jmdavisProg gmx.com>wrote:

 "Jonathan M Davis" <jmdavisProg gmx.com> wrote in message
 news:mailman.3412.1302578409.4748.digitalmars-d puremagic.com...

 On 04/11/2011 08:13 AM, Jonathan M Davis wrote:
 They mix tabs and spaces. On some lines, they use spaces and on
others
 they use tabs.
Never seen this, not even once. Messing can only happen when one copy-pastes from modules using spaces.
As Steve pointed out, it frequently happens when you have multiple developers working on the same code. It may work with one developer who likes
using
 tabs,
 but as soon as you get a mix of developers, you invariably get a mix of
 spaces
 and tabs unless _everyone_ involved is really careful, and that rarely
 happens. It's just too easy to use spaces without realizing that
someone
 else
 used tabs or even that you yourself are using spaces, depending on your
 editor's settings.
That applies the other way around, too.
 Using only spaces and no tabs avoids the entire issue...
It avoid the issue *as well as* using only tabs for indentation.
No, because you _always_ have spaces. It's not like you stop using the spacebar just because your tab key is actually inserting tab characters. If you have tabs, then you're still going to have spaces. It's just a question of whether those involved in the project are disciplined enough to avoid ever using spaces for indenting. If, on the other hand, you only allow spaces, then you don't have the same concern about tabs being inserted. True, someone's editor could be set up poorly for either situation and insert spaces where they shouldn't or tabs where they shouldn't, but it's generally trivial to set up an editor to _never_ input tabs that it's easy to make it so that tabs are never used. However, the same can't be said of using tabs, because it's always possible to input spaces with the spacebar. It's true that people occasionally end up inserting tabs in space-only environments, but in my experience, it's fairly rare. It's pretty much a guarantee, however, that _someone_ will insert spaces in an environment where it's supposed to be tabs. There's not much point in arguing the matter. Some folks prefer tabs, and some prefer spaces, but I believe that it's most common for spaces to be preferred as far as style guides go, and they're generally less error-prone simply because it's easy enough to set up editors so that tabs are never used, and you can't do the same with spaces when you're using tabs for indentation. - Jonathan M Davis
Apr 11 2011
parent reply "Nick Sabalausky" <a a.a> writes:
"Cliff Hudson" <cliff.s.hudson gmail.com> wrote in message 
news:mailman.3414.1302586393.4748.digitalmars-d puremagic.com...
 Spaces *should* only be used within string constants (as needed), or when
 the language otherwise requires them.  The editor should format the code
 according to user preferences.

 Absent that, spaces represent the lowest common denominator of formatting,
 so we can all use them and our text shows up as we desire regardless of
 editor or setting.
I'd rather my text show up indented the way the person reading it desires.
 Can we move along now?  This argument was old 30 years ago.  Perhaps we
 should do VI vs. EMACS while we are at it.
Pico rules them all! ;)
Apr 12 2011
parent reply Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
On 12/04/2011 20:49, Nick Sabalausky wrote:
 Can we move along now?  This argument was old 30 years ago.  Perhaps we
 should do VI vs. EMACS while we are at it.
Pico rules them all! ;)
Vi *and* Emacs suck. Argument settled :P (yes, that was hyperbolic rhetoric) -- Bruno Medeiros - Software Engineer
Jun 03 2011
next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On 2011-06-03 05:45, Bruno Medeiros wrote:
 On 12/04/2011 20:49, Nick Sabalausky wrote:
 Can we move along now? This argument was old 30 years ago. Perhaps we
 should do VI vs. EMACS while we are at it.
Pico rules them all! ;)
Vi *and* Emacs suck. Argument settled :P
Yeah, I got sucked in by vim, and I've never gotten away. ;) - Jonathan M Davis
Jun 03 2011
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
I bet you wrote std.datetime with a call to a single Vim macro.

Just kidding. :P
Jun 03 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 4/12/11, Cliff Hudson <cliff.s.hudson gmail.com> wrote:
 Perhaps we
 should do VI vs. EMACS while we are at it.
Don't bring operating systems into this... ... just kidding. :P
Apr 11 2011
prev sibling parent reply spir <denis.spir gmail.com> writes:
On 04/12/2011 07:13 AM, Jonathan M Davis wrote:
 It's true that people occasionally end up inserting tabs in space-only
 environments, but in my experience, it's fairly rare. It's pretty much a
 guarantee, however, that _someone_ will insert spaces in an environment where
 it's supposed to be tabs.
How can you assert that? you stated yourself that in all your work environments the convention was spaces. So, logically, all mess up cases you have ever experienced are due to the standard beeing spaces. Your assertion about tab-as-standard causing more mess up is complete guessing. Please, be fair. Denis -- _________________ vita es estrany spir.wikidot.com
Apr 12 2011
parent reply =?UTF-8?B?IkrDqXLDtG1lIE0uIEJlcmdlciI=?= <jeberger free.fr> writes:
spir wrote:
 On 04/12/2011 07:13 AM, Jonathan M Davis wrote:
 It's true that people occasionally end up inserting tabs in space-only=
 environments, but in my experience, it's fairly rare. It's pretty much=
a
 guarantee, however, that _someone_ will insert spaces in an
 environment where
 it's supposed to be tabs.
=20 How can you assert that? you stated yourself that in all your work environments the convention was spaces. So, logically, all mess up case=
s
 you have ever experienced are due to the standard beeing spaces.
 Your assertion about tab-as-standard causing more mess up is complete
 guessing.
 Please, be fair.
=20
Well, I have worked in both environments, and I have seen a lot more mess ups with tabs than with spaces... Other than that (and the fact that almost *no* editors are able to do it properly), I would really prefer "tabs for indent, spaces for align". Jerome --=20 mailto:jeberger free.fr http://jeberger.free.fr Jabber: jeberger jabber.fr
Apr 12 2011
parent reply "Nick Sabalausky" <a a.a> writes:
""Jérôme M. Berger"" <jeberger free.fr> wrote in message 
news:io230l$1ldc$3 digitalmars.com...
Well, I have worked in both environments, and I have seen a lot
more mess ups with tabs than with spaces... Other than that (and the
fact that almost *no* editors are able to do it properly), I would
really prefer "tabs for indent, spaces for align".
I prefer "tabs for indent, tabs for align, spaces for separation", but that requires elastic tabstops. And at least one of the biggest code-edit controls out there (the one I use), Scintilla, doesn't support them :(
Apr 12 2011
parent reply =?UTF-8?B?IkrDqXLDtG1lIE0uIEJlcmdlciI=?= <jeberger free.fr> writes:
Nick Sabalausky wrote:
 ""J=EF=BF=BDr=EF=BF=BDme M. Berger"" <jeberger free.fr> wrote in messag=
e=20
 news:io230l$1ldc$3 digitalmars.com...
 Well, I have worked in both environments, and I have seen a lot
 more mess ups with tabs than with spaces... Other than that (and the
 fact that almost *no* editors are able to do it properly), I would
 really prefer "tabs for indent, spaces for align".
=20 I prefer "tabs for indent, tabs for align, spaces for separation", but =
that=20
 requires elastic tabstops. And at least one of the biggest code-edit=20
 controls out there (the one I use), Scintilla, doesn't support them :(
=20
=20
That depends what you mean by "align". I agree that for the following, elastic tab stops would be best: int a; SomeType b; However, for this, I think that spaces are better: doSomething (someLongParameterThatJustifiesBreakingTheLine, someOtherLongParameterJustInCase); Jerome --=20 mailto:jeberger free.fr http://jeberger.free.fr Jabber: jeberger jabber.fr
Apr 13 2011
parent reply "Nick Sabalausky" <a a.a> writes:
""Jérôme M. Berger"" <jeberger free.fr> wrote in message 
news:io4sng$1p9b$1 digitalmars.com...
Nick Sabalausky wrote:
 ""J?r?me M. Berger"" <jeberger free.fr> wrote in message
 news:io230l$1ldc$3 digitalmars.com...
 Well, I have worked in both environments, and I have seen a lot
 more mess ups with tabs than with spaces... Other than that (and the
 fact that almost *no* editors are able to do it properly), I would
 really prefer "tabs for indent, spaces for align".
I prefer "tabs for indent, tabs for align, spaces for separation", but that requires elastic tabstops. And at least one of the biggest code-edit controls out there (the one I use), Scintilla, doesn't support them :(
That depends what you mean by "align". I agree that for the following, elastic tab stops would be best: int a; SomeType b; However, for this, I think that spaces are better: doSomething (someLongParameterThatJustifiesBreakingTheLine, someOtherLongParameterJustInCase);
I guess we disagree on that. Like I said in another branch, I used to do that, but then I found that mixing tabs/spaces before the first non-whitespace on a line is just asking for trouble. I'd rather do it like this (assuming elastic tabstops): doSomething(->someLongParameterThatJustifiesBreakingTheLine, -> someOtherLongParameterJustInCase); Of course, that does demonstrate that I've never liked putting any whitespace between a function name (or if/while/etc.) and the opening paren. YMMV.
Apr 13 2011
parent reply =?UTF-8?B?IkrDqXLDtG1lIE0uIEJlcmdlciI=?= <jeberger free.fr> writes:
Nick Sabalausky wrote:
 ""J=EF=BF=BDr=EF=BF=BDme M. Berger"" <jeberger free.fr> wrote in messag=
e=20
 news:io4sng$1p9b$1 digitalmars.com...
 Nick Sabalausky wrote:
 ""J?r?me M. Berger"" <jeberger free.fr> wrote in message
 news:io230l$1ldc$3 digitalmars.com...
 Well, I have worked in both environments, and I have seen a lot
 more mess ups with tabs than with spaces... Other than that (and the=
 fact that almost *no* editors are able to do it properly), I would
 really prefer "tabs for indent, spaces for align".
I prefer "tabs for indent, tabs for align, spaces for separation", bu=
t=20
 that
 requires elastic tabstops. And at least one of the biggest code-edit
 controls out there (the one I use), Scintilla, doesn't support them :=
(

 That depends what you mean by "align". I agree that for the
 following, elastic tab stops would be best:

 int      a;
 SomeType b;

 However, for this, I think that spaces are better:

 doSomething (someLongParameterThatJustifiesBreakingTheLine,
             someOtherLongParameterJustInCase);
=20 I guess we disagree on that. Like I said in another branch, I used to d=
o=20
 that, but then I found that mixing tabs/spaces before the first=20
 non-whitespace on a line is just asking for trouble.
=20
Yes, that is the main reason why I use spaces for indenting...
 I'd rather do it like this (assuming elastic tabstops):
=20
 doSomething(->someLongParameterThatJustifiesBreakingTheLine,
 ->            someOtherLongParameterJustInCase);
=20
 Of course, that does demonstrate that I've never liked putting any=20
 whitespace between a function name (or if/while/etc.) and the opening p=
aren.=20
 YMMV.
=20
Well, standard (printed) typographic practices put spaces outside the parenthesis and none inside. And as opposed to a lot of typographic rules, that one is a constant across languages and variants. Jerome --=20 mailto:jeberger free.fr http://jeberger.free.fr Jabber: jeberger jabber.fr
Apr 13 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 4/13/11 4:17 PM, "Jérôme M. Berger" wrote:
 Nick Sabalausky wrote:
 ""J�r�me M. Berger""<jeberger free.fr>  wrote in message
 news:io4sng$1p9b$1 digitalmars.com...
 Nick Sabalausky wrote:
 ""J?r?me M. Berger""<jeberger free.fr>  wrote in message
 news:io230l$1ldc$3 digitalmars.com...
 Well, I have worked in both environments, and I have seen a lot
 more mess ups with tabs than with spaces... Other than that (and the
 fact that almost *no* editors are able to do it properly), I would
 really prefer "tabs for indent, spaces for align".
I prefer "tabs for indent, tabs for align, spaces for separation", but that requires elastic tabstops. And at least one of the biggest code-edit controls out there (the one I use), Scintilla, doesn't support them :(
That depends what you mean by "align". I agree that for the following, elastic tab stops would be best: int a; SomeType b; However, for this, I think that spaces are better: doSomething (someLongParameterThatJustifiesBreakingTheLine, someOtherLongParameterJustInCase);
I guess we disagree on that. Like I said in another branch, I used to do that, but then I found that mixing tabs/spaces before the first non-whitespace on a line is just asking for trouble.
Yes, that is the main reason why I use spaces for indenting...
 I'd rather do it like this (assuming elastic tabstops):

 doSomething(->someLongParameterThatJustifiesBreakingTheLine,
 ->             someOtherLongParameterJustInCase);

 Of course, that does demonstrate that I've never liked putting any
 whitespace between a function name (or if/while/etc.) and the opening paren.
 YMMV.
Well, standard (printed) typographic practices put spaces outside the parenthesis and none inside. And as opposed to a lot of typographic rules, that one is a constant across languages and variants.
Math typography rules also preclude inserting a space between a function's name and the opening brace. That's why I consistently go with no space after the opening paren or before the closing paren. Also, that's why there's no need to make if (condition) and func(args) consistent with regard to space before opening paren. In the first case the paren is pure punctuation; in the latter it is an organic part of the function invocation syntax. So one should never leave a space between function name and opening paren, and decide independently regarding the existence of a space between if/while etc. and the opening paren. Andrei
Apr 13 2011
parent reply spir <denis.spir gmail.com> writes:
On 04/13/2011 11:44 PM, Andrei Alexandrescu wrote:
 On 4/13/11 4:17 PM, "Jérôme M. Berger" wrote:
 Well, standard (printed) typographic practices put spaces outside
 the parenthesis and none inside. And as opposed to a lot of
 typographic rules, that one is a constant across languages and variants.
Math typography rules also preclude inserting a space between a function's name and the opening brace. That's why I consistently go with no space after the opening paren or before the closing paren. Also, that's why there's no need to make if (condition) and func(args) consistent with regard to space before opening paren. In the first case the paren is pure punctuation; in the latter it is an organic part of the function invocation syntax. So one should never leave a space between function name and opening paren, and decide independently regarding the existence of a space between if/while etc. and the opening paren.
Agreed. In the same vein, function definition is not a function call; thus I use to write: int square (int n) { return n * n; } sq = square(3); Actually, I have never been pleased that func defs (1) look like func calls (2) have an exceptional syntax compared to other definitions. I'd like instead eg: square = function (int n) int { return n * n; } Denis -- _________________ vita es estrany spir.wikidot.com
Apr 14 2011
parent reply =?UTF-8?B?IkrDqXLDtG1lIE0uIEJlcmdlciI=?= <jeberger free.fr> writes:
spir wrote:
 Actually, I have never been pleased that func defs (1) look like func
 calls (2) have an exceptional syntax compared to other definitions. I'd=
 like instead eg:
=20
     square =3D function (int n) int {
         return n * n;
     }
=20
That is still different from other definitions where the type comes first. But the following would work too: function (int n) int square =3D { return n*n; } And both would be easier to parse to boot:) There are actually languages out there with this kind of syntax. Jerome --=20 mailto:jeberger free.fr http://jeberger.free.fr Jabber: jeberger jabber.fr
Apr 14 2011
parent spir <denis.spir gmail.com> writes:
On 04/14/2011 07:58 PM, "Jérôme M. Berger" wrote:
 spir wrote:
 Actually, I have never been pleased that func defs (1) look like func
 calls (2) have an exceptional syntax compared to other definitions. I'd
 like instead eg:

      square = function (int n) int {
          return n * n;
      }
That is still different from other definitions where the type comes first.
True. I was firstly evoking the "x = y" form.
  But the following would work too:

 function (int n) int square = {
     return n*n;
 }

 	And both would be easier to parse to boot:)
Yes, I like your format as well.
  There are actually
 languages out there with this kind of syntax.
Yop, I know (my example was Lua-like: we are not reinventing the wheel ;-) Denis -- _________________ vita es estrany spir.wikidot.com
Apr 14 2011
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2011-04-12 05:19, Jonathan M Davis wrote:
 On 04/11/2011 08:13 AM, Jonathan M Davis wrote:
 They mix tabs and spaces. On some lines, they use spaces and on others
 they use tabs.
Never seen this, not even once. Messing can only happen when one copy-pastes from modules using spaces.
As Steve pointed out, it frequently happens when you have multiple developers working on the same code. It may work with one developer who likes using tabs, but as soon as you get a mix of developers, you invariably get a mix of spaces and tabs unless _everyone_ involved is really careful, and that rarely happens. It's just too easy to use spaces without realizing that someone else used tabs or even that you yourself are using spaces, depending on your editor's settings.
How can it not be as easy to use tabs without realizing that someone else used spaces?
 Using only spaces and no tabs avoids the entire issue and is one of the major
 reasons (if not _the_ major reason) why it is incredibly common for coding
 standards to require spaces and prohibit tabs. Obviously, you _can_ use tabs
 if you're careful - especially if you're the only programmer involved - but
 it's just simpler to disallow tabs when you're dealing with a group of
 developers.

 - Jonathan M Davis
-- /Jacob Carlborg
Apr 12 2011
parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
 On 2011-04-12 05:19, Jonathan M Davis wrote:
 On 04/11/2011 08:13 AM, Jonathan M Davis wrote:
 They mix tabs and spaces. On some lines, they use spaces and on others
 they use tabs.
Never seen this, not even once. Messing can only happen when one copy-pastes from modules using spaces.
As Steve pointed out, it frequently happens when you have multiple developers working on the same code. It may work with one developer who likes using tabs, but as soon as you get a mix of developers, you invariably get a mix of spaces and tabs unless _everyone_ involved is really careful, and that rarely happens. It's just too easy to use spaces without realizing that someone else used tabs or even that you yourself are using spaces, depending on your editor's settings.
How can it not be as easy to use tabs without realizing that someone else used spaces?
Oh, it can be. But what generally happens in environments where spaces are required is that everyone sets up their editors to insert spaces when you hit the tab key instead of a tab (if everyone is using a common IDE, it's probably even required), so it becomes pretty much impossible to enter tabs by accident, whereas in an environment where tabs are used, you're not going to disable the spacebar, so spaces can still be inserted. So, generally, in a spaces-only environment, you don't run into problems with tabs. - Jonathan M Davis
Apr 12 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On 04/12/2011 05:15 AM, Jonathan M Davis wrote:
 So, how you format
 your code matters. Using tabs screws with that unless you're completely
 consistent, and while a single developer may be consistent, groups of
 developers rarely are.
This is as true in the case of spaces. With the additional issue of indent-width. Denis -- _________________ vita es estrany spir.wikidot.com
Apr 12 2011
prev sibling next sibling parent reply spir <denis.spir gmail.com> writes:
On 04/12/2011 05:19 AM, Jonathan M Davis wrote:
 Using only spaces and no tabs avoids the entire issue
spaces <--> tabs works as fine Why are programmers so blindly unfair when discussing this point?
 and is one of the major reasons (if not _the_ major reason) why it is
incredibly common for coding
standards to require spaces and prohibit tabs. Obviously, you _can_ use tabs if you're careful - especially if you're the only programmer involved - but it's just simpler to disallow tabs when you're dealing with a group of developers. I guess the true reason why spaces are required in guidelines is a mix of conformism and "virality". At one point in time, people started to face the issue, thay had to make a choice for coding standard in language libs, corporation code, school/university works, etc. They chose spaces because, at that time, most people used spaces and did not want to change. Then, even more programmers get used to use spaces and don't want to change, so that new coding standards are forced to enforce spaces, and so on... There is no, and there has never been any, logical reason for this choice. There cannot be, in fact: 1. Tabs properly separate code content from view, 2. and respect each reader's preference. In addition to those main reasons, they have a few nice side-effects: * No indent width issue (!), * 1 tab <--> 1 indent level conceptually, * deletion is 1 key press, even with stupid editors. A drawback is one cannot directly have different indent levels, for instance to indent collection contents more, or less, than blocks of code. This can also be considered an advantage; and is simply solved by using... spaces ;-) void f () { -> while (true) { -> -> table = [ -> -> .."aaa" : 1, -> -> .."bbb" : 2, -> -> .."ccc" : 3, -> -> ]; -> -> auto a = this(table); -> -> if (! a) break; -> } } (yes, the example is stupid) Denis -- _________________ vita es estrany spir.wikidot.com
Apr 12 2011
parent reply =?UTF-8?B?IkrDqXLDtG1lIE0uIEJlcmdlciI=?= <jeberger free.fr> writes:
spir wrote:
 In addition to those main reasons, they have a few nice side-effects:
=20
 * No indent width issue (!),
True
 * 1 tab <--> 1 indent level conceptually,
True
 * deletion is 1 key press, even with stupid editors.
False, not with some *really* stupid editors I have seen (!)
=20
 A drawback is one cannot directly have different indent levels, for
 instance to indent collection contents more, or less, than blocks of
 code. This can also be considered an advantage; and is simply solved by=
 using... spaces ;-)
=20
 void f () {
  -> while (true) {
  ->  -> table =3D [
  ->  -> .."aaa" : 1,
  ->  -> .."bbb" : 2,
  ->  -> .."ccc" : 3,
  ->  -> ];
  ->  -> auto a =3D this(table);
  ->  -> if (! a) break;
  -> }
 }
=20
 (yes, the example is stupid)
=20
Unfortunately, most editors are completely unable to handle this example properly: sure they will *display* it fine, but they will not allow you to *enter* it right (especially if you need more spaces for alignment than the tab size). Jerome --=20 mailto:jeberger free.fr http://jeberger.free.fr Jabber: jeberger jabber.fr
Apr 12 2011
parent reply "Nick Sabalausky" <a a.a> writes:
""Jérôme M. Berger"" <jeberger free.fr> wrote in message 
news:io2396$1nuo$1 digitalmars.com...
spir wrote:
 A drawback is one cannot directly have different indent levels, for
 instance to indent collection contents more, or less, than blocks of
 code. This can also be considered an advantage; and is simply solved by
 using... spaces ;-)

 void f () {
  -> while (true) {
  ->  -> table = [
  ->  -> .."aaa" : 1,
  ->  -> .."bbb" : 2,
  ->  -> .."ccc" : 3,
  ->  -> ];
  ->  -> auto a = this(table);
  ->  -> if (! a) break;
  -> }
 }

 (yes, the example is stupid)
Unfortunately, most editors are completely unable to handle this example properly: sure they will *display* it fine, but they will not allow you to *enter* it right (especially if you need more spaces for alignment than the tab size).
That's unfortunately true. I used to try to do that in cases like this: if(blah) { -> foo(.bigLongArg1, -> .....bigLongArg2, -> .....bigLongArg3 -> ); } But editors just choke on that like crazy. It's a pain to type it in that way, and then when you go back to edit (add another arg on another line, for instance), it just screws it all up again, likely without me even noticing right away. (And I even have most auto-formatting turned off.) I decided it was far more trouble than it was worth. So I've changed my style to this: if(blah) { -> foo( -> -> bigLongArg1, -> -> bigLongArg2, -> -> bigLongArg3 -> ); } Much better. Of course, it would be even better still if Scintilla would be willing to add elastic tabstops (I'm getting increasingly annoyed that it doesn't, and that it doesn't even seem receptive to the idea, for technical reasons), because then I *could* do exactly what I used to with absolutely no problem: if(blah) { -> foo(->bigLongArg1, -> -> bigLongArg2, -> -> bigLongArg3 -> ); } And everything would always align properly.
Apr 12 2011
next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
Nick Sabalausky wrote:
 So I've changed my style to this:

 if(blah)
 {
 ->  foo(
 ->  ->  bigLongArg1,
 ->  ->  bigLongArg2,
 ->  ->  bigLongArg3
 ->  );
 }
That's something I've started doing too. It's not just a matter of alignment either - I think the first argument on the same line as the function name is easy to miss. It all blends in together.
Apr 12 2011
prev sibling next sibling parent Kagamin <spam here.lot> writes:
Nick Sabalausky Wrote:

 So I've changed my style to this:
 
 if(blah)
 {
 ->  foo(
 ->  ->  bigLongArg1,
 ->  ->  bigLongArg2,
 ->  ->  bigLongArg3
 ->  );
 }
 
 Much better. Of course, it would be even better still if Scintilla would be 
 willing to add elastic tabstops (I'm getting increasingly annoyed that it 
 doesn't, and that it doesn't even seem receptive to the idea, for technical 
 reasons), because then I *could* do exactly what I used to with absolutely 
 no problem:
Scintilla has 3 word wrapping modes, so long lines should not be a problem.
Apr 12 2011
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On 04/12/2011 10:08 PM, Nick Sabalausky wrote:
 ""Jérôme M. Berger""<jeberger free.fr>  wrote in message
 news:io2396$1nuo$1 digitalmars.com...
 spir wrote:
 A drawback is one cannot directly have different indent levels, for
 instance to indent collection contents more, or less, than blocks of
 code. This can also be considered an advantage; and is simply solved by
 using... spaces ;-)

 void f () {
   ->  while (true) {
   ->   ->  table = [
   ->   ->  .."aaa" : 1,
   ->   ->  .."bbb" : 2,
   ->   ->  .."ccc" : 3,
   ->   ->  ];
   ->   ->  auto a = this(table);
   ->   ->  if (! a) break;
   ->  }
 }

 (yes, the example is stupid)
Unfortunately, most editors are completely unable to handle this example properly: sure they will *display* it fine, but they will not allow you to *enter* it right (especially if you need more spaces for alignment than the tab size).
That's unfortunately true.
Strange... did not know that, but I have only used geany for a while already. Denis -- _________________ vita es estrany spir.wikidot.com
Apr 12 2011
prev sibling parent Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
On 12/04/2011 21:08, Nick Sabalausky wrote:
 ""Jérôme M. Berger""<jeberger free.fr>  wrote in message
 news:io2396$1nuo$1 digitalmars.com...
 spir wrote:
 A drawback is one cannot directly have different indent levels, for
 instance to indent collection contents more, or less, than blocks of
 code. This can also be considered an advantage; and is simply solved by
 using... spaces ;-)

 void f () {
   ->  while (true) {
   ->   ->  table = [
   ->   ->  .."aaa" : 1,
   ->   ->  .."bbb" : 2,
   ->   ->  .."ccc" : 3,
   ->   ->  ];
   ->   ->  auto a = this(table);
   ->   ->  if (! a) break;
   ->  }
 }

 (yes, the example is stupid)
Unfortunately, most editors are completely unable to handle this example properly: sure they will *display* it fine, but they will not allow you to *enter* it right (especially if you need more spaces for alignment than the tab size).
Why would editors not allow you to enter that right? I don't see what the problem would be, unless you configured your editor to replaces N spaces into a tab for indentation.
 That's unfortunately true. I used to try to do that in cases like this:

 if(blah)
 {
 ->   foo(.bigLongArg1,
 ->   .....bigLongArg2,
 ->   .....bigLongArg3
 ->   );
 }

 But editors just choke on that like crazy. It's a pain to type it in that
 way, and then when you go back to edit (add another arg on another line, for
 instance), it just screws it all up again, likely without me even noticing
 right away. (And I even have most auto-formatting turned off.) I decided it
 was far more trouble than it was worth.
Works fine in Eclipse, again because when it auto-indents on Enter, it uses the indentation of the previous line. :) -- Bruno Medeiros - Software Engineer
Apr 13 2011
prev sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On 2011-06-03 11:01, Andrej Mitrovic wrote:
 I bet you wrote std.datetime with a call to a single Vim macro.
 
 Just kidding. :P
That sort of talk leads to things like this: http://xkcd.com/378/ - Jonathan M Davis
Jun 03 2011
parent Stewart Gordon <smjg_1998 yahoo.com> writes:
On 03/06/2011 19:06, Jonathan M Davis wrote:
<snip>
 That sort of talk leads to things like this: http://xkcd.com/378/
I was told that Real Programmers use punch cards. Someone must've found some even realer programmers.... Stewart.
Jun 03 2011