Archives

Archives / 2008
  • Getting jQuery to work with MasterPages - Code Junkie

    Jared Roberts asked a question today on his blog about using jQuery with ASP.NET Master Pages (Getting jQuery to work with MasterPages - Code Junkie). Master Pages present some interesting problems. Because the Content Page could live at a different directory level than the Master you can quickly run into issues with relative paths breaking.

    The solution is to place your scripts references into a ScriptManager on the Master Page. This ScriptManager will render the proper <Script> tags for you at runtime. For example:

    <asp:ScriptManager ID="ScriptManager" runat="server">
    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">Scripts</span><span style="color: #0000ff">&gt;</span></pre>
    
    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none">        <span style="color: #0000ff">&lt;</span><span style="color: #800000">asp:ScriptReference</span> <span style="color: #ff0000">Path</span><span style="color: #0000ff">=&quot;~/js/jquery-1.2.6.min.js&quot;</span> <span style="color: #0000ff">/&gt;</span></pre>
    
    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">Scripts</span><span style="color: #0000ff">&gt;</span></pre>
    
    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #0000ff">&lt;/</span><span style="color: #800000">asp:ScriptManager</span><span style="color: #0000ff">&gt;</span></pre>
    

    The downside of this is that your Content Pages will lack Intellisense for the scripts you’ve referenced. The workaround for this is to give the designer a reference it can use at design time but that won’t render at runtime. This is done by placing the following code into your Content Page:

    <%
       if (false) { 
    %>
    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">script</span> <span style="color: #ff0000">src</span><span style="color: #0000ff">=&quot;../js/jquery-1.2.6-vsdoc.js&quot;</span> <span style="color: #ff0000">type</span><span style="color: #0000ff">=&quot;text/javascript&quot;</span><span style="color: #0000ff">&gt;&lt;/</span><span style="color: #800000">script</span><span style="color: #0000ff">&gt;</span></pre>
    
    <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="background-color: #ffff00">&lt;%</span><pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><p>   } </p></pre><span style="background-color: #ffff00">%&gt;</span></pre>
    

    This gives you properly pathed <Script> tags at runtime and JS Intellisense at design time. This also works with User Controls where you’re using a ScriptManagerProxy and want Intellisense support.

    As an aside, the <% if (false) { %> trick is useful for other design time content. We’ve used it to reference style sheets when building user controls. It lets the control developer get a good visual of what the final control might look like but allows the final styles to be controlled by the page hosting the control.

  • Office Communication Servers moves to 64-bit only

    The Office Communication Server team announced Friday that OCS 2007 R2 will support 64-bit operating systems only.

    As a part of the broad initiative across Microsoft to support 64 bit versions across many of its product lines, the next release of OCS will support 64-bit operating systems only. This decision will help meet customer demand and is a natural progression of the product that aligns with the same approach taken by the Exchange team (with Exchange 2007) and the SharePoint team (with SharePoint 2007) to support 64 bit operating systems only....

    Read full article

  • Windows Live Writer 2009

    I updated my Windows Live Writer to the 2009 release candidate today. I’ve been a fan of WLW for a long time and this update seems like a nice incremental step forward. Scoble seems to like it too.

    You can download the new version from http://windowslivewriter.spaces.live.com/. It includes updates to the entire library of Windows Live applications (including a nice update of Messenger)

    The only thing on my wish list is built in support for cross-posting to multiple blogs.

  • I Snapped My Chrome!

    One of the more interesting features in Google’s new Chrome browser is “Application Shortcuts”. These are web site links that Chrome places on your Start menu, Desktop and/or Quick Launch bar. When launched they open with a trimmed down UI, giving the web application a decidedly “desktop” feel. I’ve created shortcuts for a number of applications, including my GMail account.

    Today, while responding to an email, I got what is best described as a “black screen of death”. Chrome informed me that “Ah, Snap! Something went wrong while displaying this webpage. To continue, press Reload or go to another page”.

    Aside from being a rather silly error message, it tells me nothing of value. I don’t know what went wrong. It doesn’t help me diagnose if it was Chrome that failed or the site it was viewing. And the methods suggested for resolving this error are not valid in “shortcut mode” as there are no toolbar items to press or URL boxes to navigate with.

    One aspect of this message that I like is that it assumes the user isn’t an expert. It doesn’t shove a bunch of technical information at the poor user who cannot do anything with it anyway. Why needlessly make things confusing?

    The problem is that they didn’t give any obvious way to get at the technical information for those who can make use of it. And if you’re going to go with the simplicity route then you need to make sure your error message gives a working resolution to the user. That novice user isn’t going to make the same assumption that I did and press F5 to reload the page.

  • My First Chrome Experience

    My inbox has been flooded with emails asking me to blog about my opinion of Chrome. That is if you consider "flooded" to be one more than zero. And you include the email I sent to myself from work as a reminder to give it a shot...

    Ok fine. No one asked. And even less likely care. But guess what, you're getting it anyway.

    What I liked...

    The download is a wonderfully small 475 KB. The same cannot be said for either IE or Firefox.

    I was impressed with how quickly Chrome opened for me. Both IE and Firefox take between 3 and 5 seconds to load on my Vista machine. Chrome however opens instantly.

    One feature that sticks out is the default home page. Rather than a search page like Firefox or that bloated MSN page from IE, you get a slick UI with personalized content on it. The "Most visited" site section is reminiscent of the XP and Vista start menu's listing of most commonly used applications. And having bookmarks displayed is also a nice touch.

    Overall I'd have to say that Chrome is very quick and responsive. Pages render quickly and (from my limited testing) without any major issues.

    What I didn't...

    One major flaw in my view is that the default home page, while innovative, lacks any control over what gets displayed. If you search Monster regularly for example then it is going to show up on your home page. While convenient in some circumstances, imagine your manager walking past your desk and seeing a screen shot of Monster at the top of your list. And I've been told that some people have been known to use the net for more "adult" activities. Wouldn't that go over well when you open your browser during your quarterly sales presentation.... 

    As a research project Chrome has some real value. If the benchmarks they present are accurate they have made some major improvements to JavaScript processing. But they are talking about it in much grander terms than just a research project. They seem to be positioning it as a first-class browser to replace IE, Firefox and the rest.

    I'm still not sure why I should care. I've never felt an overwhelming desire to get a new browser. I use Firefox and IE and find very little difference between the two. I don't really see what market need Google is trying to fill here.

  • Executing a Speech Server Workflow via the API

    In my previous post I outlined a basic framework for using the Core API for Speech Server 2007. Today I'll outline how to mix both the API and Workflow models by calling out to a workflow using the API and returning control back when it is complete.

    If you are interested in the complete project code you may download it here.

    I'm starting with the same basic framework from my last post. To this I'm adding a simple Voice Response Workflow with a single Statement activity. Rather than calling the synthesizer from the API, I'm going to use the Statement activity inside the workflow.  We're going to pass in the text we want it to play at runtime.

    1) The first thing we need to do is add a new Voice Response Workflow to the project. Too this we'll add a single Statement activity. Because we've established the call using the API there is no AnswerCall, MakeCall, or DisconnectCall activities in this workflow.

    image

     

    2) Now that we have our really-big-and-complex workflow ready, we can start adding some code to set the prompt. The first thing we need to do is add a handler for the TurnStarting event. This is where we will assign the Main Prompt property for the activity.

    3) Next we need to add a property to pass in our input parameters too. We'll call this MyPrompt. The resulting code behind should look like the following:

    using System;
    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.Collections;
    using System.Diagnostics;
    using System.Drawing;
    using System.Workflow.ComponentModel.Compiler;
    using System.Workflow.ComponentModel.Serialization;
    using System.Workflow.ComponentModel;
    using System.Workflow.ComponentModel.Design;
    using System.Workflow.Runtime;
    using System.Workflow.Activities;
    using System.Workflow.Activities.Rules;
    using Microsoft.SpeechServer.Dialog;

    namespace VoiceResponseWorkflowApplication2
    {
        public sealed partial class Workflow1: SpeechSequentialWorkflowActivity
        {
            public Workflow1()
            {
                InitializeComponent();           
            }

            private string _myPrompt;
            public string MyPrompt
            {
                get { return _myPrompt; }
                set { _myPrompt = value; }
            }

            private void statementActivity1_TurnStarting(object sender, TurnStartingEventArgs e)
            {
                statementActivity1.MainPrompt.SetText(MyPrompt);
            }
        }
    }

    4) Now we need to add some code to kick off the workflow. We'll do this from within the OpenCompleted event handler in Class1.cs. This code establishes an input parameter Dictionary<>, instantiates the workflow object, and starts the workflow. We'll add a handler for the WorkflowCompleted event so that we can cleanup the call once the workflow is done. 

    Dictionary<string, object> inputParam = new Dictionary<string, object>();
    inputParam.Add("MyPrompt", "HelloWorld");
    myWorkflow = SpeechSequentialWorkflowActivity.CreateWorkflow(_host, typeof(Workflow1), inputParam);
    myWorkflow.WorkflowRuntime.WorkflowCompleted += new EventHandler<WorkflowCompletedEventArgs>(WorkflowRuntime_WorkflowCompleted);
    SpeechSequentialWorkflowActivity.Start(myWorkflow);

    One interesting item here is the inputParam object. The way this works is that you pass in parameters to the workflow and it assigns the values to the corresponding public properties of the workflow. If you pass an input parameter for which there is no property you will get an exception.

    The complete Class1.cs:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using Microsoft.SpeechServer ;
    using Microsoft.SpeechServer.Dialog;
    using System.Workflow.Runtime;

    namespace VoiceResponseWorkflowApplication2
    {
        public class Class1 : IHostedSpeechApplication
        {
            private IApplicationHost _host;
            private WorkflowInstance myWorkflow;

            public void Start(IApplicationHost host)
            {
                if (host != null)
                {
                    _host = host;
                    _host.TelephonySession.CurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo("en-US");

                    // Dial and outbound call (make sure you change these numbers :-)
                    _host.TelephonySession.OpenCompleted += new EventHandler<AsyncCompletedEventArgs>(TelephonySession_OpenCompleted);
                    _host.TelephonySession.OpenAsync("7813062200", "8887006263");
                }
                else
                {
                    throw new ArgumentNullException("host");
                }
            }

            void TelephonySession_OpenCompleted(object sender, AsyncCompletedEventArgs e)
            {
                if (e.Error != null)
                {
                    _host.TelephonySession.Close();
                }
                else
                {
                    Dictionary<string, object> inputParam = new Dictionary<string, object>();
                    inputParam.Add("MyPrompt", "HelloWorld");
                    myWorkflow = SpeechSequentialWorkflowActivity.CreateWorkflow(_host, typeof(Workflow1), inputParam);
                    myWorkflow.WorkflowRuntime.WorkflowCompleted += new EventHandler<WorkflowCompletedEventArgs>(WorkflowRuntime_WorkflowCompleted);
                    SpeechSequentialWorkflowActivity.Start(myWorkflow);
                }
            }

            void WorkflowRuntime_WorkflowCompleted(object sender, WorkflowCompletedEventArgs e)
            {
                _host.TelephonySession.Close();
            }

            public void Stop(bool immediate)
            {

            }

            public void OnUnhandledException(Exception exception)
            {
                if (exception != null)
                {
                    _host.TelephonySession.LoggingManager.LogApplicationError(100, "An unexpected exception occurred: {0}", exception.Message);
                }
                else
                {
                    _host.TelephonySession.LoggingManager.LogApplicationError(100, "An unknown exception occurred: {0}", System.Environment.StackTrace);
                }

                _host.OnCompleted();
            }
        }
    }

    (download the zipped project here)

  • Getting Started with the Speech Server 2007 API

    Speech Server 2007 has a really cool Windows Workflow based programming model that lets you quickly build interactive voice response applications. For many applications it is all you will ever need.

    Sometimes however you find the workflow model just isn't the right fit. If you're looking for really fine-grained control over the application, or you simply prefer to work in code, then the Core API is what you need.

    Unfortunately figuring out you want to use the API is a lot easier than figuring out how to start using it. There is very little documentation and no Visual Studio project templates or samples included with Speech Server.

    I'll do my best to give a brick-simple explanation of how to get your first core API project started. You can also download the zipped project files.

    1) First you'll need to create a new Voice Response Workflow Application. We'll use the project that gets generated as our foundation.

    image

    2) When asked for the application resources you'll want to uncheck everything.

    image

    3) Open up the Class1.cs file and remove all of the references to the VoiceResponseWorkflow1 class. The resulting class should look like the following (I removed the comments in the code for brevity):

    using System;
    using System.Collections.Generic;
    using System.Text;
    using Microsoft.SpeechServer ;
    using Microsoft.SpeechServer.Dialog;

    namespace VoiceResponseWorkflowApplication1
    {
        public class Class1 : IHostedSpeechApplication
        {     
            private IApplicationHost _host;

            public void Start(IApplicationHost host)
            {
                if (host != null)
                {
                    _host = host;
                    _host.TelephonySession.CurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo("en-US");
                }
                else
                {
                    throw new ArgumentNullException("host");
                }
            }
            public void Stop(bool immediate)
            {
            }

            public void OnUnhandledException(Exception exception)
            {
                if (exception != null)
                {
                    _host.TelephonySession.LoggingManager.LogApplicationError(100, "An unexpected exception occurred: {0}", exception.Message);
                }
                else
                {
                    _host.TelephonySession.LoggingManager.LogApplicationError(100, "An unknown exception occurred: {0}", System.Environment.StackTrace);
                }

                _host.OnCompleted();
            }
        }
    }

    That's all folks. Class1.cs is now the starting point of your Core API application. As a further example, lets take the project and add some code to turn it into an outbound dialing "Hello World" application.

    using System;
    using System.Collections.Generic;
    using System.Text;
    using Microsoft.SpeechServer ;
    using Microsoft.SpeechServer.Dialog;

    namespace VoiceResponseWorkflowApplication1
    {
        public class Class1 : IHostedSpeechApplication
        {     
            private IApplicationHost _host;

            public void Start(IApplicationHost host)
            {
                if (host != null)
                {
                    _host = host;
                    _host.TelephonySession.CurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo("en-US");
                    // Dial and outbound call (make sure you change these numbers :-)
                    _host.TelephonySession.OpenCompleted += new EventHandler<AsyncCompletedEventArgs>(TelephonySession_OpenCompleted);
                    _host.TelephonySession.OpenAsync("7813062200", "8887006263");
                }
                else
                {
                    throw new ArgumentNullException("host");
                }
            }

            void TelephonySession_OpenCompleted(object sender, AsyncCompletedEventArgs e)
            {
                if (e.Error != null)
                {
                    _host.TelephonySession.Close();
                }
                else
                {
                    _host.TelephonySession.Synthesizer.SpeakCompleted += new EventHandler<Microsoft.SpeechServer.Synthesis.SpeakCompletedEventArgs>(Synthesizer_SpeakCompleted);
                    _host.TelephonySession.Synthesizer.SpeakAsync("Hello World", Microsoft.SpeechServer.Synthesis.SynthesisTextFormat.PlainText);
                }
            }

            void Synthesizer_SpeakCompleted(object sender, Microsoft.SpeechServer.Synthesis.SpeakCompletedEventArgs e)
            {
                _host.TelephonySession.Close();
            }
            public void Stop(bool immediate)
            {
            }

            public void OnUnhandledException(Exception exception)
            {
                if (exception != null)
                {
                    _host.TelephonySession.LoggingManager.LogApplicationError(100, "An unexpected exception occurred: {0}", exception.Message);
                }
                else
                {
                    _host.TelephonySession.LoggingManager.LogApplicationError(100, "An unknown exception occurred: {0}", System.Environment.StackTrace);
                }

                _host.OnCompleted();
            }
        }
    }

    (download the zipped project)

  • Scoble Scale?

    Robert Scoble has an interesting post in response to Om Malik's suggestion that Twitter start charging "Super Users". Scoble would qualify as an edge-case when comes to social network . He has a history of hitting the limits like these on MSN Messenger and Facebook.

    Charging seems like an acceptable action to take for users like Robert who use these services at such a level. Robert is obviously getting business value out of these services and it is perfectly reasonable to get revenue from that. But I agree with Robert when he says that this won't completely solve their scalability problems. The amount they would have to charge would likely exceed the value of the service.

    I also hope that Robert is correct in his assertion that Twitter's problem isn't caused by how it manages the data. If Assetbar is correct in his description then Twitter has a problem. I have no knowledge as to how Twitter works under the covers but I sure hope Assetbar's description isn't accurate.

    I think we need to add another level to our description of scale: Small, Large , Enterprise and now Scoble Scale. Maybe he should rent himself out as a testing framework for social networks...

  • VoiceXML on Speech Server

    Yesterday I posted about an issue with Speech Server and Vista. One reader named Bill asked a question in the comments. My response was a bit long for a comment so I decided to turn it into a separate post instead.

    Hey Marc, are you using Microsoft Speech Server with VXML?  If so, what hardware are you using on it?  Also, does MSS support CCXML?
    -Bill

    Yes, I'm using quite a bit of VoiceXML. Most of the applications I work on are written to run against the Nuance Voice Platform. I've been using VXML so that I could run them against either platform (or any other platform for that matter).

    There are some issues that I ran into where I was using Nuance specific properties (example) that Microsoft doesn't have VXML equivalents for. In those cases I needed to write them using the Speech Server managed model.

    The key thing to keep in mind is that Microsoft has implemented the VXML spec pretty much verbatim. So as long as your application is pure VXML you should be fine.

    I haven't put Speech Server through any sizing tests so I'm not sure what the hardware requirements will be in the end. That said, my development machine is a DELL D830 with 4GB of RAM running Vista Ultimate. In the lab I'm using a DELL 1950 with 4GB of RAM running Windows Server 2003. In both cases I'm using a Dialogic DMG2000 gateway.

    As for CCXML, they don't support it and I don't see that changing. I actually think CCXML is going to go the way of SALT. With only Voxeo supporting a real CCXML implementation I don't think there is going to be a lot of call for it. Also, everything you would want to do with CCXML can be done using Speech Server's Managed API. This is just a guess on my part, I don't have any inside knowledge as to what Microsoft's roadmap looks like.

  • Reinstalling Microsoft Speech Server on Windows Vista

    If you're thinking of uninstalling/reinstalling Microsoft Speech Server on Windows Vista then this post might prove helpful.

    It seems that Speech Server Setup doesn't do such a good job uninstalling itself from Vista. And when you reinstall the server it fails to properly configure IIS. Namely it has a number of problems dealing with the *.speax exemption. This results it 404.2 and 500 errors being returned by IIS when you attempt to launch a Speech Server application.

    The workaround I've found for this issue requires manually mapping the handler for *.speax in your application's web.config. Adding the following to the <system.webServer> section will map IIS to the correct handler:

    <system.webServer>
    <handlers>
    <remove name="MSSCustomMap" />
    <add name="MSSCustomMap" path="*.speax" verb="*" modules="IsapiModule" scriptProcessor="C:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" responseBufferLimit="0" />
    </handlers>
    </system.webServer>

  • Notiva

    Around 18 months ago I started a new position with Parlance Corporation. I’m proud to say I've delivered my first product - Notiva.

    Essentially Notiva is an outbound messaging service which gives developers the ability to add voice, email, and SMS messaging to any application, infrastructure, or architecture with just a few lines of code.

    It has been a while since I've last rolled out a completely new product. This has been, without question, one of the most rewarding products I've every worked on. Frankly it has been an absolute blast to work on this.

    I'm really excited about Notiva and where it is headed. We're working on the final touches of a full application build on Notiva now. We've already had one partner integrate it into an existing product already.

    If you would like to give it a try you can drop me an email or check out www.notiva.com.

  • Wanted: Senior Software Engineer

    Parlance Corporation
    200 Boston Avenue, Medford, MA 02155
    www.parlancecorp.com

    Job Description: Senior Software Engineer

    Parlance is a small privately held company providing speech-driven call routing solutions and outbound messaging solutions to businesses of all sizes. To deliver these turnkey, managed solutions, Parlance uses a combination of comprehensive directory management tools, automatic speech recognition, computer telephony, data analysis tools, and dedicated customer service personnel.

    We are seeking a qualified senior software engineer to help us advance and expand the capabilities of Parlance's extensive tools software. Your primary mission will be to help design a new architecture for our service infrastructure, and then, using the latest technology, write, test, deliver, and support this new implementation of our mission-critical tools. You will also have the opportunity to work with speech recognition and VoiceXML, complex database systems and algorithms, user interfaces, computer telephony and much more, all in an environment where you are involved in the complete life-cycle of your work, from conception to deployment.

    We are looking for smart people that possess the eagerness and flexibility to learn new technologies and a commitment to delivering high-quality software. Experience in database programming is required, preferably with both Access and SQL Server. We are a small stable company where doing right by our customers is our daily mission. If you are looking for a position where you can take on new projects, and contribute more than just code, and want to help us change the way people communicate, Parlance is the place for you.

    Qualifications:

    • B.S. degree in Computer Science or equivalent experience
    • Minimum 6 years of experience
    • Significant programming experience with C#, ASP.NET, SQL Server, and Access
    • Understanding of Service Oriented Architectures, Web Services, AJAX, and Object-Oriented Design
    • Demonstrated analysis and troubleshooting skills
    • Excellent oral and written communication skills
    • Commitment to detail, quality, and customer focus
    • Experience with Python, C++/MFC, Java, XML, and VoiceXML a plus
    • Experience with both web and desktop GUI design preferred

    Compensation:

    • Salary commensurate with experience
    • 3 weeks of vacation
    • Medical benefits
    • 401(k) plan

    To apply, please send your resume and a code sample you are proud of to: job0314@parlancecorp.com.

  • New Year, New Resolutions

    Happy New Year!

    This whole "new year" thing is really interesting. I know it is really just an arbitrary milestone based on the rotation of a single planet around some star on the outskirts of one of the many galaxies. And yet I still can't help but feel a sense of renewal. What can I say? I'm a human being and we're a bit odd sometimes.

    So far 2008 looks to be one heck of a year. I'm expecting my 3rd child (and 2nd son) in April, I've got two products about to go into beta (more on them in the coming months), and a bunch of challenging new projects to architect involving everything from data centers to multi-language telephony. I'm very excited.

    I've also got a few new years resolutions:

    • Switch for black coffee. We're talking the difference between 150 calories and 15 here. At the rate I drink coffee I can afford an extra helping of Pad Thai on what I'll save!
    • Spend more time at home. I am notoriously bad at using my vacation time. I get wrapped up in projects and free time feels anything but free. For the last two weeks I've been home in order to use up my vacation time (how bad am I? I still have over a week to roll over). This year I'm going to use all my vacation time and maybe even work from home once and a while so I can save the two hours a day I commute. In the end I love my family and I'd rather they not forget what I look like.
    • Learn LINQ / Entity Framework. I've played with both an really love what LINQ brings to the table. I'm not so sold on the the Entity Framework but that I've never been a real ORM guy. I'm using WCF in one of my projects and plan to use LINQ in it as well.
    • Learn Ruby. Last year I spent some time picking up Python. This will fill my one language per year quota. Python is nice but I quickly figured our I'm a "bracket" guy. Although I do I have to say I found some serious problems with Python (and dynamic languages in general) that leave me still leaning towards compiled languages. I'll have to post my experiences and see what the community has to say - maybe the issues I've have can be mitigated (I hope so, I really like some aspects of dynamic languages).

    So there you go. I've now publicly posted my resolutions so I might just feel a bit more obligated to keep them this year. I wouldn't hold my breath. :)

    [update: fixed typo]