CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Grant Killian's Blog

No, this has nothing to do with beer -- but maybe it should?
  • Following Up on Brendan's Crystal Post

    Brendan has an interesting post about Crystal "from an insiders perspective." 

    Crystal Reports is reporting software that's marketed well to business decision-makers; Crystal is a household name when it comes to reports!  Most developers, however, work to avoid Crystal Reports like the plague.  Crystal is marketed well to people who write the checks, but not to people who write and implement the reports.  I think a "perception of value" scenario is sometimes at work, too, where something that costs a lot must be very valuable -- therefore expensive Crystal Reports must be a great reporting tool.  Following that logic: if we charged people a membership fee to read the blogs on CodeBetter.com they'd percieve the content to be more valuable and worthwhile.

    Brendan's post has another little kernel of wisdom in there . . . the guru points out that Crystal wants to stay ahead of Cognos.  If that's the gauge Crystal uses, developers don't do handstands over working with Cognos either.  If it's between Cognos and Crystal, I'll gladly take Excel and custom charts any day!

    Which brings me to Reporting Services from Microsoft and what a welcome addition it is to the enterprise reporting landscape.  Is it perfect?  No.  Is it better than the alternatives?  Seems to be -- although I'm no Reporting Services guru.  They work fine on my machine, though, which is more than I can say for my frustrations with Crystal!

  • Option Strict On Salvation

    Yeah, I should have put this in my earlier post but I didn't have time.  Maybe I'm crazy, but the whole Option Strict stuff with the TimeTracker starter kit is something I lose sleep over.  The solution is easy: just add a few ToString() and DateTime.Parse() functions where necessary . . . and then you have the whole ubiquitous IIF() function to wrestle with.   There's dozens of calls to the Option-Strict-On-hating Visual Basic IIF() function scattered all through the starter kit so fight that initial urge to do a search and replace approach.  And no, VB.Net doesn't have a ? operator either. 

    Instead, overload IIF() with the appropriate strongly typed parameters and you'll be all set.  This is an example:

    Public Class IIFHelper
     Public Shared Function IIF( Condition as Boolean, TrueResult as String, FalseResult as String ) as String
      If Condition Then
       return TrueResult
      Else
       return FalseResult
      End If
     End Function
    End Class

    Repeat as necessary and start using IIFHelper.IIF() instead of just IIF() -- I found only a handful of IIFHelper.IIF permutations necessary to get to Option Strict On salvation.

    Now I can rest easier. 

     

  • NHibernate

    Anyone having fun with NHibernateThis article from TheSeverSide gives a nice NHibernate overview, but I'm curious about how people are finding the config file management and the tool in general after a bit of real world use.

    I've used a home grown version that did the same thing; it used a combination of .Net Reflection and CodeSmith.  I wonder if NHibernate is the way to progress in the future . . .

  • No Option Strict For You

    I'm looking at sample apps for some newer .Net web developers to learn from . . . I figured the ASP.Net starter kits would be a good place to start.  One of the things we wanted to include was the importance of Option Strict On vs Option Strict Off and wouldn't you know it: the TimeTracker Starter Kit app doesn't use Option Strict On.  I guess I shouldn't consider a "starter kit" to be the same as a best-practice "reference application" but it would be better for everyone if these sorts of samples stuck to some fundamentals.  Oh well . . . I can use this as an exercise in why they aren't using Option Strict On and how we can correct it

    I won't even go into what happens when I run FxCop against the starter kit.

  • Making a Copy of ASP.Net Application -- Best Practices?

    Somewhere between this article on the .webinfo file and this post about the .csproj file (that incorrectly presumes it's a Visual SourceSafe problem -- I'm no big fan of VSS but it's not the issue in this case) I successfully made a local copy of a web app we've been working on.  Copy the directory . . . make it a virtual directory in IIS, modify the .webinfo file, rename as necessary (webinfo must be same name as the csproj file it seems).

    My question: what are the best practices around duplicating a web app on the same box (for running side-by-side as different instances with slightly different interfaces, etc?).  I KNOW that one can deploy the app to different virtual directories, but what I'm after is a form of branching the codebase into a totally new web application on a dev machine with the least amount of effort.  We'll use VS.Net to make some changes to the UI code for each customer (but reuse the same core assemblies for business logic etc); we're talking more than just style sheets, here, also.  Too bad "deploying" the app to the same machine (and checking the "include source code" option") doesn't configure IIS for you and the other manual work . . .

    Writing this post has reminded me of a few projects I've been on where all the UI stuff was configured from a database . . . the text of every label, x and y positioning on the screen, presence of dropdown lists and other user input widgets, graphics, etc.  This would solve my particular problem of changing the UI stuff for each customer but introduce a whole host of other architecture issues -- think about doing web layout from a set of related SQL Server tables and you'll get the idea.  

    Maybe this would be a handy utility to throw up on something like GotDotNet . . . if GDN didn't have so many issues.  I guess SourceForge is the main player in the shared project space -- but for something as minor as I'm suggesting it might be better off just posted as an EXE somewhere on CodeBetter.  I'll give it some thought.

  • Schiavo and VB6 expire on the same day

    Today, March 31st 2005, marks the final day of free support for VB 6 by Microsoft.  It's caused quite a stir in some circles, most notably the petition for Microsoft to re-align "it's long-term strategies with those of its customers."  Signatories would rather have Microsoft invest money in keeping a parallel VB6 compiler and IDE current (this is part of what the petition suggests) instead of pursuing innovation and improvement in the .Net direction -- and don't give me the "Microsoft should do both" talk because you, too, can do both: keep your VB6 CDs and service packs around and you'll be able to continue to do VB6 stuff until all the DLLs rot away sometime in 2030.  They run side-by-side with the newer toys, at least it works on my machine.  A company the size of Microsoft can do what the petition proposes, but I'd rather have them looking forward and sort out performance in .Net and improve on SQL Server and enhance the Web Service architecture.  It's a zero-sum game folks: energy spent on VB6 stuff is energy not spent on all the other products.

    We've already seen Java saddled with backward compatibility woes (just one example here but there are myriad) and .Net already has some of it's own (DataGrid replaced by GridView and . . . maybe someday in .Net 3.0 we'll get the DataGridView that combines the two -- the point being a cluttering of the object model and controls).  Let's not bring VB 6 back from the dead and into the .Net IDE equation.

    I just saw where Schiavo was declared dead a few hours ago . . . that's a ghastly situation that's now behind us [hopefully].  In the same spirit, hasn't VB6 been through enough?  Yes, that's an insensitive comparison -- but a bizarre coincidence -- just send your comments to Brendan because he lets me keep this blog around.  Yes, I've drank the .Net kool-aid but why haven't you?  I'm much more productive with .Net and my apps are more professionally developed, tested, deployed, and maintained thanks to the .Net family.  Any new development I do is almost always in .Net unless the customer is extending an existing legacy app and even then I'm always looking for ways of strangling the old app with .Net.  As a last resort, I fire up the VB6 IDE and take a trip down memory lane.

  • 3 Lessons from TechEd (and Secret TechEd)

    I agree with Brendan that TechEd is too pricey for my blood.  Thanks to INETA, I got to go last year and I had a great time, but it wasn't my dime.  Let me share some insight and demistify the TechEd experience.

    Lesson 1:  There are lots of salespeople at TechEd and, apparently, lots of people keen to collect all the cheesy free things the salespeople are giving away.  I don't get it since the salespeople must know the leads they get at TechEd are mostly junk, but it must pay off on some level.  Does the company get a viral marketing buzz?  Maybe the salespeople are just as happy to be in a sunny and pleasant town for a week?

    Lesson 2:  There are lots of casual techies there -- project managers or junior developers, ones who don't open a technical book or read weblogs or explore technology on their own time very much.  For these folks, the sessions on "what is Sharepoint" and "DataSets vs Custom Objects" are ground breaking and truly new news.

    To me, lesson 1 and 2 are NOT worth the $2,000 price tag; especially if you are already up on the latest in technology.  Most of the sessions will be review, but there will still be a few great sessions that you should catch like Jeffrey Richter, Eric Gunnerson, and Don Box -- do the math, and even if those 3 guys do 2 sessions each (which they probably don't), thats 6 great talks for $2,000 . . . I can wait for the DVD.

    Lesson 3:  There is a Secret TechEd that takes place beyond the conference rooms.  This is the lunches and after-hours parties, some invite-only, where authors, speakers, and Microsoft big shots talk shop and build relationships.  Sometimes it's a group of 2 or 3, other times it's a hotel room overflowing with 50 people.  This is the good stuff, the stuff you can't get from reading MSDN or taking a few hours each weekend to play with ASP.Net 2.0.  This is fun!  I know many tech-ed attendees who never experience this, and I was only on the periphery of this secret TechEd. 

    The catch is, you can't buy admission to Secret TechEd and you have to be in the right mindset to take advantage of it.  Between WeProgram.Net, CodeBetter.com, and some other projects I'm feeling connected enough to save my money and time for other things.  For example, I will attend the Devscovery conference in Reston where nearly every session is a ball-buster from the likes of Jeffrey Richter and Johnnie "Flash" Robbins and the price tag is closer to Brendan's $600 threshhold.

  • Landscape printing your XSL transformed XML

    A friend of mine was trying to force a web browser to print in landscape for a specific XSL transformed XML page.  I mulled this over while on my lunch break and put together this little proof-of-concept when I got back; while it doesn't do ANYTHING to the printer, it renders the page at a different 90 degree angle so when printed it appears to be landscape format:
    First, a very simple XML data file (data.xml):

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <?xml-stylesheet type="text/xsl" href="Style.xsl"?>
    <data>
     <quote>
      <author>Socrates</author>
      <text>I drank what?</text>
     </quote>
     <quote>
      <author>Anonymous</author>
      <text>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
    incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
    nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
    Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
    fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
    culpa qui officia deserunt mollit anim id est laborum.</text>
     </quote>
    </data>

    Second, an XSL file that will transform the XML into our landscape view (Style.xsl):

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
      <html>
    <head>
    <style>
    div.page {
       writing-mode: tb-rl;
       height: 80%;
       margin: 10% 0%;
    }
    div.page p {
       margin-right: 80pt;
       filter: progid:DXImageTransform.Microsoft.BasicImage(Rotation=1);
    }
    </style>
    </head>
      <body>
    <div class="page">
      <h2>Quotes</h2>
      <xsl:apply-templates/>
    </div>
      </body>
      </html>
    </xsl:template>

    <xsl:template match="quote">
      <p>
      <xsl:apply-templates select="author"/>
      <xsl:apply-templates select="text"/>
      </p>
    </xsl:template><xsl:template match="author">
      Author: <span style="color:darkgreen">
      <xsl:value-of select="."/></span>
      <br />
    </xsl:template><xsl:template match="text">
      Text: <span style="color:navy">
      <xsl:value-of select="."/></span>
      <br />
    </xsl:template>
    </xsl:stylesheet>

    That's it.  It's just a matter of having a DIV tag styled with the appropriate attributes.  The "DXImageTransform.Microsoft.BasicImage . . ." is the critical bit of the style and, unfortunately, locks us into a browser with ActiveX support (basically just Internet Explorer).  The full docs on this BasicImage approach are here: http://msdn.microsoft.com/library/default.asp?url=/workshop/author/filter/reference/filters/basicimage.asp

    I've put these filters to good use on other projects, creating gradient backgrounds for tables (http://msdn.microsoft.com/library/default.asp?url=/workshop/author/filter/reference/filters/gradient.asp) and other clever UI stuff.  Remember, it's Internet Explorer specific.

     

  • If you tolerate something, you insist upon it

    Bob "Not Just The Coding Slave Guy" Reselman blogs about his interview with Microsoft and sneaks a real gem of a quote in near the end: If you tolerate something, you insist upon it (by the way, Reselman cites Jim McCarthy as being the source for this remark).

    This really got me thinking.  So often in work -- and life in general -- we're tempted to settle for the easy way out or to take the path of short term convenience.  In programming it usually bites you in the ass, turning January's easy fix into March's nightmare code overhaul.  Since we've recently added a new puppy to our household I'm hyper-sensitive to what we let the dog get away with; we can't tolerate her eating our cats, for example -- to the malleable puppy brain it's the same as if we're insisting upon her eating the cats!  If you tolerate something, you insist upon it speaks on many levels!

    In a way we're all these malleable puppy brains running amok . . .

  • Powerful Web Charting with NPlot

    I previously considered the free web charting component from Carlos Aguilar to be my main web chart tool . . . but I recently strayed and found a new web chart component.  NPlot has become my new main web charting squeeze because it gives me more control over the chart surface area, plotting behaviour, etc.  Carlos Aguilar's component is quick and simple and will still be useful for basic web charting, but NPlot is the more sophisticated alternative. 

    It's hard to describe unless you've worked with both charting tools, but I've got considerably more control when I use NPlot.  NPlot is still in development so you have to make due without much documentation and other polishes, but I really like what they've got so far.  NPlot has a much more scientific aspect to it, with Abscissa and other slick math nerdy things.  A project I'm working on requires some scientific data presentation and NPlot gives me the control I need and the customer wants. 

    Since the docs aren't available yet, here's a snippet that will get you up and running:

    • Set a reference to the NPlot assembly (NPlot.dll) -- assuming you've downloaded the files from http://netcontrols.org/nplot/
    • Add a PlotSurface2D control on your web form (drag and drop it or manually add it with the Register ASPX Page directive and add the control tag "<cc1:PlotSurface2D id="surface" runat="server" Width="200px" Height="100px"/>" to your web form
    • Here is the quick-and-dirty sample code for your page Load event (in VB -gasp- since our customer requested we work in it):

    surface.Title = "My Title"
    Dim lp As LinePlot = New LinePlot
    lp.DataSource = New Integer() {1, 5, 3, 4}
    lp.Color = Color.RosyBrown
    Dim dates As ArrayList = New ArrayList
    dates.Add( CDate( "11/1/2004" ) )
    dates.Add( CDate( "11/11/2004" ) )
    dates.Add( CDate( "11/27/2004" ) )
    dates.Add( CDate( "12/1/2004" ) )
    lp.Color = Color.Blue
    lp.AbscissaData = dates
    surface.Add(lp)
    surface.XAxis1.Label = "x-axis label"
    surface.Refresh()

    Oh yeah, if you want another reason to check out NPlot, it looks like the developers (Matt Howlett and Paolo Pierini) are into the Mono project after a fashion -- I don't know the full pedigree, I just know I can get great web reports out of it.  Keep up the great work!

  • Blog Quandary

    Here's the scenario:

    • The blog helps secure a contract with a customer; the blog's tech content helped to sell the customer.  This is wonderful!
    • The contract with the customer has aggressive timeframes that involve overtime etc.  Project can't be done soon enough.  This isn't wonderful, but fairly typical.
    • The blog is now used as a barometer of how busy the blogger is: if the blogger has time to blog then they have time to rename these columns and tackle all the other items on the todo list.  Translation: time spent blogging is time not spent on the contract and, therefore, time wasted in the eyes of the customer.

    Has anybody else been stuck in this quandary?  Blogging is good for business . . . but blogging is bad for the blogger.  I don't think a frequent blogger is an unproductive worker (necessarily!), but I've heard of Human Resource issues around bloggers posting and so on.

    I'm thinking one approach is to queue up all the blog posts until the contract ends and then let them loose like a dam breaking . . . maybe one every 12 hours or so until they're all out there.  The problem is, what happens when the contract renews . . . I think a more sustainable compromise is necessary.

  • Are you an Enterprise Manager Addict?

    I sure am.  It's so much easier than remembering all the SQL syntax for editing tables, setting up indexes, etc.  I learned this -for about the 100th time in my career- over the last week when we started to get the invalid cursor state errors identified in this KB article: http://support.microsoft.com/default.aspx?scid=kb;en-us;831997

    We're not sure why it started, but last week any data schema changes we made through Enterprise Manager would fail and give us the above error.  We could make our changes in SQL Query Analyzer, sure, but using that philosophy I should be writing my .Net code in Notepad and compiling from the command line instead of using VS.Net.  Just because you can do something doesn't mean you should.  SQL Enterprise Manager is a huge productivity boost and frees my brain from remembering the SQL syntax for indexing and other dba minutia. 

    It took about 3 days of prodding before the powers-that-be relented and decided getting the hotfix was the way to go; they were understandably concerned about having a non-standard database build on the server, but I dare you to show me a truly "standard" db build except for one that comes straight from the installation disk.  Applications are installed, uninstalled, and updated over time and dlls, the registry, and other services get configured so that eventually a server is a complicated spider web of deviations from "the norm." 

    It does concern me, however, that this hotfix isn't freely down-loadable from the web . . . just the sort of thing that might bite us in the butt when we're making changes to other parts of the server.  Regardless, we jumped through the hoops with Microsoft Dev Support (1-800-936-5800) and got the hotfix and resolved the issue.  Enterprise manager is back and I can dump any of that SQL admin syntax that my short term memory may still be storing!

  • CodingWorse (at least slightly) with MsgBox

    My previous post pointed out the shortcomings of using Try-Catch blocks to handle situations that are not truly exceptional.  In the same vein I offer this opinion on the VB.Net MsgBox() function -- note I say opinion because this time I don't have the astounding perf numbers to back me up.  Here goes . . .

    I was eating dinner tonight and showing a friend of mine a little VB.Net code.  Yes, that's right -- a buddy stopped by and we were huddled around the laptop for a little nerdery and eggplant parmesan.  This friend of mine does some Access development and I've been working on bringing him into the .Net fold.  We got sidetracked for about 30 minutes on why I don't use MsgBox() and, instead, use MessageBox.Show().  While some will say it's only a matter of preference, I think it's more than that.  MsgBox is the Visual Basic wrapper around the .Net Framework's MessageBox.Show method -- there is a tiny bit more overhead to MsgBox, but it's negligible especially when you consider you're halting your program to display a dialog box to the user!  I can't really play the perf card here.

    I think my two main issues with MsgBox are:

    1. It reminds me of old VB6 and VBA days (like with Access); it carries a stigma of belonging to a bygone era.  Comparing the IL for functions with MsgBox() and MessageBox.Show() is strikingly different: the MsgBox alternative calls into Microsoft.VisualBasic while MessageBox.Show() calls System.Windows.Forms.  This might be a very very academic point, but I just get a warm and fuzzy feeling with System.Windows.Forms compared to Microsoft.VisualBasic.
    2. I do a lot of C# programming and there's no MsgBox there!  By learning the true .Net Framework I'm making my life easier -- it's more like I'm programming in only one language instead of VB.Net sometimes and C# at other times.  I think Jeff Richter of Wintellect was the first to proclaim that all .Net developers are really programming in the same language.  The Base Class Library is common to all .Net developers and the type systems can be coded the same (I could use System.Int32 instead of int or Integer -- and I did that for a while until I decided that was taking things too far).  I can use the Show method of the MessageBox object in any .Net compliant language (even with Darrell's recent Python fixation!).

    Call me a snob, but I know if I was reviewing code for a new hire and saw MsgBox() in their VB.Net code, I'd have a slightly -- just ever so slightly -- lesser opinion of the code.  If it came down to two identical candidates, one MsgBoxer and one MessageBox.Shower, I'd hire the MessageBox.Shower for sure.  MSDN even says MessageBox.Show is preferred

    I realize this is hardly a CodingWorse scenario on par with the previous try-catch transgression, but MsgBox just rubs me the wrong way. 

     

  • CodingWorse with a try{}catch{} solution?

    I used to teach in a technology program at ODU (until the university sold the program . . . but that's another story); I still get questions emailed from students about the “right” way to program things etc.  The latest question was about the lack of an “IsNumeric” function in C#; as you probably know, VB.Net has an IsNumeric() function that returns a boolean for if a number is numeric or not.  While VB.Net's IsNumeric() function is hardly rocket science, it is a very useful function for testing your strings.

    Anyway, C# is a little more “roll-up-your-sleeves” and solve your own problem, so there is no equivalent IsNumeric function in C#.  This former student of mine asked if the following was an acceptable alternative:

    public static bool isNumeric( string strText )
    {
     try
     {
      int i = int.Parse( strText ) ;
      return true ;
     }
     catch
     {
     return false ;
     }
    }

    What's wrong with this picture?  This is classic lazy-programming (or, in this case, just inexperienced programming) because the person knows enough about C# to use try{}catch{}, but is using it inappropriately.  Exceptions are for exceptional situations -- not for avoiding some real thinking through the issue.  Catching exceptions is hard work on your programs and performance will really suffer: this try{}catch{} isNumeric() function is over 2,000 times slower than this alternative:

    public static bool isNumeric( string strText )
    {
        char[] chars = strText.ToCharArray() ;
        for ( int i = 0; i < chars.Length; i++ )
        {
            if( !Char.IsDigit( chars[ i ] ) ) //could also explore IsNumber
            {
                return false ;
            }
        }
        return true ;
    }

    The good ol' Char class has a baked in IsDigit() function that will also handle localized definitions of numbers; this version of isNumeric() will work with Cyrillic defined numbers as well as our “conventional” numerals -- assuming the system is setup for the appropriate region/locale.  This function requires a bit more typing, but iterating over every character in a string and testing for that character's “IsDigit-ness” is 2,000 times faster than the try{}catch{} solution.  Of course, your mileage may vary based on the length of the string you're comparing etc (I used strings of 10 characters in my tests).

    If blinding perf is what you're after, this is the alternative isNumeric function you want:

    public static bool isNumeric( string strText )
    {
        char[] chars = strText.ToCharArray() ;
        for ( int i = 0; i < chars.Length; i++ )
        {
            if ( chars[ i ] > 57 || chars[ i ] < 48 )
            {
                return false ;
            }
        }
        return true ;
    }

    You lose the universal comparison logic built into Char.IsDigit(), but this is over twice as fast as the previous alternative (and fully 5000+ times faster than the original try{}catch{} function).  Exact statistics are at the bottom of this post.  If your app will only run on machines where characters 48-57 will be numeric -- like with our western number system -- this is the moet et chandon of the IsNumeric() world.

    Yes, you can call into the VB.Net library to get to that IsNumeric() function; this will be slow, too.  Besides, I know some C# die-hards that would rather eat their own young than call a VB.Net library intentionally.  I've also omitted a Regex isNumeric() alternative and a few others, but I didn't set out to write the definitive study on isNumeric for C#.  Originally, I wanted to demonstrate that the “quick-and-dirty” try{}catch{} coding solution to this problem is for those who want to CodeWorse -- and since my blog is now on www.CodeBetter.com I figured I better get with the program!

    So, using perf monitoring like in this post and a little ILDasm:

    • The try{}catch{} CodeWorse approach took 43 seconds to run through 30,000 test calls to IsNumeric where 66% of the strings were not numeric (meaning, 66% return false).  That's a lot of exceptions!  The IL for the function has 2 calls into MSCorLib and the perf-crushing IL try-catch handlers.
    • The Char.IsDigit approach took only .0171 seconds to run through the same 30,000 test calls.  This approach still has 2 calls into MSCorlib in the IL, but none of the try-catch handlers to cause pain and perf agony.
    • The simple character comparison array loop was the fastest for these 30,000 calls at .0078 seconds.  Only 1 MSCorLib call.  No try-catch nonsense.

    Can you hear me in the back?  The time it takes the try{}catch{} “solution” to work in a loop situation can be measured in whole seconds (perhaps minutes!) while the other approaches only take fractions of fractions of seconds. I can literally type the entire “verbose” character comparison array loop solution in Visual Studio in the time it takes the try{}catch{} “solution” to run -- so don't give me any “quick and dirty is fine” stuff here.  It's just inexperience or laziness that would have you CodingWorse with try{}catch{} blocks.

  • the Bob's blog

    Author of Coding Slave, Bob Reselman (aka “the Bob“), is joining the blog community with his Coding Slave blog: http://codingslave.blogspot.com/.  It's “the Bob Blog.”  Say it 10 times fast . . .  It's part socratic introspection, part social commentary, with a dose of technology thrown in.  Rosa Luxembourg would be proud (google it if you don't know who she is): “Love of your own country is patriotism; love a country owned by others is not patriotism, but something else.“   

    Check it out if you're in the mood for something smart and semi-colon free (meaning, it's not just about programming).  I was lucky to grab a meal with “the Bob“ last year and he is an unabashed deep thinker in a world that could use a lot more deep thinking. 

    In my opinion, one great reason to follow blogs is to foster critical thinking about topics you may not otherwise consider.  This may come as a surprise, but it's not just about finding code you can copy-and-paste.  Go on and take the red pill . . . or was it the blue pill?  I forget.  Check out The Bob's blog.

     

More Posts Next page »