Wednesday, June 1, 2016

What Developers Should Know About Businesses


I think it’s important for a software developer to understand their boss’s motives to better align interests and goals so that career satisfaction is maximized, whether that’s developer happiness or hard cold cash. We’ll take a look at how businesses work and how this affects the developer. 

A quick note before we start: This mainly applies to businesses where there’s few layers of management. With more layers of management, the incentives get further and further away from the actual business goals, and it gets complicated.
  • Businesses need to make money. This is obvious, but sometimes we forget that the money coming in must be greater than money going out. Money coming in can be from sales, donations, investments, or any other kind of money coming in. If this gets flipped around, the business is in serious trouble. Thus, most businesses try to make this ratio nice and fat.
  • Developers are an expense. We may call it an "investment", but it's still money going out. Hence, it's generally required that whatever the developers produce bring some money in. Hopefully, the money it brings in is more than the money that goes out.
  • Features need to sell. Since any feature that developers produce cost money, every feature must sell. The "payment" may be more customers, higher prices, fewer refunds, less churn, or just more good-will from the community. Sometimes features that were projected to make money don't, so generally there needs to be a fairly good margin for each feature as well. Sometimes businesses can afford to throw away some money to make the executives feel good, but most things must sell.
  • Cash flow should be positive. Money in needs to be greater than money out on the long term, but it's also preferable that money in be greater than money out on the short term as well. It just makes every feel good to see the bank account go up rather than down. For developers, this means that giant projects that take a few years to see a return on investment are going to be hard sells, no matter how lucrative it is. 
  • Feature value is hard to measure. The average feature is just a small part of the overall product so it's very difficult to measure exactly how much money it'll bring in. This means that the business is often times just going by a gut feel of how much they feel like features helped. This means it's hard to quantify just how much money each individual developer is bringing in.
  • Developer productivity is hard to measure. Developers are very smart, and are generally good at finding edge cases. This means that any system for measuring developer productivity is fairly easily gamed. As a result, there is basically no way for anyone to objectively measure developer productivity. The only thing we have is the gut feel from a bunch of managers. Since the overall value of a developer highly depends on the manager's feelings, it's in the developer's best interest to make the manager feel very good about him/her. =)
  • Pay raise is a tool to improve retention. Pay raises are not about paying a "fair" wage to anyone. It's there so that valuable employees don't look elsewhere and take training or tribal knowledge with them. It's usually cheaper to pay a raise than to train someone new. Hence, the most powerful argument to a manager for a raise is not "I made the company super successful", but "I got a better offer elsewhere." This will probably cause some people to think you're not loyal, so figure out a different way of saying it. =)
  • Hiring is hard. Figuring out who to hire is very difficult. Training him/her takes a long time. Building team rapport takes time. All of this means most businesses don't want to fire developers. As long as you keep listening to your manager's feedback, you should have plenty of warning before getting canned.
  • Ideas are a lot more abundant than resources. At any healthy business, there's always a lot more ideas for improvement than there are resources to make it happen. This means priority is usually given to things that will make the most money, e.g. putting out fires that cause customers to leave and new paid add-ons. Lower priority will be given to things like automation, unit tests, and code cleanup.
  • Businesses love more data. A surprising portion of all business decisions are made on gut feels. Everyone would love some data to back up what they're saying, so it's good to see some reports on how things are doing. If you can get some quick reports for your manager, it'll probably make you look good and make him/her look good, too, increasing your "productivity" without too much work. =)

Wednesday, August 19, 2015

Dynamically vs Statically Typed Languages

There's a huge divide between programmers that like dynamic languages vs those that like static languages. The usual argument for dynamic languages is that it makes it so much easier to add things and change things. You don't need to bother with changing the types of things. They just work.

I strongly prefer statically typed languages now, but I used Python 2 for a number of years. Coming from C/C++, it was awesome. I loved the conciseness, and I didn't have to worry about declaring variables before using them. After my first 1-5AM debugging session where I mis-capitalized one variable, I began to waver in my position. After a few more debugging sessions where I wondered why my properties are undefined, I was beginning to hope for a better way. But I couldn't give up lambdas and list comprehensions. It was so much easier to describe things.

Fast forward a few years, and my first job was at a .NET shop. Although they used VB.NET, I fell in love with IntelliSense. It told me what was available and it was right 100% of the time, regardless of how I had made a typo. Back in Python land, I always had at least one browser window open to the docs to make sure I spelled everything correctly. I had just thought this was the way things worked. After getting IntelliSense, I don't need to worry about spelling anymore. Occasionally, I can even use a library without even reading the docs first! The types and names told me everything I needed to know, right there in my IDE.

