<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-4168503339888369834</atom:id><lastBuildDate>Wed, 28 Oct 2009 22:43:38 +0000</lastBuildDate><title>sizeof(uint32t)</title><description>Dodheim reads only four blogs. This is one of them.</description><link>http://uint32t.blogspot.com/</link><managingEditor>sohail@taggedtype.net (Sohail Somani)</managingEditor><generator>Blogger</generator><openSearch:totalResults>116</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/uint32t" type="application/rss+xml" /><feedburner:emailServiceId>uint32t</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/uint32t" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fuint32t" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-1037310819205501139</guid><pubDate>Sat, 17 Oct 2009 14:09:00 +0000</pubDate><atom:updated>2009-10-17T08:24:24.991-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">qt</category><title>Using Boost Function with Qt, Part 2.</title><description>[Following up &lt;a href="http://uint32t.blogspot.com/2008/11/using-boost-bind-and-boost-function.html"&gt;this post&lt;/a&gt;]&lt;br /&gt;&lt;br /&gt;&lt;a href="http://uint32t.blogspot.com/2008/11/using-boost-bind-and-boost-function.html?showComment=1255764339129#c1759598075976409702"&gt;Johan asks&lt;/a&gt;:&lt;br /&gt;&lt;dl class="avatar-comment-indent" id="comments-block"&gt;&lt;dd class="comment-body"&gt;&lt;p&gt;please, please post that follow-up. I'm new to Qt and have just run into this problem. While searching the net, I think your solution seems like the best approach!&lt;br /&gt;&lt;/p&gt;&lt;/dd&gt;&lt;/dl&gt;Who am I to deny a seeker of knowledge? Having used this method in a couple of projects now, I think it is fairly sound and easy to maintain. So here goes.&lt;br /&gt;The main problem with the solution outlined in the earlier post was that it could not handle multiple arguments. On that same post, Ken posted &lt;a href="http://paste.lisp.org/display/87422"&gt;his solution&lt;/a&gt; apparently inspired by mine. His solution also handles multiple arguments but does it by implementing qt_metacall, i.e., mimicking moc. This is probably the most scalable solution and I'll probably give it a second look when I need to do this again. The only problem might be requiring exact matches for types but I am not sure how much of an issue this is for code I have written.&lt;br /&gt;&lt;br /&gt;To review, the problem is that we want to use function objects (Boost Bind, Boost Function, etc) as Qt slots because sometimes it is too much work to create stateful slots.&lt;br /&gt;&lt;br /&gt;My solution looked something like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;struct SignalHandler0 : QObject&lt;br /&gt;{&lt;br /&gt;private:&lt;br /&gt;Q_OBJECT&lt;br /&gt;public:&lt;br /&gt;SignalHandler0(QObject * parent,&lt;br /&gt;              boost::function&lt;void(void)&gt; const &amp;amp; f):&lt;br /&gt; QObject(parent), // parent will delete this object when destructed&lt;br /&gt; m_f(f) {}&lt;br /&gt;&lt;br /&gt;public slots:&lt;br /&gt;void&lt;br /&gt;handleSignal()&lt;br /&gt;{&lt;br /&gt; try&lt;br /&gt; {&lt;br /&gt;   m_f();&lt;br /&gt; }&lt;br /&gt; catch(...)&lt;br /&gt; {&lt;br /&gt;   // Cannot throw exceptions from signals.&lt;br /&gt;   ASSERT_BUG_HERE&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;private:&lt;br /&gt;boost::function&lt;void()&gt;&lt;void(void)&gt; m_f;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;bool&lt;br /&gt;connect(QObject * sender, const char * signal,&lt;br /&gt;     boost::function&lt;void(void)&gt;&lt;void()&gt; const &amp;amp; f)&lt;br /&gt;{&lt;br /&gt;return QObject::connect(sender,signal,&lt;br /&gt;                       // Note: Not a leak as sender will delete the handler when destructed&lt;br /&gt;                       new SignalHandler0(sender,f),SLOT(handleSignal()));&lt;br /&gt;}&lt;br /&gt;&lt;/void()&gt;&lt;/void(void)&gt;&lt;/void(void)&gt;&lt;/void()&gt;&lt;/void(void)&gt;&lt;/pre&gt;To extend it to a single argument, we might do:&lt;br /&gt;&lt;pre&gt;struct SignalHandler1 : QObject&lt;br /&gt;{&lt;br /&gt;private:&lt;br /&gt;Q_OBJECT&lt;br /&gt;public:&lt;br /&gt;SignalHandler1(QObject * parent,&lt;br /&gt;              boost::function&lt;void(a)&gt;&lt;void(qstring&gt; const &amp;amp; f):&lt;br /&gt; QObject(parent), // parent will delete this object when destructed&lt;br /&gt; m_f(f) {}&lt;br /&gt;&lt;br /&gt;public slots:&lt;br /&gt;void&lt;br /&gt;handleSignal(QString const &amp;amp; a)&lt;br /&gt;{&lt;br /&gt; try&lt;br /&gt; {&lt;br /&gt;   m_f(a);&lt;br /&gt; }&lt;br /&gt; catch(...)&lt;br /&gt; {&lt;br /&gt;   // Cannot throw exceptions from signals.&lt;br /&gt;   ASSERT_BUG_HERE&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;private:&lt;br /&gt;boost::function&lt;void(a)&gt;&lt;void(qstring&gt; m_f;&lt;br /&gt;};&lt;br /&gt;&lt;/void(qstring&gt;&lt;/void(a)&gt;&lt;/void(qstring&gt;&lt;/void(a)&gt;&lt;/pre&gt;&lt;br /&gt;That is, create a new class with the right signature. So you might think: well that screams for class templates! Unfortunately, Qt does not support class templates. Doh.&lt;br /&gt;&lt;br /&gt;So basically, we write it out:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;struct SignalHandler : public QObject&lt;br /&gt;{&lt;br /&gt;template&lt;typename&gt;&lt;typename signature=""&gt;&lt;br /&gt;SignalHandler(QObject * parent,boost::function&lt;signature&gt;&lt;signature&gt; f):&lt;br /&gt; QObject(parent),&lt;br /&gt; m_handler(new SignalHandlerImpl&lt;signature&gt;(f))&lt;br /&gt;{}&lt;br /&gt;&lt;br /&gt;struct SignalHandlerBase&lt;br /&gt;{&lt;br /&gt; virtual ~SignalHandlerBase();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;template &lt;typename&gt;&lt;typename signature=""&gt;&lt;br /&gt;struct SignalHandlerImpl&lt;br /&gt;{&lt;br /&gt; SignalHandlerImpl(boost::function&lt;signature&gt;&lt;signature&gt; f):m_f(f){}&lt;br /&gt; boost::function&lt;signature&gt;&lt;signature&gt; f;&lt;br /&gt;}&lt;br /&gt;public slots:&lt;br /&gt;void handleSignal(void);&lt;br /&gt;void handleSignal(QString const &amp;amp;);&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;private:&lt;br /&gt;shared_ptr&lt;signalhandlerbase&gt; m_handler;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;void&lt;br /&gt;SignalHandler::handleSignal(void)&lt;br /&gt;{&lt;br /&gt;typename SignalHandlerImpl&lt;void(void)&gt; type;&lt;br /&gt;type* handler = dynamic_cast&lt;type*&gt;;(m_handler.get());&lt;br /&gt;ASSERT(handler);&lt;br /&gt;handler-&gt;f();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void&lt;br /&gt;SignalHandler::handleSignal(QString const &amp;amp; a)&lt;br /&gt;{&lt;br /&gt;typename SignalHandlerImpl&lt;void(qstring&gt; type;&lt;br /&gt;type* handler = dynamic_cast&lt;type*&gt;(m_handler.get());&lt;br /&gt;ASSERT(handler);&lt;br /&gt;handler-&gt;f(a);&lt;br /&gt;}&lt;br /&gt;&lt;/type*&gt;&lt;/void(qstring&gt;&lt;/type*&gt;&lt;/void(void)&gt;&lt;/signalhandlerbase&gt;&lt;/signature&gt;&lt;/signature&gt;&lt;span style="font-family:Georgia,serif;"&gt;&lt;br /&gt;You can use macros to generate these handlers. You will also need overloaded connect() functions:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;template&lt;typename signature=""&gt;&lt;typename&gt;&lt;br /&gt;QObject*&lt;br /&gt;connect(QObject * sender,&lt;br /&gt;     const char * signal,&lt;br /&gt;     boost::function&lt;signature&gt;&lt;signature&gt; slot);&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;template&lt;&gt;&lt;br /&gt;QObject*&lt;br /&gt;connect&lt;void(void)&gt;&lt;void(void)&gt;(QObject * sender,&lt;br /&gt;                  const char * signal,&lt;br /&gt;                  boost::function&lt;void(void)&gt;&lt;void(void)&gt; slot);&lt;br /&gt;&lt;br /&gt;template&lt;&gt;&lt;br /&gt;QObject*&lt;br /&gt;connect&lt;void(qstring&gt;&lt;void(qstring&gt;(QObject * sender,&lt;br /&gt;                            const char * signal,&lt;br /&gt;                            boost::function&lt;void(qstring&gt;&lt;void(qstring&gt; slot);&lt;br /&gt;&lt;/void(qstring&gt;&lt;/void(qstring&gt;&lt;/void(qstring&gt;&lt;/void(qstring&gt;&lt;/void(void)&gt;&lt;/void(void)&gt;&lt;/void(void)&gt;&lt;/void(void)&gt;&lt;/signature&gt;&lt;/signature&gt;&lt;/typename&gt;&lt;/typename&gt;&lt;/signature&gt;&lt;/signature&gt;&lt;/typename&gt;&lt;/typename&gt;&lt;/signature&gt;&lt;/signature&gt;&lt;/signature&gt;&lt;/typename&gt;&lt;/typename&gt;&lt;/pre&gt;Again, you can use macros.&lt;br /&gt;&lt;br /&gt;I prefer Ken's solution from a technical standpoint. It is a good evolution. The main advantage of his solution is that the amount of code you need to add scales linearly with the number of arguments you need to handle whereas with my solution, they scale with the number of signals and that there are no macros.&lt;br /&gt;&lt;br /&gt;The main advantage of my solution is that it is simpler to understand and maintain, which might be worth the extra code.&lt;br /&gt;&lt;br /&gt;Hope that helps!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-1037310819205501139?l=uint32t.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/O4RpuMQqobI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/O4RpuMQqobI/using-boost-function-with-qt-part-2.html</link><author>sohail@taggedtype.net (Sohail Somani)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2009/10/using-boost-function-with-qt-part-2.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-7075960956301391475</guid><pubDate>Sat, 12 Sep 2009 14:12:00 +0000</pubDate><atom:updated>2009-09-12T07:43:51.124-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ping</category><category domain="http://www.blogger.com/atom/ns#">imnotdead</category><title>Hello, Toronto</title><description>&lt;insert insight="" here=""&gt;&lt;insert&gt;We just completed a cross-country move back to Toronto. Moving is tiring but my wife was very organized. I have to make it up to her somehow. We will still be setting up for a few months, I'm sure.&lt;br /&gt;&lt;/insert&gt;&lt;insert insight="" here=""&gt;&lt;br /&gt;I'm looking for some good meet ups but I can't seem to find any quality ones. The only things I might actually be able to make time for are:&lt;br /&gt;&lt;/insert&gt;&lt;ul&gt;&lt;li&gt;Backyard / amateur astronomy&lt;/li&gt;&lt;li&gt;Business-related&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Software-related (anything to do with 3D graphics would be awesome)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;I've found meet ups for the first 2 but nothing enticing for the software-related. It's all fluff.&lt;br /&gt;&lt;br /&gt;The business-related one I will be attending is &lt;a href="http://entrepreneur.meetup.com/732/"&gt;"Tech Entrepreneurs &amp;amp; Emerging Companies Group"&lt;/a&gt;. There seem to be some serious people there. I look forward to sharing and learning (mostly learning, I'm sure!) from them. This one seems to be a diamond in the rough as most of the business-related meet ups are just advertising for the host.&lt;br /&gt;&lt;br /&gt;Time will tell.&lt;br /&gt;&lt;br /&gt;It's good to be back Toronto. By the way, your garbage bins have become too small.&lt;br /&gt;&lt;br /&gt;&lt;/insert&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-7075960956301391475?l=uint32t.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/wJs6-la-dn4" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/wJs6-la-dn4/hello-toronto.html</link><author>sohail@taggedtype.net (Sohail Somani)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2009/09/hello-toronto.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-3503919203351431488</guid><pubDate>Wed, 19 Aug 2009 05:04:00 +0000</pubDate><atom:updated>2009-08-18T22:17:29.119-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">money</category><title>The best market is one with lots of money</title><description>There are always people who feel that developing plug-ins is not a profitable market. Now while developing a plug-in may not make you as rich as Bill Gates, if there is a sizable market, you will make money.&lt;br /&gt;&lt;br /&gt;So if you are looking for whether your idea makes sense, here is a simple relation to figure it out:&lt;br /&gt;&lt;br /&gt;UnitPrice * NumberOfQualifiedCustomers * ConversionRate &gt;= SomeSpecificFinancialGoal&lt;br /&gt;&lt;br /&gt;If the statement is true, you will make money. If it is not, you will fail.&lt;br /&gt;&lt;br /&gt;I'm pretty sure that I grossly over estimated NumberOfQualifiedCustomers when creating &lt;a href="http://worklogassistant.com"&gt;Worklog Assistant&lt;/a&gt;. How did I over calculate? Simply, the number of total JIRA users who also use JIRA as a timesheet system is quite small (yeah, duh right?) I would not have known this if I did not reach market quickly.&lt;br /&gt;&lt;br /&gt;However, I used very pessimistic values for ConversionRate so maybe that balanced it out because I still reached my financial goals.&lt;br /&gt;&lt;br /&gt;What does this mean for me? It means V2 is going to kick some serious ass. Oh how I wish I could have people to work on this with me, wink wink :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-3503919203351431488?l=uint32t.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/nF1fl5ivYW8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/nF1fl5ivYW8/best-market-is-one-with-lots-of-money.html</link><author>sohail@taggedtype.net (Sohail Somani)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2009/08/best-market-is-one-with-lots-of-money.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-8779086434072392022</guid><pubDate>Thu, 09 Jul 2009 21:12:00 +0000</pubDate><atom:updated>2009-07-21T22:39:34.706-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">dontreadme</category><category domain="http://www.blogger.com/atom/ns#">bzr</category><category domain="http://www.blogger.com/atom/ns#">futurereference</category><category domain="http://www.blogger.com/atom/ns#">afk</category><title>Going AFK with Bazaar</title><description>One thing I've really liked about distributed VC systems is that they handle merging really well. Of course, this is not limited to DVCSs. Subversion and Perforce have very good merging but do not support offline work very well.&lt;br /&gt;&lt;br /&gt;I've been using Bazaar for a little while now for &lt;a href="http://worklogassistant.com/"&gt;my app&lt;/a&gt; because I knew that I would need to be offline every now and then. I just had one of those periods and thought it would be a great chance to see how well AFK mode works with Bazaar.&lt;br /&gt;&lt;br /&gt;This is more for my own future reference rather than for you :-)&lt;br /&gt;&lt;br /&gt;laptop $ rsync -avz -e ssh sohail@desktop:/home/sohail/bzr/ ~/bzr&lt;br /&gt;laptop $ bzr branch ~/bzr/code/master project&lt;br /&gt;laptop $ bzr bind ~/bzr/code/master&lt;br /&gt;&lt;br /&gt;Now I can work offline in the "project" directory and all checkins go to ~/bzr .&lt;br /&gt;&lt;br /&gt;Upon return:&lt;br /&gt;&lt;br /&gt;laptop $ rsync -avz -e ssh ~/bzr/ sohail@desktop:/home/sohail/bzr&lt;br /&gt;&lt;br /&gt;NOTE TRAILING SLASH ON SOURCE DIRECTORY!!!!!1111oneone....&lt;br /&gt;&lt;br /&gt;Note: I think the above is insane. Ideally, I'd just do something like:&lt;br /&gt;&lt;br /&gt;laptop $ bzr checkout bzr+ssh://sohail@desktop/home/sohail/bzr bzr&lt;br /&gt;laptop $ cd bzr&lt;br /&gt;laptop $ bzr work-offline&lt;br /&gt;&lt;br /&gt;Return from afk:&lt;br /&gt;&lt;br /&gt;laptop $ bzr I'm back&lt;br /&gt;&lt;br /&gt;Or something like that.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-8779086434072392022?l=uint32t.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/BlaMV2FcBIM" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/BlaMV2FcBIM/going-afk-with-bazaar.html</link><author>sohail@taggedtype.net (Sohail Somani)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2009/07/going-afk-with-bazaar.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-1554303701121057451</guid><pubDate>Sun, 28 Jun 2009 17:38:00 +0000</pubDate><atom:updated>2009-06-28T11:49:00.064-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">dontreadme</category><category domain="http://www.blogger.com/atom/ns#">soapbox</category><title>Software developer, businessman or problem solver?</title><description>[Warning: Soap box post. I reserve the right to use this blog as such and you reserve the right not to read it! Please let me know if it reads like a Steve Yegge post. You can tell if it is like Steve Yegge if you hate it more and more as you read it. If this is so, please inform me and I will revise the article.]&lt;br /&gt;&lt;br /&gt;As a software developer and still fledgling businessman, I am faced with many problems I need to solve each day. From how to accept payments online to maintenance renewals to how to write as little code as possible to do something useful, sometimes it boggles the mind how much we really have to deal with each day in our profession. Good thing I don't think about it much!&lt;br /&gt;&lt;br /&gt;Some time back, I had lunch with a friend and we got to talking about needed skills for a software developer. This friend is quite possibly one of the smartest guys I know, not because he knows at what point Newton's theories break down or how generational garbage collection works, but because I think he really understands people. So I was very interested when he stated that the most important skill needed is the ability to search out solutions to problems. Not coding or encyclopedic knowledge of C++, .NET, Java, or functional programming but simply, the ability to take a problem, go away and come back with a solution.&lt;br /&gt;&lt;br /&gt;I don't recall whether we talked about it more but it's been sitting in the back of my mind. Ever since then, I've come across situations where this statement jumps to the forefront and I think, "Yeah, this person could be a really good problem solver!" or "Hmm, I really should have tried to put on my problem solving hat here."&lt;br /&gt;&lt;br /&gt;Is software development or growing a business actually problem solving? Maybe the answer is obvious to you but I have never thought about it consciously. To answer that question, I have to think about what a problem is. To me, a problem is an obstacle in the way to achieving a goal.&lt;br /&gt;&lt;br /&gt;A goal one should probably have when starting a software business is to get paid. Now, unless I am experienced at achieving this goal, I will have no idea where to start. So one of two things will happen:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I will give up because I don't know the answer already&lt;br /&gt;&lt;/li&gt;&lt;li&gt;I will start to look for the answer&lt;/li&gt;&lt;/ul&gt;I know, it's obvious right? Every time there is a bug I don't know how to fix, or a feature I don't know how to implement, I am faced with these two choices. I'd like to think that I never choose the first option, but I'd be lying to myself.&lt;br /&gt;&lt;br /&gt;Fixing bugs is something I'm generally good at. I've fixed some whoppers (mmm whopper) in the past, self-inflicted or otherwise. So I rather like the example above of choosing a way to get paid because I've never done it before. I've no idea how it works. I'm deathly afraid to screw up. But I've bought lots of software online. I know people who sell software online. So I start by asking people I know or people I trust. I recall situations in which I &lt;span style="font-weight: bold; font-style: italic;"&gt;hated&lt;/span&gt; the purchasing process and situations in which it was the best process ever. I go back to these online stores and find out what I liked or hated. I make a list and check it twice.&lt;br /&gt;&lt;br /&gt;With all this research, I have not written a line of code, yet I now have a very good idea of what a good solution should look like. Problem solved? Not quite. Now I have to decide whether to buy or build. I've already decided ahead of time that writing it myself is not really something I'm interested in but to ensure I understand what is going on, I research this topic as well. Indeed, it is not worth it. Eventually, I settle on a reseller and move on to achieving the next goal.&lt;br /&gt;&lt;br /&gt;There is nothing magical about solving the problem above. In fact, it is almost mechanical. But the key point is the decision that was taken at the first point. That is, the decision to actually solve the problem.&lt;br /&gt;&lt;br /&gt;I am fairly convinced that software development as well as growing a fledgling business are very much problem-centric. They are filled with goals along with many obstacles to achieving them. At each obstacle, you have two choices: to give up or keep going. We need to keep going. This does not mean being stubborn and trying the same thing over and over again. This often means trial and error, hypothesizing and experimentation (Carl Sagan might like that!) Above all, don't give up and say it is impossible.&lt;br /&gt;&lt;br /&gt;Anyway, just thought I'd put the thought in your heads since it's been in mine for a while. I think I'm going to try calling myself Chief Problem Solver from now on.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-1554303701121057451?l=uint32t.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/niyjU3MP0qM" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/niyjU3MP0qM/software-developer-businessman-or.html</link><author>sohail@taggedtype.net (Sohail Somani)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2009/06/software-developer-businessman-or.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-1161318549264845423</guid><pubDate>Mon, 08 Jun 2009 23:37:00 +0000</pubDate><atom:updated>2009-06-08T16:40:29.128-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">vancpp</category><title>VanCPP June meeting</title><description>If you are in Vancouver and interested in programming (who isn't?!) you might want to make your way to the VanCPP meeting in June. The announcement is below:&lt;br /&gt;      &lt;!--~-|**|PrettyHtmlEnd|**|-~--&gt;       &lt;p&gt;Our June 2009 meeting will be held on Thursday, June 18. Please note the &lt;a href="http://workspacecafe.ca/"&gt;new venue&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Topic: &lt;span style="color:#407f00;"&gt;&lt;b&gt;&lt;span style="font-size:100%;"&gt;Concurrent Programming in the D Programming Language&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Presented by &lt;strong&gt;Walter Bright&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;&lt;b&gt;Abstract&lt;/b&gt;: Many-core concurrent programming offers exciting and compelling advantages. The single core, single thread programming model is assumed by imperative programming languages. This model offers sequential consistency as its fundamental characteristic.&lt;wbr&gt;Because many-core systems use layered cache memory systems,sequential consistency is not guaranteed among threads.Because imperative programming languages allow implicit sharing of data between threads, many misguided idioms and optimizations are possible that erroneously assume sequential consistency.&lt;wbr&gt;One example of this is the double checked locking optimization.&lt;wbr&gt;The pernicious nature of these sorts of bugs is they defy programmers' natural intuition about how programs behave,they are not statically detectable, and there is no way to reliably test a program to rule out the existence of such bugs.A program may appear to work, but have problems appear years later, fail when ported to a different platform, and such problems may be extremely hard to reproduce and track down.In essence, the correctness of the program relies entirely on the expertise and care of the programmer.This is not an acceptable situation for developers of programs that require high reliability.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;The &lt;a href="http://www.digitalmars.com/d/"&gt;D programming language&lt;/a&gt; is an imperative programming language with an innovative type system that prevents implicit sharing and also fosters a complete, integrated pure functional subset. It is possible to statically verify that D programs do not have sequential consistency bugs. The double checked locking optimization bug is not possible. Type support for shared data and immutable data, as well as pure functions, means that mutating data interactions between threads can occur only under carefully controlled conditions.This dramatically reduces the problem space for concurrency bugs from the whole of the source code to a small subset of it, making it a much more tractable problem.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;&lt;strong&gt;Speaker bio:&lt;/strong&gt; &lt;a href="http://www.walterbright.com/"&gt;Walter Bright&lt;/a&gt; graduated from Caltech in 1979 with a degree in mechanical engineering. He worked for Boeing for three years on the development of the 757 stabilizer trim system. He then switched to writing software, in particular compilers, and has been writing them ever since.&lt;/span&gt;&lt;/p&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;The meeting will be held at:&lt;br /&gt;&lt;strong&gt;&lt;a href="http://workspacecafe.ca/"&gt;Workspace&lt;/a&gt;&lt;/strong&gt;&lt;br /&gt;&lt;a href="http://maps.google.com/maps?f=q&amp;amp;source=s_q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=21+water+street,+vancouver,+canada&amp;amp;ie=UTF8&amp;amp;z=16&amp;amp;iwloc=A"&gt;21 Water Street&lt;/a&gt;&lt;br /&gt;Vancouver, BC&lt;br /&gt;V6B 1A&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Regards,&lt;/p&gt;&lt;p&gt;Vladan Vidakovic&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-1161318549264845423?l=uint32t.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/eqHpk-lHigY" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/eqHpk-lHigY/vancpp-june-meeting.html</link><author>sohail@taggedtype.net (Sohail Somani)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2009/06/vancpp-june-meeting.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-7862667418648087530</guid><pubDate>Fri, 08 May 2009 01:26:00 +0000</pubDate><atom:updated>2009-05-08T11:21:10.159-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">c++0x</category><category domain="http://www.blogger.com/atom/ns#">lambda</category><category domain="http://www.blogger.com/atom/ns#">wla</category><title>Using C++0x lambda to replace Boost Bind in C++03 code</title><description>[Note: This post looks ugly under Internet Explorer. If you want to tell me how to fix my CSS, that would be much appreciated]&lt;br /&gt;[Note: This post was written using the Intel C++ compiler with -std=c++0x.]&lt;br /&gt;&lt;br /&gt;As some of you know, I work on &lt;a href="http://worklogassistant.com/"&gt;Worklog Assistant&lt;/a&gt; which is written using C++/Qt.&lt;br /&gt;&lt;br /&gt;One thing that I've made very good use of is a slightly modified version of the code in an earlier post titled &lt;a href="http://uint32t.blogspot.com/2008/11/using-boost-bind-and-boost-function.html"&gt;"Using Boost Bind and Boost Function with Qt"&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;As an example, consider the following code from the above app which creates a popup menu to toggle the visibility of table columns. This is done by creating a "toggle" action for each column header that... toggles the visibility. It might help to think how this action would be created in plain Qt (hint: it would be painful.) It would certainly not have the locality it does now.&lt;br /&gt;&lt;pre class="cxx"&gt;&lt;span class="type"&gt;voi&lt;/span&gt;&lt;span class="type"&gt;d&lt;/span&gt;&lt;br /&gt;&lt;span class="function-name"&gt;showColumnHeaderContextMenu&lt;/span&gt;(&lt;span class="constant"&gt;ssci&lt;/span&gt;::&lt;span class="type"&gt;CustomTableView&lt;/span&gt; * &lt;span class="variable-name"&gt;self&lt;/span&gt;,&lt;span class="keyword"&gt;const&lt;/span&gt; &lt;span class="type"&gt;QPoint&lt;/span&gt; &amp;amp; &lt;span class="variable-name"&gt;pos&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;&lt;span class="type"&gt;QMen&lt;/span&gt;&lt;span class="type"&gt;u&lt;/span&gt; &lt;span class="function-name"&gt;columns&lt;/span&gt;(&lt;span class="constant"&gt;ssci&lt;/span&gt;::&lt;span class="constant"&gt;CustomTableView&lt;/span&gt;::tr(&lt;span class="string"&gt;"Visible Columns"&lt;/span&gt;));&lt;br /&gt;columns.setIcon(QIcon(&lt;span class="constant"&gt;QString&lt;/span&gt;::fromLatin1(&lt;span class="string"&gt;":/ui/icons/grid.png"&lt;/span&gt;)));&lt;br /&gt;&lt;br /&gt;QHeaderView * headers(self-&amp;gt;horizontalHeader());&lt;br /&gt;&lt;br /&gt;&lt;span class="constant"&gt;std&lt;/span&gt;::&lt;span class="type"&gt;vector&lt;/span&gt;&amp;lt;&lt;span class="constant"&gt;std&lt;/span&gt;::&lt;span class="type"&gt;pair&lt;/span&gt;&amp;lt;QString,&lt;span class="type"&gt;int&lt;/span&gt;&amp;gt; &amp;gt; &lt;span class="variable-name"&gt;sorted_columns&lt;/span&gt;;&lt;br /&gt;getSortedColumns(self-&amp;gt;model(),headers,sorted_columns);&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;for&lt;/span&gt;(&lt;span class="type"&gt;in&lt;/span&gt;&lt;span class="type"&gt;t&lt;/span&gt; &lt;span class="variable-name"&gt;ii&lt;/span&gt; = 0; ii &amp;lt; headers-&amp;gt;count(); ++ii)&lt;br /&gt;{&lt;br /&gt;&lt;span class="type"&gt;QActio&lt;/span&gt;&lt;span class="type"&gt;n&lt;/span&gt; * &lt;span class="variable-name"&gt;action&lt;/span&gt; =&lt;br /&gt; &lt;span class="keyword"&gt;new&lt;/span&gt; &lt;span class="type"&gt;QAction&lt;/span&gt;(sorted_columns[ii].first,&lt;br /&gt;             &amp;amp;columns);&lt;br /&gt;&lt;br /&gt;&lt;span class="type"&gt;boo&lt;/span&gt;&lt;span class="type"&gt;l&lt;/span&gt; &lt;span class="variable-name"&gt;is_hidden&lt;/span&gt; = headers-&amp;gt;isSectionHidden(sorted_columns[ii].second);&lt;br /&gt;&lt;br /&gt;action-&amp;gt;setCheckable(&lt;span class="constant"&gt;true&lt;/span&gt;);&lt;br /&gt;action-&amp;gt;setChecked(&lt;span class="negation-char"&gt;!&lt;/span&gt;is_hidden);&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;using&lt;/span&gt; &lt;span class="constant"&gt;boost&lt;/span&gt;::&lt;span class="type"&gt;bin&lt;/span&gt;&lt;span class="type"&gt;d&lt;/span&gt;;&lt;br /&gt;&lt;span class="keyword"&gt;using&lt;/span&gt; &lt;span class="constant"&gt;boost&lt;/span&gt;::&lt;span class="type"&gt;functio&lt;/span&gt;&lt;span class="type"&gt;n&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="type"&gt;function&lt;/span&gt;&amp;lt;&lt;span class="type"&gt;void&lt;/span&gt;()&amp;gt; &lt;span class="variable-name"&gt;toggle&lt;/span&gt; =&lt;br /&gt; bind(&amp;amp;&lt;span class="constant"&gt;QHeaderView&lt;/span&gt;::setSectionHidden,headers,&lt;br /&gt;      sorted_columns[ii].second,&lt;span class="negation-char"&gt;!&lt;/span&gt;is_hidden);&lt;br /&gt;&lt;br /&gt;&lt;span class="constant"&gt;ssci&lt;/span&gt;::connect(action,SIGNAL(triggered()),&lt;br /&gt;             toggle);&lt;br /&gt;&lt;br /&gt;columns.addAction(action);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="type"&gt;QMen&lt;/span&gt;&lt;span class="type"&gt;u&lt;/span&gt; &lt;span class="variable-name"&gt;menu&lt;/span&gt;;&lt;br /&gt;menu.addMenu(&amp;amp;columns);&lt;br /&gt;&lt;br /&gt;menu.exec(self-&amp;gt;mapToGlobal(pos));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Of particular interest is the code in the for loop which sets up the actions:&lt;br /&gt;&lt;pre class="cxx"&gt;    &lt;span class="type"&gt;function&lt;/span&gt;&amp;lt;&lt;span class="type"&gt;void&lt;/span&gt;()&amp;gt; &lt;span class="variable-name"&gt;toggle&lt;/span&gt; =&lt;br /&gt; bind(&amp;amp;&lt;span class="constant"&gt;QHeaderView&lt;/span&gt;::setSectionHidden,headers,&lt;br /&gt;      sorted_columns[ii].second,&lt;span class="negation-char"&gt;!&lt;/span&gt;is_hidden);&lt;br /&gt;&lt;br /&gt; &lt;span class="constant"&gt;ssci&lt;/span&gt;::connect(action,SIGNAL(triggered()),&lt;br /&gt;               toggle);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This creates a function object on the fly which hides the selected column using code from the above linked post. To do this in plain Qt is a gigantic pain. &lt;a href="http://libqxt.org/"&gt;LibQxt&lt;/a&gt; has a solution as well but mine is much better!&lt;br /&gt;&lt;br /&gt;Anyway, the point is that you might find a lot of code using bind and function in an app like this. Binding member function pointers, member data pointers and function pointers is fairly normal and is really the only way to maintain sanity and reduce boiler plate. Nested binds are also used where appropriate.&lt;br /&gt;&lt;br /&gt;Boost Bind is a way to create closures, or at least as close as you can get in C++ to true closures. Therefore it is natural to try and replace some uses of Boost Bind with C++0x lambda. There is good coverage of how C++0x lambda works &lt;a href="http://blogs.msdn.com/vcblog/archive/2008/10/28/lambdas-auto-and-static-assert-c-0x-features-in-vc10-part-1.aspx"&gt;here&lt;/a&gt; so I won't repeat the same information. However, I will cover the cases of bind I could convert and (horrifically) the cases I couldn't!&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Using automatic variables&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Consider the following code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="cxx"&gt;&lt;span class="keyword"&gt;const&lt;/span&gt; &lt;span class="type"&gt;in&lt;/span&gt;&lt;span class="type"&gt;t&lt;/span&gt; &lt;span class="variable-name"&gt;LICENSING_TAB_INDEX&lt;/span&gt; = 1;&lt;br /&gt;&lt;br /&gt;&lt;span class="constant"&gt;ssci&lt;/span&gt;::connect(lblImportNewLicense,SIGNAL(linkActivated(QString &lt;span class="keyword"&gt;const&lt;/span&gt; &amp;amp;)),&lt;br /&gt;             &lt;span class="constant"&gt;boost&lt;/span&gt;::&lt;span class="type"&gt;function&lt;/span&gt;&amp;lt;&lt;span class="type"&gt;void&lt;/span&gt;()&amp;gt;(&lt;br /&gt;               &lt;span class="constant"&gt;boost&lt;/span&gt;::&lt;span class="variable-name"&gt;bind&lt;/span&gt;(&amp;amp;&lt;span class="constant"&gt;QTabWidget&lt;/span&gt;::setCurrentIndex,&lt;br /&gt;                           tabWidget,&lt;br /&gt;                           LICENSING_TAB_INDEX)&lt;br /&gt;               )&lt;br /&gt; );&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The above function call sets things up so that when a link is clicked in the interface, the &lt;tt&gt;LICENSING_TAB_INDEX&lt;/tt&gt; tab is selected in the configuration.&lt;br /&gt;&lt;br /&gt;One thing Boost Bind does is that it stores all bound arguments by value. That means &lt;tt&gt;&amp;amp;QTabWidget::setCurrentIndex&lt;/tt&gt;, &lt;tt&gt;tabWidget&lt;/tt&gt; and &lt;tt&gt;LICENSING_TAB_INDEX&lt;/tt&gt; are all stored by value. C++0x lambda calls this capturing. This can be done using implicit capture (by parsing the lambda body) or by you. &lt;ss&gt;By default, C++0x lambda captures variables by reference&lt;/ss&gt;. It is potentially buggy to capture function-local variables by reference automatically. Therefore, the above code translated to C++0x lambda is:&lt;br /&gt;&lt;pre class="cxx"&gt;[=]()&lt;br /&gt;{ tabWidget-&amp;gt;setCurrentIndex(LICENSING_TAB_INDEX); }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The first element of a lambda-introducer (the []) can be a capture default which can be one of = or &amp;amp;. The capture default tells the compiler how to capture those variables that are implicitly captured. The assignment is supposed to make you think of copy assignment and the &amp;amp; is supposed to make you think of reference to. So in the above case, to get the exact same behaviour as the bind, we need to intentionally copy all variables by value.&lt;br /&gt;&lt;br /&gt;Great! Not so bad :-)&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;A simpler example... Or is it?&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Consider the following code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="cxx"&gt;&lt;span class="constant"&gt;ssci&lt;/span&gt;::connect(clearSelectedRole,SIGNAL(clicked()),&lt;br /&gt;             &lt;span class="constant"&gt;boost&lt;/span&gt;::&lt;span class="type"&gt;function&lt;/span&gt;&amp;lt;&lt;span class="type"&gt;void&lt;/span&gt;()&amp;gt;(&lt;br /&gt;               &lt;span class="constant"&gt;boost&lt;/span&gt;::&lt;span class="variable-name"&gt;bind&lt;/span&gt;(&lt;br /&gt;                 &amp;amp;&lt;span class="constant"&gt;QComboBox&lt;/span&gt;::setCurrentIndex,&lt;br /&gt;                 projectRoles,&lt;br /&gt;                 -1)&lt;br /&gt;               )&lt;br /&gt; );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This code sets things up so that when the &lt;tt&gt;clearSelectedRole&lt;/tt&gt; button is clicked, the corresponding &lt;tt&gt;QComboBox&lt;/tt&gt; has an invalid index.&lt;br /&gt;&lt;br /&gt;The C++0x version of this is really straightforward:&lt;br /&gt;&lt;br /&gt;&lt;pre class="cxx"&gt;&lt;span class="constant"&gt;ssci&lt;/span&gt;::connect(clearSelectedRole,SIGNAL(clicked()),&lt;br /&gt;             &lt;span class="constant"&gt;boost&lt;/span&gt;::&lt;span class="type"&gt;function&lt;/span&gt;&amp;lt;&lt;span class="type"&gt;void&lt;/span&gt;()&amp;gt;(&lt;br /&gt;               [&amp;](){projectRoles-&amp;gt;setCurrentIndex(-1);}&lt;br /&gt;               )&lt;br /&gt; );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In this case, the pointer object (not the value) &lt;tt&gt;projectRoles&lt;/tt&gt; is captured by reference. This is not an issue because the pointer object is guaranteed to outlive the closure. Now you know why closures and garbage collection go together :-)&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Verbosity or Why I wish C++0x used polymorphic lambdas&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Consider the following code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="cxx"&gt;&lt;span class="keyword"&gt;static&lt;/span&gt;&lt;br /&gt;&lt;span class="type"&gt;voi&lt;/span&gt;&lt;span class="type"&gt;d&lt;/span&gt;&lt;br /&gt;&lt;span class="function-name"&gt;updateThreadSetup&lt;/span&gt;(&lt;span class="type"&gt;QObject&lt;/span&gt; * &lt;span class="variable-name"&gt;parent&lt;/span&gt;,&lt;span class="constant"&gt;ssci&lt;/span&gt;::&lt;span class="type"&gt;MainWindow&lt;/span&gt; * &lt;span class="variable-name"&gt;self&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;m_checkForUpdatesThread(&lt;span class="constant"&gt;boost&lt;/span&gt;::bind(updateThreadSetup,_1,&amp;amp;parent))&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The bound function in this case is an object that calls the function updateThreadSetup with a to-be-determined value for the first parameter and a fixed value for the second parameter.&lt;br /&gt;&lt;br /&gt;The C++0x version of this is horrible:&lt;br /&gt;&lt;pre class="cxx"&gt;m_checkForUpdatesThread([&amp;amp;parent](QObject * obj){updateThreadSetup(obj,&amp;amp;parent);});&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;First, since &lt;tt&gt;parent&lt;/tt&gt; is a local variable (was passed into the function), you can't implicitly capture it. So you have to explicitly capture it. In this case, we want to capture it by reference, hence &lt;tt&gt;[&amp;amp;parent]&lt;/tt&gt; in the lambda-introducer. Then, since this thread setup function is passed in a &lt;tt&gt;QObject*&lt;/tt&gt; we have to tell the compiler to accept this argument. Apparently it isn't smart enough. Ask someone why it is this way, you'll hear some hand waving about the callable concept. Whatever.&lt;br /&gt;&lt;br /&gt;That is some ugly code.&lt;br /&gt;&lt;br /&gt;Anyway...&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;What you cannot convert without making your code super ugly&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Consider the following simple code:&lt;br /&gt;&lt;pre class="cxx"&gt;&lt;span class="type"&gt;vector&lt;/span&gt;&amp;lt;&lt;span class="type"&gt;int&lt;/span&gt;&amp;gt; &lt;span class="variable-name"&gt;d&lt;/span&gt; = {1,2,3,4,5};&lt;br /&gt;vector&amp;lt;&lt;span class="type"&gt;function&lt;/span&gt;&amp;lt;&lt;span class="type"&gt;int&lt;/span&gt;()&amp;gt;&amp;gt; &lt;span class="variable-name"&gt;funcs&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;for&lt;/span&gt;(&lt;span class="constant"&gt;vector&lt;/span&gt;&amp;lt;&lt;span class="type"&gt;int&lt;/span&gt;&amp;gt;::&lt;span class="type"&gt;iterato&lt;/span&gt;&lt;span class="type"&gt;r&lt;/span&gt; &lt;span class="variable-name"&gt;it&lt;/span&gt; = d.begin(), &lt;span class="variable-name"&gt;end&lt;/span&gt; = d.end();&lt;br /&gt;   it != end;&lt;br /&gt;   ++it)&lt;br /&gt;{&lt;br /&gt; funcs.push_back(&lt;span class="constant"&gt;boost&lt;/span&gt;::bind(add5,*it));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This creates a vector of function objects that presumably add 5 to their bound argument and return the result.&lt;br /&gt;&lt;br /&gt;Here is the equivalent in C++0x lambda:&lt;br /&gt;&lt;br /&gt;&lt;pre class="cxx"&gt;&lt;span class="type"&gt;vector&lt;/span&gt;&amp;lt;&lt;span class="type"&gt;int&lt;/span&gt;&amp;gt; &lt;span class="variable-name"&gt;d&lt;/span&gt; = {1,2,3,4,5};&lt;br /&gt;vector&amp;lt;function&amp;lt;&lt;span class="type"&gt;int&lt;/span&gt;()&amp;gt;&amp;gt; funcs;&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;for&lt;/span&gt;(&lt;span class="constant"&gt;vector&lt;/span&gt;&amp;lt;&lt;span class="type"&gt;int&lt;/span&gt;&amp;gt;::&lt;span class="type"&gt;iterato&lt;/span&gt;&lt;span class="type"&gt;r&lt;/span&gt; &lt;span class="variable-name"&gt;it&lt;/span&gt; = d.begin(), &lt;span class="variable-name"&gt;end&lt;/span&gt; = d.end();&lt;br /&gt;   it != end;&lt;br /&gt;   ++it)&lt;br /&gt;{&lt;br /&gt; &lt;span class="type"&gt;in&lt;/span&gt;&lt;span class="type"&gt;t&lt;/span&gt; &amp;amp;&lt;span class="variable-name"&gt;i&lt;/span&gt; = *it; &lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/ &lt;/span&gt;&lt;span class="comment"&gt;WTF?&lt;br /&gt;&lt;/span&gt;  funcs.push_back([i](){add5(i);});&lt;span class="comment-delimiter"&gt;//&lt;/span&gt;&lt;span class="comment"&gt;THIS IS REDUNDANT. REDUNDANT.&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Naively, one might have done:&lt;br /&gt;&lt;br /&gt;&lt;pre class="cxx"&gt;funcs.push_back([it](){add5(*it);});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;in the loop. But this is a bug waiting to happen. Add the following line right after the for loop:&lt;br /&gt;&lt;pre class="cxx"&gt;d.push_back(0)&lt;/pre&gt;&lt;br /&gt;Now all those iterators that are captured by value can be invalidated! YAY! The only way to avoid this issue is to manually extract the value referenced by the iterator and pass that into the closure which is what I did in my translation.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;This exercise showed me that C++0x lambda is of some interest to me. I'd really like to get rid of the verbosity (I know, too late!) A couple of things would make this the perfect lambda for me:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Polymorphic lambdas (or at least let me specify auto for the arguments)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;An easy way to capture computed values (the *it bug above)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;I don't know how these problems would be solved, or whether they could be but until they are, I think there is still a future for function binding ala Boost Bind which is fine by me!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-7862667418648087530?l=uint32t.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/16jDb5QHaUo" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/16jDb5QHaUo/using-c0x-lambda-to-replace-boost-bind.html</link><author>sohail@taggedtype.net (Sohail Somani)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">7</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2009/05/using-c0x-lambda-to-replace-boost-bind.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-6821142006276838244</guid><pubDate>Mon, 04 May 2009 04:23:00 +0000</pubDate><atom:updated>2009-05-03T21:31:46.297-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">boostcon</category><title>BoostCon 2009</title><description>&lt;a href="http://boostcon.com"&gt;BoostCon&lt;/a&gt; starts tomorrow.&lt;br /&gt;&lt;br /&gt;I went to the first and second Boost conferences. The first as an attendee, the second as a speaker. I was blown away by the quality of the talks, particularly the author's corner series of talks. I think that if the organizers are smart about it, this can be one of the best conferences. For me, it is already on par with conferences like SD West for quality and relevance.&lt;br /&gt;&lt;br /&gt;I am extremely disappointed that I could not make it this year due to my schedule being way too busy. I hope that some of you reading this have been able to schedule better than me and go to BoostCon.&lt;br /&gt;&lt;br /&gt;If you are attending, please ask at least one very difficult on-topic question in each of your talks for me.&lt;br /&gt;&lt;br /&gt;Also, ask &lt;a href="http://www.boost.org/users/people/joel_de_guzman.html"&gt;Joel de Guzman&lt;/a&gt; about Boost.GUI. Apparently he's got something cooking (you didn't hear it from me!)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-6821142006276838244?l=uint32t.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/e2ubvd9fevA" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/e2ubvd9fevA/boostcon-2009.html</link><author>sohail@taggedtype.net (Sohail Somani)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2009/05/boostcon-2009.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-7231893924325400141</guid><pubDate>Thu, 19 Mar 2009 22:51:00 +0000</pubDate><atom:updated>2009-03-19T15:56:34.894-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">lisp</category><category domain="http://www.blogger.com/atom/ns#">qt</category><title>A seemingly complete Qt API for CL</title><description>Just came across this library called &lt;a href="http://common-lisp.net/project/commonqt/"&gt;CommonQT&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;It is more complete than the API I developed earlier. It is also using the KDE Smoke libraries which make it damn easy to create the API on the fly.&lt;br /&gt;&lt;br /&gt;Very exciting.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-7231893924325400141?l=uint32t.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/GwLMZ9jn9Ew" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/GwLMZ9jn9Ew/seemingly-complete-qt-api-for-cl.html</link><author>sohail@taggedtype.net (Sohail Somani)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2009/03/seemingly-complete-qt-api-for-cl.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-2870197845099753333</guid><pubDate>Sun, 15 Feb 2009 22:01:00 +0000</pubDate><atom:updated>2009-02-15T14:05:55.524-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">broken</category><category domain="http://www.blogger.com/atom/ns#">nvidia</category><category domain="http://www.blogger.com/atom/ns#">ubuntu</category><title>Latest NVIDIA drivers, Ubuntu Edgy</title><description>NVIDIA drivers not loading after the latest Ubuntu update? Low resolution mode?&lt;br /&gt;&lt;br /&gt;They used to work didn't they?&lt;br /&gt;&lt;br /&gt;Before you start uninstalling Ubuntu packages and installing the official NVIDIA drivers, throwing your hands up and generally having a bad day, try this:&lt;br /&gt;&lt;br /&gt;(as root): echo nvidia &gt;&gt; /etc/modules&lt;br /&gt;&lt;br /&gt;Reboot. Should work now.&lt;br /&gt;&lt;br /&gt;For some reason, you need to explicitly load the module with the latest nvidia packages (I'm using nvidia-glx-new)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-2870197845099753333?l=uint32t.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/EtTSEzvp1Vg" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/EtTSEzvp1Vg/latest-nvidia-drivers-ubuntu-edgy.html</link><author>sohail@taggedtype.net (Sohail Somani)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2009/02/latest-nvidia-drivers-ubuntu-edgy.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-3395965405933753573</guid><pubDate>Wed, 14 Jan 2009 08:51:00 +0000</pubDate><atom:updated>2009-01-14T00:52:18.794-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">qt</category><title>Qt goes LGPL!</title><description>http://www.qtsoftware.com/about/news/lgpl-license-option-added-to-qt&lt;br /&gt;&lt;br /&gt;Now that's awesome.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-3395965405933753573?l=uint32t.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/Y3CEnJsRUIk" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/Y3CEnJsRUIk/qt-goes-lgpl.html</link><author>sohail@taggedtype.net (Sohail Somani)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2009/01/qt-goes-lgpl.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-4183447400014795010</guid><pubDate>Wed, 26 Nov 2008 19:03:00 +0000</pubDate><atom:updated>2008-11-26T16:05:07.155-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">c++</category><category domain="http://www.blogger.com/atom/ns#">qt</category><title>Using Boost Bind and Boost Function with Qt</title><description>One very, very, very annoying feature of Qt in C++ is how very difficult it is to create bespoke slots.&lt;br /&gt;&lt;br /&gt;With &lt;a href="http://gtkmm.org"&gt;gtkmm&lt;/a&gt;, you can more or less get away with using &lt;a href="http://www.boost.org/doc/libs/1_37_0/libs/bind/bind.html"&gt;boost::bind&lt;/a&gt; so long as the bind results in a 0-ary function (otherwise the signal/slots library for gtkmm is not compatible.)&lt;br /&gt;&lt;br /&gt;With Qt, you have to write a new member function, or heaven forbid, a new class. This is too much typing for me. Ideally, what I would like to do is something like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;connect(some_button,SIGNAL(clicked()),&lt;br /&gt;        boost::bind(&amp;Foo::bar,something,else,entirely));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Doing this with bare Qt, I'd have to:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt; &lt;li&gt;Create a new slot function: &lt;tt&gt;Foo::bar_special_case&lt;/tt&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Add member variables for the variables &lt;tt&gt;else,entirely&lt;/tt&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Finally use it as: connect(some_button,SIGNAL(clicked(),something,SLOT(bar_special_case()))&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;After doing this for the 100 billionth time, I realized that there should be a better way to do this. After months of investigation, I have discovered that there is no better way to do this.&lt;br /&gt;&lt;br /&gt;Just kidding.&lt;br /&gt;&lt;br /&gt;The idea is to create a slot handler that accepts &lt;a href="http://www.boost.org/doc/libs/1_37_0/doc/html/function.html"&gt;boost::function&lt;/a&gt; types:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;struct SignalHandler0 : QObject&lt;br /&gt;{&lt;br /&gt;private:&lt;br /&gt;  Q_OBJECT&lt;br /&gt;public:&lt;br /&gt;  SignalHandler0(QObject * parent,&lt;br /&gt;                 boost::function&amp;lt;void(void)&amp;gt; const &amp; f):&lt;br /&gt;    QObject(parent), // parent will delete this object when destructed&lt;br /&gt;    m_f(f) {}&lt;br /&gt;&lt;br /&gt;public slots:&lt;br /&gt;  void&lt;br /&gt;  handleSignal()&lt;br /&gt;  {&lt;br /&gt;    try&lt;br /&gt;    { &lt;br /&gt;      m_f();&lt;br /&gt;    }&lt;br /&gt;    catch(...)&lt;br /&gt;    {&lt;br /&gt;      // Cannot throw exceptions from signals.&lt;br /&gt;      ASSERT_BUG_HERE&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;private:&lt;br /&gt;  boost::function&amp;lt;void(void)&amp;gt; m_f;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If I were to use this class directly, I would write:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;connect(button,SIGNAL(clicked()),&lt;br /&gt;        // Note: Not a leak as button will delete the handler when destructed&lt;br /&gt;        new SignalHandler0(button,boost::bind(&amp;Foo::bar,something,else,entirely)),&lt;br /&gt;        SLOT(handleSignal()));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That's pretty much it. Of course, this is a bit too verbose so I'd write a free function:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;bool&lt;br /&gt;connect(QObject * sender, const char * signal,&lt;br /&gt;        boost::function&lt;void(void)&gt; const &amp; f)&lt;br /&gt;{&lt;br /&gt;  return QObject::connect(sender,signal,&lt;br /&gt;                          // Note: Not a leak as sender will delete the handler when destructed&lt;br /&gt;                          new SignalHandler0(sender,f),SLOT(handleSignal()));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And use it as:&lt;tt&gt;::connect(button,SLOT(clicked()),boost::bind(&amp;Foo::bar,something,else,entirely))&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;The obvious problem with this approach is if you add any overload of the free function + bind and you are in for some fun. I prototyped a solution for this based on the &lt;a href="http://www.boost.org/doc/libs/1_37_0/libs/function_types/doc/html/index.html"&gt;Boost.FunctionTypes&lt;/a&gt; library but at the moment, I don't need this (i.e., I am happy with 0-ary bind)&lt;br /&gt;&lt;br /&gt;Another thing... Why does the aforementioned function types library not handle boost function and boost bind?&lt;br /&gt;&lt;br /&gt;Odd.&lt;br /&gt;&lt;br /&gt;PS: I'm not dead. I just smell funny.&lt;br /&gt;PPS: Sorry for so long in between posts, I've been very busy (the good kind!)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-4183447400014795010?l=uint32t.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/qeIN2aCVneg" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/qeIN2aCVneg/using-boost-bind-and-boost-function.html</link><author>sohail@taggedtype.net (Sohail Somani)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2008/11/using-boost-bind-and-boost-function.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-4867723890538613194</guid><pubDate>Sun, 05 Oct 2008 19:17:00 +0000</pubDate><atom:updated>2008-10-05T12:25:47.078-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">c++</category><category domain="http://www.blogger.com/atom/ns#">boost</category><title>Everything you ever wanted to know about tr1::function but were too afraid to actually know</title><description>Working title for a talk I'm giving October 16 at the &lt;a href="http://vancpp.org/"&gt;Vancouver C++ Users Group&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I find three patterns of usage around Boost Function/Bind:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt; &lt;li&gt;The right way&lt;/li&gt;&lt;br /&gt; &lt;li&gt;The wrong way&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Running away&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;My goal for this talk: attendees should no longer be in the dark about how Boost Function/Bind (and by extension, tr1 function/bind) work. If you are reading this blog, coming to this talk, not the author of this post and you have some things you'd like to hear covered, please feel free to leave some comments. I'm pretty sure the intersection of all those groups of people is the empty set but it never hurts to ask!&lt;br /&gt;&lt;br /&gt;Heckling must be reserved for the end.&lt;br /&gt;&lt;br /&gt;PS: Regular posting will resume some point soon!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-4867723890538613194?l=uint32t.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/pRjtR92evjQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/pRjtR92evjQ/everything-you-ever-wanted-to-know.html</link><author>sohail@taggedtype.net (Sohail Somani)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2008/10/everything-you-ever-wanted-to-know.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-4344157724641342161</guid><pubDate>Thu, 31 Jul 2008 15:06:00 +0000</pubDate><atom:updated>2008-08-02T07:41:42.927-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">lisp</category><category domain="http://www.blogger.com/atom/ns#">qt</category><title>Qt/Lisp: more progress</title><description>I've replaced the unsightly &lt;tt&gt;(make-instance 'qstring :ch "Foo")&lt;/tt&gt; with a reader macro: &lt;tt&gt;#q"Foo"&lt;/tt&gt;. Ideally we'd use &lt;tt&gt;cl:string&lt;/tt&gt; and &lt;tt&gt;qstring&lt;/tt&gt; interchangeably but right now its too much of a PITA to make that work.&lt;br /&gt;&lt;br /&gt;I've also made it possible to use closures for slots (see example below.) Frickin sweet.&lt;br /&gt;&lt;br /&gt;Anyway, I started getting into the &lt;a href="http://doc.trolltech.com/4.3/mainwindows-dockwidgets.html"&gt;Dock Widgets example&lt;/a&gt; but lost interest after seeing all the code. &lt;a href="http://paste.lisp.org/display/64482"&gt;Here&lt;/a&gt; is the code so far. Not very concise yet but will get there. Once I get into make-it-less-ugly mode, I will probably copy what Paul did with &lt;a href="http://lisp-cffi-qt4.sourceforge.net/"&gt;EQL&lt;/a&gt; as he calls it now.&lt;br /&gt;&lt;br /&gt;&lt;s&gt;Also the :foreign-pointer thingy will go away when I get around to adding cffi type translations.&lt;/s&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-4344157724641342161?l=uint32t.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/iDnybWa5pa0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/iDnybWa5pa0/qtlisp-more-progress.html</link><author>sohail@taggedtype.net (Sohail Somani)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2008/07/qtlisp-more-progress.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-3122616166564985534</guid><pubDate>Mon, 28 Jul 2008 23:04:00 +0000</pubDate><atom:updated>2008-07-28T16:09:23.252-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">python</category><category domain="http://www.blogger.com/atom/ns#">svn</category><title>svn-bisect</title><description>Well it was only a matter of time... &lt;a href="http://scons.tigris.org/source/browse/*checkout*/scons/branches/core/bin/svn-bisect.py?content-type=text%2Fplain&amp;rev=3249"&gt;svn-bisect.py&lt;/a&gt; lives!&lt;br /&gt;&lt;br /&gt;Greg Noel of SCons fame (is that really fame?) has committed a modification of a script I created whose purpose was to binary search the introduction of a bug in a SVN repository.&lt;br /&gt;&lt;br /&gt;Example usage of the script is &lt;a href="http://scons.tigris.org/issues/show_bug.cgi?id=2037"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Enjoy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-3122616166564985534?l=uint32t.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/TMF2zao6cdc" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/TMF2zao6cdc/svn-bisect.html</link><author>sohail@taggedtype.net (Sohail Somani)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2008/07/svn-bisect.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-3990927677037015372</guid><pubDate>Mon, 28 Jul 2008 22:51:00 +0000</pubDate><atom:updated>2008-07-28T15:55:25.382-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">personal</category><category domain="http://www.blogger.com/atom/ns#">nothingtoseehere</category><title>Why complaining works..</title><description>My email to an online store:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Hey guys, I ordered product XYZ from your site yesterday. According to your shipping estimates, it should be here in 2-4 days. However, I see that it is not shipped yet. I have had one bad experience with your service before and would not like it to repeat. Please see that this is so.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Literally 5 minutes later:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Your order has been shipped.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Now if I can only get them to do it before I complain.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-3990927677037015372?l=uint32t.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/XSPGINWW2As" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/XSPGINWW2As/why-complaining-works.html</link><author>sohail@taggedtype.net (Sohail Somani)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2008/07/why-complaining-works.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-1790320458741790045</guid><pubDate>Tue, 22 Jul 2008 17:04:00 +0000</pubDate><atom:updated>2008-07-27T16:59:05.580-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">lisp</category><category domain="http://www.blogger.com/atom/ns#">qt</category><title>Simple CFFI - Qt4 integration attempt</title><description>Update: Paul has sent me his code. He calls it "EQL" for ECL and Qt. Or something like that anyway! I have put it up &lt;a href="http://taggedtype.net/~sohail/lisp/eql-2008-07-24.tgz"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The author of the &lt;a href="http://lisp-cffi-qt4.sourceforge.net/"&gt;Simple CFFI - Qt4 integration attempt&lt;/a&gt; has contacted me to let me know that a modification of the above linked software is in commercial use. I have prodded him to release his modified version. He says he'll do it Real Soon Now (TM).&lt;br /&gt;&lt;br /&gt;I don't know if he is reading this blog but maybe a little pressure will help. Just kidding!&lt;br /&gt;&lt;br /&gt;What I like most about his method is the use of the introspection capabilities of Qt. Compared to the duct tape and glue I used, his is a lot more elegant. Currently, you cannot extend Qt in Lisp (via inheritance) but all the other goodies are still there. Indeed he tells me that for his application, he extended Qt from within C++ and used these extensions from his Lisp.&lt;br /&gt;&lt;br /&gt;I look forward to the update and to using the library.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-1790320458741790045?l=uint32t.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/1pClBkaVOd4" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/1pClBkaVOd4/simple-cffi-qt4-integration-attempt.html</link><author>sohail@taggedtype.net (Sohail Somani)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2008/07/simple-cffi-qt4-integration-attempt.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-3159387250960714266</guid><pubDate>Fri, 18 Jul 2008 17:22:00 +0000</pubDate><atom:updated>2008-12-08T18:20:03.909-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">lisp</category><category domain="http://www.blogger.com/atom/ns#">qt</category><title>Qt/Lisp: looking for feedback</title><description>Update: You can download the generated code from &lt;a href="http://taggedtype.net/~sohail/package.tgz"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The tubes were down this morning, so I managed to get up to tutorial 6 in my Qt/Lisp API. It covers about 95% of the API by design so most of the non-extension tutorials/examples should work.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://paste.lisp.org/display/63901"&gt;Tutorial 1:&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_NJChfbPZ2fA/SIDeB2YpWsI/AAAAAAAAAC4/JjX-aSairMI/s1600-h/tutorial1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_NJChfbPZ2fA/SIDeB2YpWsI/AAAAAAAAAC4/JjX-aSairMI/s200/tutorial1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5224419691109898946" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://paste.lisp.org/display/63902"&gt;Tutorial 2&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_NJChfbPZ2fA/SIDeT6lTQ5I/AAAAAAAAADA/n_bsHvr8TnQ/s1600-h/tutorial2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_NJChfbPZ2fA/SIDeT6lTQ5I/AAAAAAAAADA/n_bsHvr8TnQ/s200/tutorial2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5224420001474364306" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://paste.lisp.org/display/63903"&gt;Tutorial 3&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_NJChfbPZ2fA/SIDeUFoum0I/AAAAAAAAADI/k5WFqsLpLD8/s1600-h/tutorial3.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_NJChfbPZ2fA/SIDeUFoum0I/AAAAAAAAADI/k5WFqsLpLD8/s200/tutorial3.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5224420004441529154" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://paste.lisp.org/display/63904"&gt;Tutorial 4&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_NJChfbPZ2fA/SIDeUCT_JTI/AAAAAAAAADQ/swwXN5ZydAM/s1600-h/tutorial4.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_NJChfbPZ2fA/SIDeUCT_JTI/AAAAAAAAADQ/swwXN5ZydAM/s200/tutorial4.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5224420003549226290" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://paste.lisp.org/display/63905"&gt;Tutorial 5&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_NJChfbPZ2fA/SIDeUUJJlDI/AAAAAAAAADY/A8bVadsAK6g/s1600-h/tutorial5.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_NJChfbPZ2fA/SIDeUUJJlDI/AAAAAAAAADY/A8bVadsAK6g/s200/tutorial5.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5224420008335610930" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://paste.lisp.org/display/63906"&gt;Tutorial 6&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_NJChfbPZ2fA/SIDeUQ3qmwI/AAAAAAAAADg/EeaYKCV29kI/s1600-h/tutorial6.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_NJChfbPZ2fA/SIDeUQ3qmwI/AAAAAAAAADg/EeaYKCV29kI/s200/tutorial6.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5224420007456971522" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;I would like to hear your complaints, suggestions, feedback if you have any.&lt;br /&gt;&lt;br /&gt;Note that this API is a first draft and I thought it better to have something out there than wait until everything is perfect.&lt;br /&gt;&lt;br /&gt;To start with, my current complaints:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt; &lt;li&gt;(in-package :qt) -&gt; Nothing is actually exported from the package yet :-)&lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;s&gt;(make-instance 'qstring ...) -&gt; A really verbose way to pass a string! Should convert lisp strings to qstrings automagically.&lt;/s&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Naming: instead of qpush-button, q:push-button&lt;/li&gt;&lt;br /&gt; &lt;li&gt;No way to extend Qt from within Lisp yet (&lt;a href="http://doc.trolltech.com/4.3/tutorial-t7.html"&gt;tutorial 7&lt;/a&gt; won't work)&lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;s&gt;No way to attach arbitrary functions as slots&lt;/s&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Not Lispy enough.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;I expect to address most of these at some point though the "Not Lispy enough" complaint is a bit subjective.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-3159387250960714266?l=uint32t.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/J79Yvp3knhI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/J79Yvp3knhI/qtlisp-looking-for-feedback.html</link><author>sohail@taggedtype.net (Sohail Somani)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_NJChfbPZ2fA/SIDeB2YpWsI/AAAAAAAAAC4/JjX-aSairMI/s72-c/tutorial1.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2008/07/qtlisp-looking-for-feedback.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-6700781333683502992</guid><pubDate>Wed, 09 Jul 2008 16:56:00 +0000</pubDate><atom:updated>2008-07-09T10:46:50.526-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">personal</category><title>Sohail, it doesn't work anymore</title><description>Everyone has a story about when they were younger. For example, Joel Spolsky talks about his time in an army bakery (or something like that.) Sometimes, the stories are quite pathetic like Al Bundy and his high school football team. I am neither as exciting as Spolsky, nor as pathetic as Al Bundy (though I'm sure the latter is up for debate.)&lt;br /&gt;&lt;br /&gt;This story is about something that happened to me when I was younger that made me who I am today.&lt;br /&gt;&lt;br /&gt;I started programming quite late by geek standards. I was either 11 or 14 depending on whether you count batch files as programming. But I loved it. And when I got tired of programming, I'd program some more in FastTracker 2!&lt;br /&gt;&lt;br /&gt;For a while, I had a job as a pharmacist's assistant. This particular pharmacy had the option for delivery of prescriptions and other general items. The deliveries were done in the evening and were done by two very friendly guys named Krish and Sam.&lt;br /&gt;&lt;br /&gt;Part of my job here (besides preparing the methadone!) was to add up all the deliveries that these two guys did within some period of time and summarize for the boss. It used to take me hours in a busy month as it required use of some large Excel spreadsheet. So I resolved to solve that problem with my programming chops. I got the owner to agree to pay me hourly (wow, $10/hour!) and he told me not to spend "too much time" on it. So I guesstimated 40 hours until I would be able to deploy the application. He was fine with that.&lt;br /&gt;&lt;br /&gt;I was mostly right but near the end of it, while I was testing with the users (me), it turned out some other data collection was necessary. After discussing with the boss, he said it was important but not to spend "too much time" on it. By then, I had come to realize that "too much time" means "don't charge me more than I want to pay you." So I added it quickly, and it was done.&lt;br /&gt;&lt;br /&gt;I deployed the application in December of that year to rave reviews from the boss. I'm not sure if the other employees cared that much but I know that it made my life easier and the count of deliveries more accurate so I was happy.&lt;br /&gt;&lt;br /&gt;Due to other responsibilities (I think it was school?), I had to reduce my hours at the pharmacy. That was around June. I had trained the other people to use the application and it was becoming quite necessary for them to use if they wanted to retain their sanity.&lt;br /&gt;&lt;br /&gt;Fast-forward to November. I get a call. "Sohail, it's not working anymore." "Crap", I thought. What did I miss? I went into the pharmacy and fudged around in the flat files to see what could be wrong.&lt;br /&gt;&lt;br /&gt;It turns out that one of the data files was being named incorrectly. Can you guess which data file? Yes, it was the one I had added last just before I completed the project.&lt;br /&gt;&lt;br /&gt;I think I spent about 10 unpaid hours debugging the problem at home while studying for exams/finishing projects. It came down to this (in C++, I don't really recall the language):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// data1.cpp&lt;br /&gt;const char * months[] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// data2.cpp&lt;br /&gt;const char * months[] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov ","Dec"};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Can you see the problem? In the second instance, I added a space after "Nov". So while data2.cpp was saving "Data2Nov Year.file", data1.cpp was saving "Data1NovYear.file" and the code that summarized the data was trying to open "Data&amp;lt;N&amp;gt;NovYear.file".&lt;br /&gt;&lt;br /&gt;Oops.&lt;br /&gt;&lt;br /&gt;I fixed this bug and apologized to the owner. I explained why it happened and that I fixed the code duplication. The boss said that he thought I should get an award for this software (a big ego boost!) and wondered if he could sell it to other people. Apparently he had been raving about it to his other pharmacist buddies. I don't remember what I said to him about that (something about me not having enough time to modify it to be generic enough as Sam and Krish were hardcoded!) but I really learned something that month.&lt;br /&gt;&lt;br /&gt;Fortunately, in this case, things turned out alright. So I swore to avoid similar problems in the future in case future clients were not as forgiving. How did I do this? Quite simply:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt; &lt;li&gt;Thorough testing&lt;/li&gt;&lt;br /&gt; &lt;li&gt;No copy-and-waste&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;My business cards have always had some variation of this. The current incarnation has something like "Do it once, do it right." Corny, but conveys my philosophy quite well. I will work very hard to reduce code duplication now. I try my best to write a test for each function/class that I write. Yes it is hard work. Yes it takes time. Quite frankly, software &lt;i&gt;is&lt;/i&gt; hard. But in the end, I get very few calls saying "Sohail, it doesn't work anymore."&lt;br /&gt;&lt;br /&gt;And no, you are not allowed to put a comment on this post saying "Sohail, it doesn't work anymore" :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-6700781333683502992?l=uint32t.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/RZ796EotEPw" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/RZ796EotEPw/sohail-it-doesnt-work-anymore.html</link><author>sohail@taggedtype.net (Sohail Somani)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2008/07/sohail-it-doesnt-work-anymore.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-5496163434442401429</guid><pubDate>Tue, 24 Jun 2008 04:32:00 +0000</pubDate><atom:updated>2008-12-08T18:20:04.185-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">c++</category><category domain="http://www.blogger.com/atom/ns#">gtk</category><category domain="http://www.blogger.com/atom/ns#">gui</category><category domain="http://www.blogger.com/atom/ns#">gtkmm</category><title>Automatically rescale a Gtk::Image (and preserve aspect ratio)</title><description>Don't really have enough time to explain it all, but hopefully the comments help. Here are a couple of screenshots:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_NJChfbPZ2fA/SGB5Ta3T8WI/AAAAAAAAACk/qtPukoWkMpI/s1600-h/Screenshot-1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_NJChfbPZ2fA/SGB5Ta3T8WI/AAAAAAAAACk/qtPukoWkMpI/s200/Screenshot-1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5215301743030825314" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_NJChfbPZ2fA/SGB5bYP6vrI/AAAAAAAAACs/bCWC89awffY/s1600-h/Screenshot-2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_NJChfbPZ2fA/SGB5bYP6vrI/AAAAAAAAACs/bCWC89awffY/s200/Screenshot-2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5215301879767678642" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The image used in the examples above is &lt;a href="http://www.utahskies.org/image_library/deepsky/constellations/orionwa.jpg"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;And the code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="cxx"&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;*&lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt;  Problem:&lt;br /&gt;&lt;br /&gt;  Using GTK, display an image in a window and rescale when the window&lt;br /&gt;  resizes preserving the aspect ratio.&lt;br /&gt;  &lt;br /&gt;  Analysis:&lt;br /&gt;&lt;br /&gt;  Gtk provides Gtk::Image which works on a Gdk::Pixbuf (pixel buffer)&lt;br /&gt;  which allows rescaling but without preserving aspect ratio.&lt;br /&gt;&lt;br /&gt;  Summary of solution:&lt;br /&gt;&lt;br /&gt;  Use a Gtk::Image embedded in a Gtk::AspectFrame and resize image&lt;br /&gt;  using dimensions determined by Gtk::AspectFrame. The AspectFrame&lt;br /&gt;  knows how to maintain a ratio so it does the messy work for us.&lt;br /&gt;&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="preprocessor"&gt;#&lt;/span&gt;&lt;span class="preprocessor"&gt;include&lt;/span&gt; &lt;span class="string"&gt;&amp;lt;&lt;/span&gt;&lt;span class="string"&gt;gtkmm.h&lt;/span&gt;&lt;span class="string"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="preprocessor"&gt;#&lt;/span&gt;&lt;span class="preprocessor"&gt;include&lt;/span&gt; &lt;span class="string"&gt;&amp;lt;&lt;/span&gt;&lt;span class="string"&gt;iostream&lt;/span&gt;&lt;span class="string"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;/// &lt;/span&gt;&lt;span class="comment"&gt;This Widget only scales the image but does not preserve&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/// &lt;/span&gt;&lt;span class="comment"&gt;aspect ratios.&lt;br /&gt;&lt;/span&gt;&lt;span class="keyword"&gt;s&lt;/span&gt;&lt;span class="keyword"&gt;truc&lt;/span&gt;&lt;span class="keyword"&gt;t&lt;/span&gt; &lt;span class="type"&gt;ScalingImage&lt;/span&gt; : &lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="constant"&gt;Gtk&lt;/span&gt;::&lt;span class="type"&gt;Image&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;  &lt;span class="keyword"&gt;explici&lt;/span&gt;&lt;span class="keyword"&gt;t&lt;/span&gt;&lt;br /&gt;  &lt;span class="function-name"&gt;ScalingImage&lt;/span&gt;(&lt;span class="constant"&gt;Glib&lt;/span&gt;::&lt;span class="type"&gt;RefPtr&lt;/span&gt;&amp;lt;&lt;span class="constant"&gt;Gdk&lt;/span&gt;::Pixbuf&amp;gt; &lt;span class="variable-name"&gt;pixbuf&lt;/span&gt;,&lt;br /&gt;               &lt;span class="constant"&gt;Gdk&lt;/span&gt;::&lt;span class="type"&gt;InterpType&lt;/span&gt; &lt;span class="variable-name"&gt;interp&lt;/span&gt; = &lt;span class="constant"&gt;Gdk&lt;/span&gt;::INTERP_BILINEAR):&lt;br /&gt;    &lt;span class="constant"&gt;Gtk&lt;/span&gt;::Image(pixbuf),&lt;br /&gt;    m_original(pixbuf),&lt;br /&gt;    m_interp(interp),&lt;br /&gt;    m_sized(&lt;span class="constant"&gt;false&lt;/span&gt;)&lt;br /&gt;  {&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;protected&lt;/span&gt;:&lt;br /&gt;  &lt;span class="keyword"&gt;virtual&lt;/span&gt;&lt;br /&gt;  &lt;span class="type"&gt;voi&lt;/span&gt;&lt;span class="type"&gt;d&lt;/span&gt;&lt;br /&gt;  &lt;span class="function-name"&gt;on_size_allocate&lt;/span&gt;(&lt;span class="constant"&gt;Gtk&lt;/span&gt;::&lt;span class="type"&gt;Allocation&lt;/span&gt; &amp;amp; &lt;span class="variable-name"&gt;r&lt;/span&gt;)&lt;br /&gt;  {&lt;br /&gt;    &lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/ &lt;/span&gt;&lt;span class="comment"&gt;This event is fired on all Widgets when their rectangle gets&lt;br /&gt;&lt;/span&gt;    &lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/ &lt;/span&gt;&lt;span class="comment"&gt;resized. So we rescale our image. But rescaling our image fires&lt;br /&gt;&lt;/span&gt;    &lt;span class="comment-delimiter"&gt;// &lt;/span&gt;&lt;span class="comment"&gt;another resize event, and another, and another... You see the&lt;br /&gt;&lt;/span&gt;    &lt;span class="comment-delimiter"&gt;// &lt;/span&gt;&lt;span class="comment"&gt;problem!&lt;br /&gt;&lt;/span&gt;    &lt;span class="comment-delimiter"&gt;//&lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt;&lt;/span&gt;    &lt;span class="comment-delimiter"&gt;// &lt;/span&gt;&lt;span class="comment"&gt;The most straightforward solution is to not rescale the image&lt;br /&gt;&lt;/span&gt;    &lt;span class="comment-delimiter"&gt;// &lt;/span&gt;&lt;span class="comment"&gt;the second time the event is fired. Hence the m_size toggle.&lt;br /&gt;&lt;/span&gt;    &lt;span class="comment-delimiter"&gt;//&lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt;&lt;/span&gt;    &lt;span class="comment-delimiter"&gt;// &lt;/span&gt;&lt;span class="comment"&gt;Ideally I'd not like to do this but this was the best way I&lt;br /&gt;&lt;/span&gt;    &lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/ &lt;/span&gt;&lt;span class="comment"&gt;found!&lt;br /&gt;&lt;/span&gt;    &lt;span class="keyword"&gt;i&lt;/span&gt;&lt;span class="keyword"&gt;f&lt;/span&gt;(&lt;span class="negation-char"&gt;!&lt;/span&gt;m_sized)&lt;br /&gt;    {&lt;br /&gt;      &lt;span class="constant"&gt;Glib&lt;/span&gt;::&lt;span class="type"&gt;RefPtr&lt;/span&gt;&amp;lt;&lt;span class="constant"&gt;Gdk&lt;/span&gt;::Pixbuf&amp;gt; &lt;span class="variable-name"&gt;scaled&lt;/span&gt; = &lt;br /&gt;        m_original-&amp;gt;scale_simple(r.get_width(),&lt;br /&gt;                                 r.get_height(),&lt;br /&gt;                                 m_interp);&lt;br /&gt;      &lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/ &lt;/span&gt;&lt;span class="comment"&gt;Reset the image to be the new scaled image which&lt;br /&gt;&lt;/span&gt;      &lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/ &lt;/span&gt;&lt;span class="comment"&gt;will cause the second size-allocate signal&lt;br /&gt;&lt;/span&gt;      &lt;span class="constant"&gt;G&lt;/span&gt;&lt;span class="constant"&gt;tk&lt;/span&gt;::&lt;span class="constant"&gt;Image&lt;/span&gt;::set(scaled);&lt;br /&gt;&lt;br /&gt;      &lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/ &lt;/span&gt;&lt;span class="comment"&gt;Make sure we don't treat it as a rescale request &lt;br /&gt;&lt;/span&gt;      &lt;span class="comment-delimiter"&gt;// &lt;/span&gt;&lt;span class="comment"&gt;next time&lt;br /&gt;&lt;/span&gt;      m_sized = &lt;span class="constant"&gt;true&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;    &lt;span class="keyword"&gt;else&lt;/span&gt;&lt;br /&gt;    {&lt;br /&gt;      &lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/ &lt;/span&gt;&lt;span class="comment"&gt;Reaction to set above. Call the base class's on_size_allocate&lt;br /&gt;&lt;/span&gt;      &lt;span class="comment-delimiter"&gt;// &lt;/span&gt;&lt;span class="comment"&gt;function. Shouldn't I have to call this above too? Maybe it&lt;br /&gt;&lt;/span&gt;      &lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/ &lt;/span&gt;&lt;span class="comment"&gt;isn't necessary since it gets called anyway.&lt;br /&gt;&lt;/span&gt;      &lt;span class="constant"&gt;G&lt;/span&gt;&lt;span class="constant"&gt;tk&lt;/span&gt;::&lt;span class="constant"&gt;Image&lt;/span&gt;::on_size_allocate(r);&lt;br /&gt;&lt;br /&gt;      &lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/ &lt;/span&gt;&lt;span class="comment"&gt;Treat next resize event as a rescale&lt;br /&gt;&lt;/span&gt;      m_sized = &lt;span class="constant"&gt;false&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;&lt;span class="keyword"&gt;private&lt;/span&gt;:&lt;br /&gt;  &lt;span class="constant"&gt;Glib&lt;/span&gt;::&lt;span class="type"&gt;RefPtr&lt;/span&gt;&amp;lt;&lt;span class="constant"&gt;Gdk&lt;/span&gt;::Pixbuf&amp;gt; &lt;span class="variable-name"&gt;m_original&lt;/span&gt;;&lt;br /&gt;  &lt;span class="constant"&gt;Gdk&lt;/span&gt;::&lt;span class="type"&gt;InterpTyp&lt;/span&gt;&lt;span class="type"&gt;e&lt;/span&gt; &lt;span class="variable-name"&gt;m_interp&lt;/span&gt;;&lt;br /&gt;  &lt;span class="type"&gt;boo&lt;/span&gt;&lt;span class="type"&gt;l&lt;/span&gt; &lt;span class="variable-name"&gt;m_sized&lt;/span&gt;;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;// &lt;/span&gt;&lt;span class="comment"&gt;This widget automatically scales the image but preserves the&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/// &lt;/span&gt;&lt;span class="comment"&gt;aspect ratio of the original image. This is accomplished via use&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/// &lt;/span&gt;&lt;span class="comment"&gt;of the AspectFrame class&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;///&lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/// &lt;/span&gt;&lt;span class="comment"&gt;Ideally would like this to be a Gtk::Image subclass.&lt;br /&gt;&lt;/span&gt;&lt;span class="keyword"&gt;s&lt;/span&gt;&lt;span class="keyword"&gt;truc&lt;/span&gt;&lt;span class="keyword"&gt;t&lt;/span&gt; &lt;span class="type"&gt;AspectPreservingScalingImage&lt;/span&gt; : &lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="constant"&gt;Gtk&lt;/span&gt;::&lt;span class="type"&gt;AspectFrame&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;  &lt;span class="keyword"&gt;explici&lt;/span&gt;&lt;span class="keyword"&gt;t&lt;/span&gt;&lt;br /&gt;  &lt;span class="function-name"&gt;AspectPreservingScalingImage&lt;/span&gt;(&lt;span class="constant"&gt;Glib&lt;/span&gt;::&lt;span class="type"&gt;RefPtr&lt;/span&gt;&amp;lt;&lt;span class="constant"&gt;Gdk&lt;/span&gt;::Pixbuf&amp;gt; &lt;span class="keyword"&gt;const&lt;/span&gt; &amp;amp; &lt;span class="variable-name"&gt;pixbuf&lt;/span&gt;,&lt;br /&gt;                               &lt;span class="constant"&gt;Gdk&lt;/span&gt;::&lt;span class="type"&gt;InterpType&lt;/span&gt; &lt;span class="variable-name"&gt;interp&lt;/span&gt; = &lt;span class="constant"&gt;Gdk&lt;/span&gt;::INTERP_BILINEAR):&lt;br /&gt;    m_img(pixbuf,interp)&lt;br /&gt;  {&lt;br /&gt;    &lt;span class="variable-name"&gt;set&lt;/span&gt;(&lt;span class="constant"&gt;Gtk&lt;/span&gt;::ALIGN_CENTER, &lt;span class="constant"&gt;Gtk&lt;/span&gt;::ALIGN_CENTER,&lt;br /&gt;        &lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/ &lt;/span&gt;&lt;span class="comment"&gt;Aspect ratio of frame&lt;br /&gt;&lt;/span&gt;        pixbuf-&amp;gt;get_width()/&lt;span class="type"&gt;float&lt;/span&gt;(pixbuf-&amp;gt;get_height()));&lt;br /&gt;    &lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/ &lt;/span&gt;&lt;span class="comment"&gt;This makes it appear as if there is no frame&lt;br /&gt;&lt;/span&gt;    set_shadow_type(&lt;span class="constant"&gt;Gtk&lt;/span&gt;::SHADOW_NONE);&lt;br /&gt;    &lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/ &lt;/span&gt;&lt;span class="comment"&gt;This allows a minimum size&lt;br /&gt;&lt;/span&gt;    set_size_request(pixbuf-&amp;gt;get_width()/2,pixbuf-&amp;gt;get_height()/2);&lt;br /&gt;    &lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/ &lt;/span&gt;&lt;span class="comment"&gt;Finally, add the image to be managed&lt;br /&gt;&lt;/span&gt;    add(m_img);&lt;br /&gt;  }&lt;br /&gt;&lt;span class="keyword"&gt;private&lt;/span&gt;:&lt;br /&gt;  &lt;span class="type"&gt;ScalingImag&lt;/span&gt;&lt;span class="type"&gt;e&lt;/span&gt; &lt;span class="variable-name"&gt;m_img&lt;/span&gt;;  &lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span class="type"&gt;i&lt;/span&gt;&lt;span class="type"&gt;n&lt;/span&gt;&lt;span class="type"&gt;t&lt;/span&gt; &lt;span class="function-name"&gt;main&lt;/span&gt;(&lt;span class="type"&gt;int&lt;/span&gt; &lt;span class="variable-name"&gt;argc&lt;/span&gt;, &lt;span class="type"&gt;char&lt;/span&gt;* &lt;span class="variable-name"&gt;argv&lt;/span&gt;[])&lt;br /&gt;{&lt;br /&gt;  &lt;span class="keyword"&gt;if&lt;/span&gt;(argc != 2)&lt;br /&gt;  {&lt;br /&gt;    &lt;span class="constant"&gt;std&lt;/span&gt;::cout &amp;lt;&amp;lt; &lt;span class="string"&gt;&amp;quot;Usage: &amp;quot;&lt;/span&gt; &amp;lt;&amp;lt; argv[0] &amp;lt;&amp;lt; &lt;span class="string"&gt;&amp;quot; &amp;lt;image-file&amp;gt;&amp;quot;&lt;/span&gt; &amp;lt;&amp;lt; &lt;span class="constant"&gt;std&lt;/span&gt;::endl;&lt;br /&gt;    &lt;span class="keyword"&gt;return&lt;/span&gt; 1;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;span class="constant"&gt;Gtk&lt;/span&gt;::&lt;span class="type"&gt;Mai&lt;/span&gt;&lt;span class="type"&gt;n&lt;/span&gt; &lt;span class="variable-name"&gt;kit&lt;/span&gt;(argc,argv);&lt;br /&gt;&lt;br /&gt;  &lt;span class="constant"&gt;Gtk&lt;/span&gt;::&lt;span class="type"&gt;Windo&lt;/span&gt;&lt;span class="type"&gt;w&lt;/span&gt; &lt;span class="variable-name"&gt;win&lt;/span&gt;;&lt;br /&gt;  &lt;span class="constant"&gt;Gtk&lt;/span&gt;::&lt;span class="type"&gt;VBo&lt;/span&gt;&lt;span class="type"&gt;x&lt;/span&gt; &lt;span class="variable-name"&gt;box&lt;/span&gt;;&lt;br /&gt;  win.add(box);&lt;br /&gt;&lt;br /&gt;  &lt;span class="constant"&gt;Gtk&lt;/span&gt;::&lt;span class="type"&gt;LinkButto&lt;/span&gt;&lt;span class="type"&gt;n&lt;/span&gt; &lt;span class="variable-name"&gt;lb&lt;/span&gt;(&lt;span class="string"&gt;&amp;quot;http://www.utahskies.org/image_library/deepsky/constellations/orionwa.jp&lt;/span&gt;&lt;span class="string"&gt;g&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;);&lt;br /&gt;  &lt;span class="type"&gt;AspectPreservingScalingImag&lt;/span&gt;&lt;span class="type"&gt;e&lt;/span&gt; &lt;span class="variable-name"&gt;apsi&lt;/span&gt;(&lt;span class="constant"&gt;Gdk&lt;/span&gt;::&lt;span class="constant"&gt;Pixbuf&lt;/span&gt;::&lt;span class="type"&gt;create_from_file&lt;/span&gt;(&lt;span class="variable-name"&gt;argv&lt;/span&gt;[1]));&lt;br /&gt;&lt;br /&gt;  box.pack_start(lb,&lt;span class="constant"&gt;Gtk&lt;/span&gt;::PACK_SHRINK);&lt;br /&gt;  box.pack_start(apsi);&lt;br /&gt;  &lt;br /&gt;  &lt;span class="keyword"&gt;struc&lt;/span&gt;&lt;span class="keyword"&gt;t&lt;/span&gt; &lt;span class="type"&gt;launch_browser&lt;/span&gt;&lt;br /&gt;  {&lt;br /&gt;    &lt;span class="keyword"&gt;static&lt;/span&gt;&lt;br /&gt;    &lt;span class="type"&gt;voi&lt;/span&gt;&lt;span class="type"&gt;d&lt;/span&gt;&lt;br /&gt;    &lt;span class="function-name"&gt;doit&lt;/span&gt;(&lt;span class="constant"&gt;Glib&lt;/span&gt;::ustring &lt;span class="keyword"&gt;const&lt;/span&gt; &amp;amp; &lt;span class="variable-name"&gt;addr&lt;/span&gt;)&lt;br /&gt;    {&lt;br /&gt;      &lt;span class="constant"&gt;std&lt;/span&gt;::&lt;span class="type"&gt;strin&lt;/span&gt;&lt;span class="type"&gt;g&lt;/span&gt; &lt;span class="variable-name"&gt;command&lt;/span&gt;(&lt;span class="string"&gt;&amp;quot;firefox &amp;quot;&lt;/span&gt;);&lt;br /&gt;      command += addr.c_str();&lt;br /&gt;      &lt;span class="constant"&gt;std&lt;/span&gt;::system(command.c_str());&lt;br /&gt;    }&lt;br /&gt;  };&lt;br /&gt;&lt;br /&gt;  lb.signal_clicked().connect&lt;br /&gt;    ( &lt;br /&gt;     &lt;span class="constant"&gt;sigc&lt;/span&gt;::bind(&lt;br /&gt;                &lt;span class="constant"&gt;sigc&lt;/span&gt;::ptr_fun(&lt;span class="constant"&gt;launch_browser&lt;/span&gt;::doit),&lt;br /&gt;                lb.get_uri()&lt;br /&gt;                )&lt;br /&gt;      );&lt;br /&gt;      &lt;br /&gt;&lt;br /&gt;  win.show_all();&lt;br /&gt;&lt;br /&gt;  &lt;span class="constant"&gt;Gtk&lt;/span&gt;::&lt;span class="constant"&gt;Main&lt;/span&gt;::run(win);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-5496163434442401429?l=uint32t.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/GbNjbhXhETQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/GbNjbhXhETQ/automatically-rescale-gtkimage-and.html</link><author>sohail@taggedtype.net (Sohail Somani)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_NJChfbPZ2fA/SGB5Ta3T8WI/AAAAAAAAACk/qtPukoWkMpI/s72-c/Screenshot-1.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2008/06/automatically-rescale-gtkimage-and.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-7589668751641397623</guid><pubDate>Thu, 05 Jun 2008 17:19:00 +0000</pubDate><atom:updated>2008-06-05T10:21:06.440-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">c++</category><category domain="http://www.blogger.com/atom/ns#">gui</category><title>C++ Standard GUI</title><description>&lt;pre&gt;&lt;br /&gt;#include &amp;lt;gtkmm.h&amp;gt;&lt;br /&gt;&lt;br /&gt;namespace std&lt;br /&gt;{&lt;br /&gt;  namespace gui = Gtk;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I love &lt;a href="http://gtkmm.org"&gt;gtkmm&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-7589668751641397623?l=uint32t.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/bxHW24aXUqM" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/bxHW24aXUqM/c-standard-gui.html</link><author>sohail@taggedtype.net (Sohail Somani)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">6</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2008/06/c-standard-gui.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-7774464749838367868</guid><pubDate>Mon, 02 Jun 2008 20:18:00 +0000</pubDate><atom:updated>2008-06-02T13:24:36.453-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">linux</category><category domain="http://www.blogger.com/atom/ns#">mfc465-cn</category><title>Linux printing: Brother MFC-465CN</title><description>I've been using Linux for a long time and as has anyone who has done so, printers, scanners and basically anything else that does not have a USB storage interface is a risky proposition.&lt;br /&gt;&lt;br /&gt;Not so with the Brother MFC-465CN.&lt;br /&gt;&lt;br /&gt;My setup process (on Ubuntu Hardy/8.04):&lt;br /&gt;&lt;ul&gt;&lt;br /&gt; &lt;li&gt;Set up hardware as suggested in manual&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Skip software installation and connect printer to network via ethernet&lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;tt&gt;sudo apt-get install brother-lpr-drivers-extra brother-cups-wrapper-extra&lt;/tt&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;System-&gt;Administration-&gt;Printing-&gt;Test page&lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;tt&gt;sudo apt-get install xsane sane&lt;/tt&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://solutions.brother.com/linux/sol/printer/linux/sane_drivers.html"&gt;Get brsane2 driver&lt;/a&gt; (read the instructions!)&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Launch xsane and test scanner&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;I don't even want to remember what it used to be LIKE before. Brother has GPLed their printer driver which is probably part of the reason it was so easy to set up. Great job Brother and many thanks to the Open Source fairy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-7774464749838367868?l=uint32t.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/Tl9Se43zDD0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/Tl9Se43zDD0/linux-printing-brother-mfc-465cn.html</link><author>sohail@taggedtype.net (Sohail Somani)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">11</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2008/06/linux-printing-brother-mfc-465cn.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-8492558566909423275</guid><pubDate>Thu, 29 May 2008 05:18:00 +0000</pubDate><atom:updated>2008-05-28T22:46:07.562-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">lisp</category><category domain="http://www.blogger.com/atom/ns#">parenscript</category><title>YUI and Parenscript</title><description>&lt;a href="http://common-lisp.net/project/parenscript/"&gt;Parenscript&lt;/a&gt; is a nice little mini-language that lets you compile Lisp to JavaScript. Sort of like Google does with &lt;a href="http://code.google.com/webtoolkit/"&gt;GWT&lt;/a&gt; and the language to end all languages: Java.&lt;br /&gt;&lt;br /&gt;Parenscript code looks like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(ps:ps&lt;br /&gt;  (defun say-hi ()&lt;br /&gt;    (alert "Hi!"))&lt;br /&gt;  (say-hi))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The macro &lt;tt&gt;ps:ps&lt;/tt&gt; compiles the Lisp code to a JS string which looks like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function sayHi() {&lt;br /&gt;    alert('Hi!');&lt;br /&gt;};&lt;br /&gt;sayHi();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Notice the conversion from &lt;tt&gt;say-hi&lt;/tt&gt; to &lt;tt&gt;sayHi&lt;/tt&gt;. I love the Common Lisp naming conventions. They make so much sense and I miss them everywhere else. Obviously the writers of Parenscript agreed with me so they convert each symbol they see into a JS symbol which keeps things looking mostly neat.&lt;br /&gt;&lt;br /&gt;The major conventions are (I don't know that there are more):&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;&lt;tt&gt;*foo*&lt;/tt&gt; becomes &lt;tt&gt;FOO&lt;/tt&gt;&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;&lt;tt&gt;foo-bar&lt;/tt&gt; becomes &lt;tt&gt;fooBar&lt;/tt&gt;&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;&lt;tt&gt;foo.*bar&lt;/tt&gt; becomes &lt;tt&gt;foo.Bar&lt;/tt&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Anyhoo, &lt;a href="http://developer.yahoo.com/yui/"&gt;YUI&lt;/a&gt; is a largish but nice JavaScript library that one can use for creating quite interactive web applications.&lt;br /&gt;&lt;br /&gt;The problem is that YUI has names like &lt;tt&gt;YAHOO.util.Event.onDOMReady&lt;/tt&gt; which is a handful to type even in JavaScript. If you try converting this symbol via ParenScript you will be in for a surprise (try it!) Anyway, there are a couple of ways to write this in ParenScript and keep the casing intact without losing your hair:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt; &lt;li&gt;&lt;tt&gt;*yahoo*.util.*event.on-d-o-m-ready&lt;/tt&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;tt&gt;|:YAHOO.util.:Event.:onDOMReady|&lt;/tt&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;This works because the bars prevent the reader from downcasing or upcasing the symbol and ParenScript promises that it will leave symbols that begin with a colon alone.&lt;br /&gt;&lt;br /&gt;Even so, this is still a PITA to type. What I do is I have a wrapper script that gets compiled once with short names for all of these. So for the above example, using Hunchentoot:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;(defin-easy-handler (my-yui :uri "/ps/my-yui.ps") ()&lt;br /&gt;  (ps:ps&lt;br /&gt;    (defun yui-on-dom-ready (fn) &lt;br /&gt;      (|:YAHOO.util.:Event.:onDOMReady| fn))&lt;br /&gt;    (defvar yui-some-other-funky-name |:YAHOO.util.:FunkyChickens|)))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Yay.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-8492558566909423275?l=uint32t.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/OjXU3ANRoEQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/OjXU3ANRoEQ/yui-and-parenscript.html</link><author>sohail@taggedtype.net (Sohail Somani)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2008/05/yui-and-parenscript.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-1962545238667647473</guid><pubDate>Mon, 26 May 2008 19:14:00 +0000</pubDate><atom:updated>2008-05-26T12:47:08.370-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">30day</category><title>30 day product challenge: update</title><description>The idea: Develop or prototype a commercial application in 30 days. Then decide what to do with it.&lt;br /&gt;&lt;br /&gt;Initially I had thought &lt;a href="http://30dayproductchallenge.com/30day"&gt;this Wiki&lt;/a&gt; would be the central point for a uISV community but I should have known better. It appears that people are a lot more comfortable with using their own blogs to update progress.&lt;br /&gt;&lt;br /&gt;With that in mind, Patrick McKenzie (a successful uISV owner, whom I greatly respect) has decided to jump on the bandwagon in &lt;a href="http://discuss.joelonsoftware.com/default.asp?biz.5.633780.13"&gt;his own way&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I am joining up with him and will be starting in mid-June while I complete some other work.&lt;br /&gt;&lt;br /&gt;I will be aggregating all the 30 day participants I can find at &lt;a href="http://feeds.feedburner.com/30dayers"&gt;this feed&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Best of luck and happy coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-1962545238667647473?l=uint32t.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/JjETAoBv8lk" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/JjETAoBv8lk/30-day-product-challenge-update.html</link><author>sohail@taggedtype.net (Sohail Somani)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2008/05/30-day-product-challenge-update.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-1547040178395637295</guid><pubDate>Fri, 23 May 2008 05:44:00 +0000</pubDate><atom:updated>2008-05-22T22:48:58.306-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">c++</category><title>Very cool interview with a compiler developer</title><description>Its sad that this is interesting for me but when you are waiting for a large C++ project to compile (gtkmm), you listen to these things in the background:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://channel9.msdn.com/showpost.aspx?postid=405345"&gt;The route to C++ code optimization&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The C++ compiler is the best MS product that exists. Well the only good product... Or maybe I just have a soft spot for C++ compiler developers. Either way, this man (also) uses Emacs (the illegal version) so maybe there is more to the story.&lt;br /&gt;&lt;br /&gt;Channel 9 people: You need to have a whole series on the C++ compiler from top to bottom.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-1547040178395637295?l=uint32t.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/wmiLek35bPo" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/wmiLek35bPo/very-cool-interview-with-compiler.html</link><author>sohail@taggedtype.net (Sohail Somani)</author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2008/05/very-cool-interview-with-compiler.html</feedburner:origLink></item></channel></rss>
