Beware using anonymous methods in loops
Quick, what’s the output of this simple routine?
Continue reading ‘Beware using anonymous methods in loops’ »
Mason Wheeler's thoughts on Delphi programming in general, and particularly on the technical aspects of developing the TURBU engine and editor.
Quick, what’s the output of this simple routine?
Continue reading ‘Beware using anonymous methods in loops’ »
I mentioned the new generic collection TThreadedQueue<T> in my First Look at Delphi XE. I decided to play around with it a little recently. It’s useful for passing data between one thread that produces output and another that consumes it, keeping the two in step by blocking if the consumer tries to pop from the queue while it’s empty.
The first thread goes through and pushes data into the queue however it wants to. The second has it easy; all it has to do is loop endlessly until the queue is shut down. And we all know how to do that:
[code lang="delphi"] for value in queue do process(value); [/code]
Except that if you try to do that, the compiler will complain at you. There’s no enumerator. For some strange reason, out of all the collections in Generics.Collections, TThreadedQueue<T> alone does not descend from TEnumerable<T>.
Oh well. It’s not all that hard to add an enumerator to a class that doesn’t have one. Just use a class helper.
[code lang="Delphi"] TThreadedQueueEnumerator= class private FQueue: TThreadedQueue ; FCurrent: T; function GetCurrent: T; public constructor Create(queue: TThreadedQueue ); property Current: T read GetCurrent; function MoveNext: Boolean; end; TThreadedQueueHelper = class helper for TThreadedQueue public function GetEnumerator: TThreadedQueueEnumerator ; end; implementation { TThreadedQueueEnumerator } constructor TThreadedQueueEnumerator .Create(queue: TThreadedQueue ); begin FQueue := queue; end; function TThreadedQueueEnumerator .GetCurrent: T; begin result:= FCurrent; end; function TThreadedQueueEnumerator .MoveNext: Boolean; begin result := FQueue.PopItem(FCurrent) = wrSignaled; end; { TThreadedQueueHelper } function TThreadedQueueHelper .GetEnumerator: TThreadedQueueEnumerator ; begin result := TThreadedQueueEnumerator.Create(self); end; [/code]
Well, that was easy. That’s probably the simplest enumerator I’ve ever written, because of the way the queue’s design makes it easy to implement MoveNext. Except… that doesn’t compile either. Apparently you can’t put generic type parameters on a class helper, which means that as far as I can tell, you can’t apply a class helper to a generic class at all.
I suppose I could subclass it and add the enumerator that way, but TEnumerableThreadedQueue<T> is a bit of a bulky name, don’t you think? I have to wonder why the enumerator was left off of this collection, though, especially since the standard enumerator pattern is basically the only reasonable way to use a class like this…
One of the hallmarks of a society that values freedom is the concept of Rule of Law, which basically means that people, even the people in charge, can’t just arbitrarily decide that they don’t like what someone else is doing and act to stop them or punish them for it. Instead we have laws that explain what’s not allowed, what the punishment for breaking them is, and how they are to be administered. That administration part is important. It means that if my neighbor steals something from me, I can’t go and throw him in prison, even if the punishment for it is prison time, because I’m not a law enforcement official.
In fact, we have laws that specifically say that if someone breaks the law, I’m not allowed to punish them for it, even if I was directly harmed by their actions, because I don’t have the authority to enforce the law. People who attempt to do so are known as vigilantes, and their actions are usually illegal, because vigilante justice is flawed in several fundamental ways. First, it’s not always easy to know if you’ve got the right guy. Second, even if you do have the right guy, you don’t know if there are extenuating circumstances for them having done what they did. (This idea goes a very long way, even to the most serious of crimes. It’s why there’s a legal distinction between “murder” and “killing in self-defense,” for example.) And third, even if you have the right guy and you know that they acted maliciously, what you might think of as a proper punishment for the crime may be way over the top, especially if you’re the injured party. This is why trials for particularly severe and shocking crimes are often held in a different community from where it was committed, to make it possible (or at least easier) to get an impartial jury with no personal stake in the matter.
What does this have to do with software? Well, if you’ve been following DelphiFeeds lately, you can probably guess. Continue reading ‘Rule of Law, software, and stray cows’ »
There’s been a lot of talk in the last few years about major language features that Delphi doesn’t have. Stuff like Unicode and Generics which finally got added in D2009, stuff like 64-bit compilation that’s perenially slated for another year or two out, and so on. There’s currently a major debate going on (and on and on) in the Delphi forums about the team’s statement that the next release won’t include inline assembly, and the effects that that will or won’t have on library compatibility and future development.
But there are also more minor, simple things that we don’t have, and some of them are a little bit silly. Continue reading ‘Why don’t we have this?’ »
What’s wrong with this code?
[code lang="Delphi"] procedure TMyCustomChecklistPopupControl.ClosePopup; var i: integer; begin inherited ClosePopup; FInternalItemStringList.Clear; for i := 0 to Self.CheckedCount - 1 do FInternalItemStringList.Add(Self.CheckedItems[i].Name); end; [/code]
A few weeks ago, I mentioned the release of The Way of Kings, the first installment of Brandon Sanderson’s new epic, The Stormlight Archive. I’ve had a bunch of other stuff distracting me since then, but this week I’ve finally put some time aside to read through it. And it did take all week. This is an enormous novel, 1000 pages in hardcover. Howard Tayler called it “the best argument you’ll have all year to get an e-reader, because you HAVE to have this book, but you might not be muscular enough to carry it around.” I’m going to disagree with that conclusion. Get the real novel. A digital display just won’t be able to do the beautiful, detailed illustrations in between some of the chapters justice. But he’s right that you have to have this book; it’s the Must Read Novel Of The Year if you’re into fantasy literature at all. Continue reading ‘Review: The Way of Kings’ »
My friend and coworker François Gaillard recently set up a tech blog over at fgaillard.com. I just ran across an interesting post about using inherited; in Delphi, and since he’s not listed on DelphiFeeds yet, I figured I’d link to it here. He’s a pretty talented engineer with a good mind, so you can expect to see some good observations over there if he keeps at it. (He also gave a very interesting session at Delphi Live this year about speech technology, and anyone who can get an English version of Windows to understand his thick Inspector Clousseau accent obviously knows a thing or two about bending a computer to his will!) 😉
Also, just in case anyone hasn’t seen it yet, (this isn’t quite as recent,) Nick Hodges has a blog again, over at nickhodges.com, and it’s not on DelphiFeeds yet either. I figured I’d post a link here, since one good shout-out deserves another.
The last few versions of MS SQL Server have included a feature where you can create new functions in .NET assemblies and register them with the database server. This can be a good way to deal with concepts that are difficult to express in T/SQL, and it can provide some big performance boosts. The process is not without its warts, though. Continue reading ‘When is a null not a null?’ »
For those who haven’t seen it yet, due to popular demand, the StackOverflow people created a new site called programmers.stackexchange.com, a site for the more subjective questions that StackOverflow isn’t really designed for. Someone recently set up a poll: What’s your favorite programming language. You can probably guess what my answer was. Continue reading ‘Little things Delphi gets right’ »
I got a very interesting response to my last post, about missing features in extended RTTI. Barry Kelly wrote in a comment,
There wasn’t any increase in [RTTI] coverage for XE because other work had priority (64-bit, x-plat, a front end that could support LINQ, more things that I can’t talk about).
None of this actually showed up in XE. The cross-platform work was supposed to, right up until a couple months ago, but they deferred it because it wasn’t ready yet. And the 64-bit work’s been promised but not delivered yet for a long time. (Now they say it’ll be in XE2. I sure hope so!) But… LINQ support in the compiler? Under active development and not a “more things I can’t talk about”? Wow, when did this happen?
Continue reading ‘Native LINQ under active development?’ »