Developer Laptop Contenders, 2019

I had thought that my days of picking laptops were behind me when the Macbook Pro Retina won as The Best Polyglot Platform for the Money. It really wasn’t a contest. The only deficiency the Mac had was multiple monitor support; and that’s gotten a lot better over the years.

The reign of the MacBook Pro has ended with the advent of the Fourth Generation MacBook Pro line. Between the issues with the Keyboard, the lack of ports and requiring dongles for the most basic attachments (like connecting a USB keyboard to the USB-C port), and the fact that the power connector is no longer magnetic, the laptop is almost unusable from a developer’s perspective.

This is not easy news for me to take, as I’d really want to be able to use a Macbook now that I’m on my own, but I can’t in good conscience drop $5,000+ on a laptop that has these issues. And so, I’m in the market for a new laptop. I have my eye on three choices:

Dell XPS 15 (9570)

The Dell XPS 15 9570 is a solid Laptop. It even has the Stack Overflow seal of approval. One strange thing about it is its webcam placement. The webcam is located at the *bottom* of the monitor, not its top. It is the most economical of the choices; with the only downside that if I want an UHD display, I have to give up 16 GB of RAM. When I tried to customize it with UHD and 32GB of RAM, it wouldn’t work. That’s a bummer, as I think 32GB is a safe minimum for development.

Cost: $2389.99
Processor: Intel Core i7-8750H 6 Core (2.20 GHz up to 4.10GHz with Turbo Boost, 9MB Cache)
Memory: 32GB DDR4 2666 MHz
SSD: 512 GB SSD, M.2 PCIe-NVMe
Display: 15.6 FHD (1920×1080)
Graphics Card: NVIDIA GeForce GTX 1050Ti 4GB GDDR5

Alienware M15

Alienware is owned by Dell, and it is primarily a gaming laptop. As a developer, I’m OK with a gaming laptop, as they are generally better made than their business counterparts. I’m also OK with an advanced graphics card — not because I necessarily *need* one (though I would like to drive 4K displays); but because if I’m going to spend the money I might as well get a good value for my money. Some of the cons on the PC Mag review make me pause, especially around the touchpad. Overall, this laptop has a good monitor resolution, good sized ram, and isn’t too expensive for the option.

Cost: $4249.99
Processor: Intel Core i7-8750H 6 Core (2.20 GHz up to 4.10GHz with Turbo Boost, 9MB Cache)
Memory: 32GB DDR4 2666 MHz
SSD: 1TB SSD, M.2
Display: 15.6 UHD (3840×2160), 60Hhz Anti-Glare IPS
Graphics Card: NVIDIA GeForce RTX 2070 Max-Q 8GB

Legion Y740

The Lenovo Legion rounds out the top three contenders with its rather inexpensive (and yet strangely well packed) offering. In fact, it’s so well packed and so cheap that I’m a bit worried about buying it. The only difference between this and the Alienware is the Alienware has a bigger SSD and has a 4K display. Otherwise, they’re identical, spec-wise. The biggest concern is the battery is only 57Wh, which limits the amount of non-plugged in time I can have.

Cost: $2469.19
Processor: Intel Core i7-8750H 6 Core (2.20 GHz up to 4.10GHz with Turbo Boost, 9MB Cache)
Memory: 32GB DDR4 2666 MHz
SSD: 512 GB SSD, M.2 PCIe-NVMe
Display: 15.6 FHD (1920×1080)
Graphics Card: NVIDIA GeForce RTX 2070 Max-Q 8GB

Macbook Pro Retina (2018)

I’m including this because I feel like I have to. I’m not jazzed about spending this amount of money on a system with keyboard issues that only has Thunderbolt ports, and doesn’t have any of the things that really sold me on the original Macbook Pro Retina series. It’s still a contender, but it’s at the bottom of the list.

Cost: $4628.00
Processor: 2.9GHz 6‑core 8th‑generation Intel Core i9 processor, Turbo Boost up to 4.8GHz
Memory: 32GB DDR4 2400 MHz
SSD: 1TB SSD
Display: Retina Display (UHD)
Graphics Card: Radeon Pro Vega 20 with 4GB of HBM2 memory

What do you think? Which laptop should I choose? Do you have any experience with these laptops? What was your experience? Share your thoughts on these contenders and your thoughts on a good developer laptop in 2019.

