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.
Posts tagged ‘Delphi’
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…
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]
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?’ »
This week’s just getting started, and it’s already had more than enough awesomeness to pack into a typical month. The new version of Delphi came out yesterday. Metroid: Other M and The Way of Kings, a new Brandon Sanderson book, were both released today. (I have a feeling I’m going to be more distracted than usual for a while…) But as awesome as Metroid games and anything by Sanderson tend to be, (if you’re into fantasy at all, check out Elantris and Mistborn and prepare to be blown away,) this is a programming blog, and I’m supposed to be talking about Delphi. So here’s the good, the bad, and the annoying about my first impressions with Delphi XE.
Last night at DelphiLive they had a “Meet the team” event in one of the halls, where most of the RAD Studio development team was present and the attendees could hang out and chat with them. While I was there, I talked with Mike Rozlog a bit. He’d seen some of the critical things I wrote on here and on the forums about the roadmap, and he explained to me a bit about how the process of making a roadmap works. One thing to keep in mind is that he told me it’s like this everywhere he’s worked. What I’m about to describe is apparently not a symptom of dysfunctional corporate culture at Embarcadero; more like dysfunctional corporate culture in general. Continue reading ‘The insanities of roadmap publishing’ »
The second sneak preview is out now. It’s quite a bit more interesting than the first one. FinalBuilder being added to the package will make it a lot easier for me to get builds set up for the TURBU project. Right now I have to do it all by hand. So far I haven’t missed a step and ended up releasing it, but if there’s a way to reduce the chance of that happening in the future I’d definitely appreciate it. I just wonder if it’ll be in all editions or just the higher-level SKUs.
Then they mentioned AQTime, which looked interesting but IMO brings up more questions than it answers. For example, “Since this is the standard edition, not all of the profilers are enabled.” (9:13) But I don’t see any of the profilers on that list grayed out. And again, will this be in all editions, or just the high-level ones?
Also, will it come with an extension to the Open Tools API to allow other profilers to be integrated? AQTime has some great features, but its core feature, performance profiling, uses instrumenting that slows your app down horribly, which makes it unsuitable for a lot of uses. I prefer Sampling Profiler, which gives a good picture of what you’re spending your time doing without instrumenting your program. It doesn’t provide the perfect counting accuracy that instrumenting does, but most of the time you don’t actually need that anyway in order to track down performance problems. If there was a way to integrate Sampling Profiler into Delphi, it would make a good compliment to AQTime’s other profilers.
As for CodeSite, I don’t have too much to say about that, because I don’t know enough about how it works to discuss it very well. Logging’s definitely useful, but usually in different ways than what they were demonstrating on the video. For example, if CodeSite can only output to that popup window, it’s worthless IMO. But if it can write to a file, or better yet if it allows you to create and register custom outputs of some kind, that would be a big help.
The one thing I’m a bit worried about is price. Delphi’s got three general problems, which need to be resolved independently.
Delphi 2011’s main point was supposed to be addressing a missing feature. That ended up not happening, as the team members have been explaining, because they don’t have enough time to get it working at a good quality level. That’s definitely a praiseworthy attitude, but I’m a bit worried at seeing all these expensive third-party tools being suddenly announced as part of the product. They don’t actually do anything to solve the three main problems facing Delphi, and I’m a bit worried that they’ll end up taking the price even higher.
They’ve mentioned their commitment to quality several times, and specifically that they’ve done a lot of work to fix the generics issues. That’s great, and if they’ve allocated some resources to getting a Error Insight and Code Completion working properly that’ll be even better. But even so, not having the main missing feature we were expecting would be delivered is going to do a lot to reduce the perceived quality of the release, even if the objective quality has gone up quite a bit since D2010. Quality improvements are generally expected to be part of an update, not a new release. (The “I paid good money for this with the expectation that the promised features would actually work” argument.)
I really hope I’m interpreting this wrong, but what it looks like to me is that in order to avoid the new version being perceived as “just a bugfix release” that isn’t worth the price, Embarcadero decided to bundle a bunch of expensive tools to make it appear to be more worth the cost. If that’s what they’re doing, there are two ways to do it, and both will hurt them. Either the price stays about the same as it was for D2010, but they’re paying a share of it to the owners of AQTime, FinalBuilder, etc, so they lose a lot of revenue, or they pass that cost along to us, the price goes up, (without delivering the anticipated new feature,) and a lot of people end up not wanting to buy it at that price, so they lose a lot of revenue.
What I would prefer, and what I would do if it was my product, is to negotiate some sort of deal with the creators of these other products where people who buy Delphi XE can pick them up at a discount, and then sell the actual Delphi license to us at a reduced price. That would help improve sales, or at the very least help stem the loss of sales resulting from not having cross-platform available, and no one ends up paying for add-on products they don’t need. (And not everyone will need them. Where I work we’ve got a bunch of developers and one build machine. If we all got a copy of FinalBuilder… what would we do with it?)
I really hope I’m wrong about this, but this is what it looks like Embarcadero is doing. I just wish they wouldn’t, since I don’t think it will actually be good for Delphi users, or for Delphi itself.