Now I use a mix of .NET on the backend and JS on the frontend. When I need to rename something in .NET, I can use ReSharper and it'll just do everything for me. Sure it takes 30 seconds, but I'm chilling those 30 seconds. When I want to rename something in JS, I do a find all through all my files and go through each line to see if it's something I need to rename. If I want to change Name into FirstName and LastName, ... well, there are 1000 references. I say screw it, that feature is too expensive. They'll never split their names.

A huge annoyance with the loosely typed world of JS is how it tries to have method overloads, but in a really clunky manner. I would prefer a bunch of different function names, but the community has embraced a few idioms that mimic overloading. I am glad TypeScript is gaining momentum as we build larger systems out of JS.

There have been a few times when I thought a dynamic language would be good. When I'm prototyping a small program, it is pretty annoying to have to declare classes for everything. I think languages with more aggressive type inference than C# would probably help me out, here. C# doesn't allow me to have anonymous types across method boundaries. This is a huge pain in the butt. Even ReSharper doesn't make it completely seamless. I still have to think of a name when I generate a concrete type for the anonymous type. Unfortunately, these little projects grow to something bigger rather quickly, so I prefer to take the productivity hit (or use dynamic types in .NET) initially.

Another reason to use a dynamic language is that you can get macros with it. Sure some static languages have a little bit of macros sprinkled in, but nothing as awesome as Lisp. Unfortunately, it's impossible to get that level of language defining macro with static types. Several people are working on something close, but it's still icky. At the extreme end, you could pull some stuff from the network and have it generate something. Well, there's no way I can know the types ahead of time. I haven't seen many compelling reasons to use this aside from DSLs, so I don't really want to give up my static types for this.

For the near future, I'll be reaching for statically typed languages first.

Friday, June 19, 2015

SPAs Should Be Used Less Often

I've been building Single Page Apps (SPAs) for the past two years. I think they definitely have their place, but I think I, and many other developers, have used it a little too much.

Some developers (myself included) have said that any web application should be a SPA. WordPress type sites are fine as they are, but anything more complicated should be a SPA. There are quite a few good reasons including responsiveness, server side load, dynamic content, ease of porting to PhoneGap, client side load.

These are all great reasons, but I think they are often over stated. There are well known solutions for many of these for classic MVC (whether MS MVC, RoR, django, etc.) apps. These have been proven to work, and are solid.

When we go to SPA, we typically are granted a lot of "freedom". These freedoms are things that we often take for granted like:
  • loading bar
  • history
  • right click - open in a new tab
  • sharable URL
  • loading panel
  • error logging
Each of these things are things I had to reinvent for myself when doing SPAs. This is on top of SPA specific issues such as SEO, long initial page loads, and page full of spinners. The browser handles many of these things for classic MVC apps, but SPAs have the option to implement these or not. Many times, these are features that SPAs would like to have, but must reinvent or pull in a package for.

I think there should be a mix of JS heavy pages and classic MVC pages. We shouldn't throw out MVC on the server side just cause we can do it on the client.

The boundary I would like to draw is to leave routing on the server side, and have the client do dynamic things only on one page. Yes, there are things that I would love to have persist across pages, e.g. toasts that stay forever or user notifications that stay forever, but I would rather pull in one or two packages for these features rather than all those other features.

This would leverage most of the browser's features while giving us the flexibility to use a lot of JS to have dynamic content. Most pages I have done have few JS features that cross pages anyway. Within a single page, there is often a lot of dynamic content, but not many cross the page boundary.

I am hoping that soon there will be a framework out there that will solve this issue. It looks like most frameworks are still stuck on basic components like the best way to do binding, write web components, and decorate HTML with functionality. Hopefully there will be a clear winner in the next wave of web frameworks. Until then, I will be going back to MVC.

Thursday, June 18, 2015

WebAssembly