A better alternative to Sandwich Feedback

In December 2018, I had the opportunity to attend The Lead Dev conference in Austin, Texas. I was extremely lucky that my then employer also paid for a whole day workshop on becoming a manager through Demystifying Management by Lara Hogan (@lara_hogan ). It was a wonderful full day workshop, chock-full of lots of useful advice for the aspiring manager. One particular management technique she taught has stuck with me.

Instead of “Sandwich feedback”, where the giver gives feedback in the following pattern:

  1. Good Thing you do.
  2. Bad thing you did that needs correcting.
  3. Good Thing about you.

Lara suggests the following format:

  1. Observation: A by-the-numbers recounting of the behavior you witnessed that you want to give feedback on. It’s important that this observation be devoid of emotion or parsing. It should be the same observation that a camera would pick up if it were recording the behavior you’re speaking towards.
  2. Impact: How did that behavior affect you? What did you feel as a result of it? How did it affect others?
  3. Open-Ended Question: At this point, ask an open-ended question (a question that cannot be answered with a “yes” or “no”, and it should be a non-hostile question). Lara suggests one of her favorite, “What are you optimizing for?” The Open ended question allows for a non-amygdala-hijacking response. One other piece of advice she gives is to make it a genuinely curious question. Use this moment to understand what drives the other person, and what caused them to take the action they did.

If you get the opportunity to attend one of Lara’s workshops, I highly recommend it. For my part, I strive to use this feedback format in all my interactions.

Looking back at Some of the Changes in C# 6

We’re currently on C# 7.4 and approaching C# 8 (Wow!); but C# 6 was the first version of C# post Roslyn (Compiler rewrite, to oversimplify it a bit). C# 6 was the first version of C# to coincide with .NET Core, and so it’s where the development of C# seemed to… skyrocket. I’m revisiting changes to C# starting particularly with C# 6. C# 6 has been around since 2015; and arguably represents the first time core features of the language have changed since 3.0.

C# 6.0 unveiled several language features that are useful for removing verbosity from common class operations, and set the groundwork for future improvements that we’re only really scratching the surface of.

Readonly Auto-Properties

Prior to C#6, if you wanted to make a “read only” property, the best you could do was:

public class M1 
{
public string P1 {get; private set;}
public M1()
{
P1 = "hi there";
}
}

There were a few problems with this approach.

First, if M1 implmented an interface, you couldn’t use a private accessor. Second, the string P1could still be mutated inside the class; probably not what you wanted semantically.

If you forsook auto-properties entirely you’d be fine, but that’s going in the wrong direction:

public class M1 {
private readonly string p1;
public string P1
{
get { return p1; }
}
public M1(string text)
{
p1 = text;
}
}

With a readonly auto-property, you can now have reduce the above sets of code to this:

public class M1
{
public string P1 { get; }
public M1()
{
P1 = "hi there"; //can only be changed in constructor!
}
}

This improved syntax allows you to semantically and concisely declare your intent for a property: That it should be set at construction and not changed. It is immutable. This is extremely useful in the following situations:

  • For read only DTOs (Data Transfer Objects), getting data from the database for display where it wouldn’t make semantic sense for an implementor to try to change the value; or for ViewModels.
  • For a public value that will be set at construction and should be able to be referenced by other classes throughout the application in an easy manner.
  • For immutable objects. Immutable objects are easier to reason about and interact with.

Property Initialization

This feature in itself is pretty cool; but what if you don’t want to create a default constructor just to deal with creating an immutable property? You can now combine property initialization (a la field initalization) with readonly auto-properties:

public string P1 { get; } = "hi there";

This reduces the use of a default constructor just to set this property; and it ensures that no matter which constructor is used, this property gets set.

Expression-Bodied Members

These changes to C# are neat; but if you wanted to have more complex logic inside your getter; you were stuck using the ‘old’ style properties:

public class M1
 {
   public string P1
   {
     get 
     {  
         DateTime.Now.Month == 11 ? return "Month Left" : return "Months Left";
     } 
   }
 }

With C# 6, you can change this to a single line of code:

public class M1
 {
   public string P1 {get; } => DateTime.Now.Month == 11 ? "Month Left" : "Months Left";
 }