The 4 major browsers have come together to create WebAssembly (https://blog.mozilla.org/luke/2015/06/17/webassembly/), a binary compilation target for the web. This is very exciting news.

I see this as something like JVM for browsers. While not everyone loves Java, most people have really good things to say about JVM. You can compile your language down to Java bytecode and have it run everywhere. A major limitation of many languages is that it only runs where there is a virtual machine built for it. By compiling down to Java bytecode, the language can run anywhere.

JavaScript is the standard language of the web, but it is truly lacking. I firmly disagree with anyone who thinks JavaScript is a great language, but there are, unfortunately, no alternatives. TypeScript has gone a long way to fix many of JavaScript's issues, but there are still many things not fixed. I am hoping that WebAssembly will fix some of these issues. At the very least, it will let us cover over these issues with a better language. This is something I am eagerly hoping for.

Monday, October 20, 2014

MacBook Pro

I've been wanting a new laptop for a little while, now. I haven't been able to find the perfect laptop, yet, but the MacBook Pro comes fairly close.

Here are my requirements:
  • I need Windows for Visual Studio, SQL Server, and IIS. I guess IIS is optional, but since I have Windows already, might as well use IIS. This is mainly because I really like the way VS works, and SQL Server is fairly easy to use and configure.
  • I need an SSD drive. This is fairly obvious. The speed improvements are just crazy good. As an anecdote, my wife's machine was constantly trashing with only 4GB to offer to Windows 8 and her 50 Chrome tabs. Instead of upgrading her to 16GB of RAM, I decided to upgrade to an SSD. Now it's fairly responsive even with 100 hard faults/second. On the plus side, anything going to disk is fast. 
  • I want 16GB of RAM. I know I only gave my wife 4GB, but I plan on running VMs, and I want to give SQL the memory it loves. I really would like to upgrade this in the next 3 years as well.
  • I want over 4 hours of battery life. I had a nice laptop that only had 2 hours of battery, and it was pretty annoying at times.
  • I want a 15" or 17" screen. I already think 17" is small, but they don't make any reasonable 19" laptops.
  • I want a CPU with over 2000 on the single thread PassMark benchmark. Multithreaded benchmarks no longer mean much to me. I occasionally use 2-3 cores, but I don't really care how much the 8th core runs. I want whatever I'm doing to be fast, and I can't do that many things at once.
  • I want a trackpad that works well. I've used a few crappy trackpads. I had it permanently disabled on my other laptop, it was so bad.
  • I want 1920x1080. I think this is a perfect fit for a 17" screen. I guess I can settle for 1600x900 on 15", but I like having 500px on each side of the screen. This pushes right up against my medium line lengths. About 5% of my lines need more space. Retina screens are no good since they make everything super tiny or blurry.

The MacBook Pro meets most of these requirements, but misses a few:
  • The 15" comes only with a retina screen.
  • The RAM is soldered on. I don't really want to be removing solder from a $2500 laptop.
  • Doesn't run Windows out of the box.
If I put all my requirements together, the price range is around $2000-$2500. So I decided to just go with a MacBook Pro and see how it goes. Apple has a 14 return policy, so I'm going to see how it works in these two weeks.

So far, I've had these issues: 
  • I'm using Parallels since VirtualBox doesn't support Retina, and makes everything super blurry.
  • Battery life at 90% CPU and 90% disk was only 2 hours. That's a far stretch from the 8 hours advertised. I'm going to try using it with a lighter load today and see what happens. 
  • The different keyboard shortcuts are fairly annoying. For now, I'm just going to run everything in a VM. I also installed Karabiner to switch alt and win keys for the VM.

Sunday, June 8, 2014

ASP.NET vs RoR

ASP.NET? Why would anyone compare RoR to ASP.NET? The startup community has mostly dismissed ASP.NET based on the belief that Rails is a much more agile stack. Much of this applies to the Java stack as well.

One of the biggest reasons to not use ASP.NET is because it came from Microsoft. Some common gripes include not open source, letting Microsoft control your destiny, cost, and Windows servers. While this may have been true, Microsoft has recently open sourced a large portion of their system, and the cost is negligible for the first 3 years with BizSpark. Plus, the costs aren't that bad. When we look at the efficiency of .NET vs any Ruby platform, .NET is clearly fast enough to cover the Windows licensing costs. Some of the more adventurous ones will use Mono to run .NET on Linux, but I prefer the stability and speed of Microsoft's .NET over Mono. I will agree, however, Windows servers are annoying to manage. I haven't had experience with Linus machines, yet, but I don't like giving up so much of my RAM just to run Windows. I don't think Server Core is 100% ready, yet, since many non-Microsoft components still require the GUI.

Once we get over the fear of Microsoft, many people cite Ruby as one of the biggest advantages. Ruby being a dynamic language makes it the most agile. I wholeheartedly disagree with this one. I have loved Python for a few years, but that was because I was using C++. C# (and even VB.NET) has changed quite a bit over the years. C# is capable of being dynamic as well, but I don't like what I give up there. With type inference, lambda functions, extension methods, and LINQ, it's not that bad anymore.

Plus, I think the biggest gain to productivity is the compiler. I agree waiting 10 seconds to see a change reflected in the browser is annoying, but there's a huge number of tests I don't have to write because of the static type system. When I change something, I will know all the places I broke because the compiler knows. Moreover, I can't make typos anymore. Between IntelliSense and the compiler, it's impossible to type in a variable that doesn't exist unless I choose to be in the dynamic land. Those in the dynamic world would need to write a unit test for these things. I get them simply by declaring a class.

A huge draw for Rails is convention over configuration. I think this is great to a certain point. The obviously correct choices should be done by convention, or at least auto-generated configuration. However, I think there are many obscure conventions that at not obvious, and more importantly, not how I want them. For example, I don't want my view files in a separate folder from my controller files. Why can't I have them right next to each other like ASPX and code behind files? They are logically tied together, and separating them by location is just annoying. (This also applies to ASP.NET MVC, and it's very annoying in large projects.) Instead of setting a bunch of configurations to get started, I have to learn a bunch of conventions. Sure, like all other noobs, I will start by just glossing over all the magic, but they're going to come bite me later. I don't like getting bitten by decisions I didn't choose to delegate.

The huge library of gems lets developers get additional functionality for nearly free. This is also cool to a degree. The cost changes from re-inventing the wheel to learning documentation and traps. At least having gems gives me the choice of outsourcing the functionality or not. That's cool. The .NET world is sorely missing these gems. Something that helps alleviate this problem is that many integrations are now moving out of the core stack into JS libraries or web services.

But I am willing to try out Rails for a while to see if it's really as amazing as the community thinks it is.

Saturday, June 7, 2014

From Drupal to Rails

That fling with Drupal didn't last too long. I had hoped to do more with Drupal, but as I got to know it more and more (I addressed a few bugs we had), it became apparent that Drupal is a really good CMS. Since we are not centered around content, it didn't make sense to have a CMS there. Let's take a look at a few things wrong with Drupal.

The way Drupal was designed, it has horrible performance, but covers over it all with a lot of caching. This was really painful for me since I had to wait 10 seconds for my changes to render since I was constantly clearing the cache. I probably didn't need to clear all of the cache, but I didn't want to spend the time to figure out which caches I needed to clear. The main problem here is that we won't be able to cache much. (Or we will have a lot of cache invalidations flying all over the place.) We are expecting our content to constantly change.

No foreign keys. I had just come from a shop that doesn't use foreign keys, but the naming convention made it obvious which columns where referring to others. All foreign keys must have the same column name as the primary key. Drupal also has this convention, but the primary key column names are all three letters long, two of which are "id". So Node table has key "nid". That's cool if I only had 26 tables being referred to, but sadly there were 3 tables that could be the target of "aid", and I had no idea.

Drupal is very modular. With the modularity comes a lot of redirection. I know the hot thing for the past decade has been IoC, DI, interfaces, and all that stuff. That makes it hard for me and my IDE to follow what's going on. Things just happen automagically, and it hurts someone new like me.

Also along the lines of modularity, Drupal makes it sort of easy to assemble different pieces together. This is cool, but that means I had a lot of extra code that I wasn't using because we're just using one facet of many pieces to make things work. Free stuff can't be bad, right? But now there's more indirection, more tables filling up my object explorer, more possible security holes, and more options to possibly screw me over next time.

These reasons make it hard for me to work with Drupal. Nothing wrong with Drupal. We were just using it for the wrong purpose. So now we're moving to a lower level framework which will be fighting with me less.

So we were going to choose a new framework. Since I'm here to write an awesome app, not reinvent plumbing, I decided to go for one of the bigger ecosystems where every problem I will run into has already been solved. That leaves ASP.NET (the sharpest knife in my block), Java (open source alternative), RoR, or Django. Django and RoR are similar, so I chose the bigger ecosystem with RoR. I was kind of sad since I like Python a lot better than Ruby. ASP.NET and Java are fabled to more enterprise centric, so I landed with RoR, where the startup community is much more vibrant.

On my next post, I will go into why this was such a difficult decision for me. Mainly because the only reason I chose RoR is because of the community, while disagreeing with every other reason the community have for choosing RoR.