The biggest change here is the use of the Expression Body syntax (which would later be expanded in C# 7); and that there’s no “return” in this expression. This mimics the closure syntax used by LINQ.

Expression-Bodies can also be used in methods in C# 6:

public class M1
 {
    public string GetMonthPluralText() => DateTime.Now.Month == 11 ? "Month Left" : "Months Left";
 }

Null-Conditional Operator

The next ‘big’ feature in C# 6 was the change to how null checks were handled. Prior to C# 6, if you wanted to check for null, you had to do something like the following:

public class M2
{
public int? P1 {get; set;}
}
public class M1
{
public M2 M2P1 {get; set;}
}
public int GetValue(M1 m1)
{
if (M1 != null && M1.M2P1 != null && M1.M2P1.P1 != null)
{
return M1.M2P1.P1.Value;
}
return 0;
}

Ok, ok, so this seems like a convoluted example. I’ll give you that. But in order to successfully determine if class member property P1 of class M2 has a value, you have to check its parentage *first*. If anything in the chain of calls is null, you’ll get a NullReferenceException. That would be bad.

C# 6 fixed this by allowing the use of a new operator, the null-conditional operator. So that the above code becomes:

public int GetValue(M1 m1)
{
if (M1?.M2P1?.P1 != null)
{
return M1.M2P1.P1.Value;
}
return 0;
}

This is far more concise, though I’d argue that it’s not really clearer to a casual observer what’s going on.

If you read code long enough, you don’t really “read” the code any more, you skim it. With less concise code; it’s easier to ‘see’ mistakes when skimming, for instance if you leave out a null conditional check. With the ?. syntax, there’s no easy way to see that you’ve forgotten to make a null check: M1.M2P1?.P1 != null but overall it’s been a solid addition to C#.

When C# 6 came out I was quite against the Null conditional operator and the expression-body syntax; but after a few years of using them, I am happy to have them in the language.

Improve Your Resume by Focusing on Outcomes

I’ve been on both sides of the hiring aisle throughout my career. I’ve been a job seeker more times than I care to count, and I’ve been a hiring manager and on hiring teams on several occasions. I wrote about resumes in 2010, and I’d like to think most of it holds true today (I will say my thinking has evolved, especially with #8 and #9); but what I’ve noticed since then is a formula for ensuring your resume stands out amongst your peers. All programmers write code, and the best programmers figure out how to solve the problem with as little code as possible (if you believe that code is a liability, then this isn’t a logical stretch), but since you’re applying for a job as a programmer, it puts you into a counumdrum. How do you make writing code sound as appealing as possible?

You focus on the outcome, and the impact you had towards that outcome.

I love to write code for code’s sake, but on someone else’s dime they want me to solve problems and deliver value. That’s what you should focus on on your resume. We love to talk about which hammers we use to drive nails, but we sometimes forget we’re driving those nails for a reason.

You’ve been tasked with hiring a carpenter (because hiring a progammer example would be a bit on the nose). All else being equal, would you rather hire the carpenter that says:

I created a method to allow builders to reduce the time it took to frame a house from 3 days to 1 day, resulting in a 66% cost decrease using the pneumatic bfg nailgun 5000.

Or:

I used the pneumatic bfg nailgun 5000 to frame this house, and was able to do it in one day.

We all intuitively know that the first approach is better, but why? It had the same details as the second, and was shorter to boot. The reason why it is better lies in how the information is laid out.

  1. Start off with a strong action verb. Created, Shipped, Spearheaded, Drove, or one of 185 other action verbs.
  2. Describe the outcome. You did something, what was the outcome of that something? Programming doesn’t exist in a vacuum.
  3. Describe the impact that outcome had. You framed a house in one day! Great! What’s the story behind that outcome. Did it lead to higher revenues? Did it lower costs? Even if you can’t directly associate a dollar value to the outcome, can you associate something else that’s quantifiable? Like support costs/time or developer cost/time? If you wrote an optimization routine that took a 30 minute build time down to 5 minutes and you have 20 developers on the team, that’s an entire developer’s daily salary in cost saved, every day!
  4. Finally, describe the means. How did you do it? What did you use to do it? This part is less important for business people than it is for other developers who may be on the hiring team.
    The developers who read your resume still get what they want (“What hammer did you use to drive this nail?”), but the business people and non-technical people who read your resume get what they want, first.
  5. These bullets (and your resume in general) should be written to reflect where you’re applying to work, and the work they do. If you’re applying to work at a consultancy, on-time and on-budget matter a lot more than it would if you were applying to a team that care most about eeking out performance (say a financial trading firm). You want to emphasize what the company you’re applying to cares about.

In short, if you follow this format:

<Action verb> <Outcome> <Impact> <Means>

By showing what you did, what it resulted in, and the business impact of your actions, you’ll already be ahead of your peers in showing that you can communicate well. This format also has the added benefit of working for robo-reviewers, as it still includes the keywords our machine overlords are looking for.

So take a look at your resume, and think about how you can reframe it to put the impact to the business first. And if you’d like help, drop me a line. I’ll be happy to help.

.NET DC Meetup – Prototyping On the Cheap

I was fortunate to attend the .NET DC Meetup last night (3/19/2019), with Steve Goguen talking about using F# and Linqpad with the title of: Prototyping on the Cheap.

Steve opened with a relevant clip from The Founder about the Speedee System; a film that details McDonalds and their change from a single location to becoming the franchise powerhouse it has.

In the scene, the McDonalds brothers prototype how to make the most efficient kitchen layout possible to ensure fast, reliable hamburger production. Previous to this Hamburgers took 30 minutes to make and deliver in Drive-Ins. After this, Burger production went to 30 seconds. It would have been prohibitively expensive to make the changes necessary for this without prototyping. Note the tools they use: a ruler, chalk, a ladder, and imagination:

Steve then went through how F#, with its minimalist approach to declaring types and data structures (like a hash of hashes), let’s you use the code itself to prototype the relationship between entities in a system. The example he used was the menu system for chipotle. I have almost no experience with F# and I found his example easy to follow.

Besides using F# Data Structures as a way to show off relationships between entities, Steve took us through Bogus, a library for generating data.

Up until this point, I had never heard of Bogus, and I have just one question where has this thing been all my life? I hope Steve shares his code examples, but Bogus coupled with F# makes it trivial to generate sample data (image from last night’s meetup below):

Steve Goguen, taking us through how you can seed Bogus with the same number to have a deterministic randomness.

From the image above, the F# used to generate fake data is on the left, with the result, in Linqpad, shown on the right.

From this demonstration, a few things stood out to me:
1. Linqpad’s Dump()method is really useful and reminds me of the Perl library Data::Dumper, except in Linqpad it can dump in full blown HTML.
2. As Steve says in his presentation, Bogus does really well if you let it generate random data without constraints. If you provide constraints (for instance, Bogus can generate random birthdates in a 20 year timeframe), then Bogus can take much longer to generate the data you need. One way around this is to generate the data once and then use that data as the data to randomly pull from.

In the Second Act, Steve goes over FsCheck, to which I have to ask again, where has this been all my life?

FsCheck allows you to generate random values of given types as inputs for your application and check whether or not it handles those random inputs well. In terms of Prototyping, FsCheck provides a quick way to sanely flesh out where your idea may run into data problems (or where your assumptions are too broad or narrow), and you can use it in Linqpad.

Steve then went over Reactive Extensions in C# with Observables, and how to use Observables to prototype showing changes when items are selected or de-selected, as a way to show stakeholders different options.

Finally, in Act Three, Steve showed us how to use all of this along with Linqpad’s built in UI controls and some extension methods to generate Winforms and Web UIs, In Linqpad.

Linqpad has a number of controls built in , and Steve showed us how we can use these controls to prototype a Winforms UI. But that’s not all; Steve also showed us how to use an extension method to Dump IHtmlString as HTML to Linqpad, along with pulling in Bootstrap and Jquery (and Dumping it with the glorious Dump() method, to prototype entire HTML interactions in Linqpad.

Steve Goguen, showing us how to create entire interactive webpage prototypes in Linqpad.

The entire talk was well put together and made me excited for Linqpad, F#, and those newfound (to me) prototyping libraries. Many thanks to Steve Goguen for speaking on this subject. If/When the slides and code snippets are released, I’ll update this post with links to them. For now, Steve’s site is here, here’s his Github and Twitter.