Thursday, July 14, 2016

Functional Practice: Euler Problem #2 in F#

I'm still moving forward with my exploration of F#. I decided to take a shot of Euler Problem #2. I've previously looked at this problem using Haskell (back in January 2014). Now it's time to take a shot at it with F#.

I'm not completely happy with the solution I came up with. I'm sure there are better approaches. But it's a good starting point, and I've learned quite a bit about sequences in the process.

[Update: Collected articles for the first 10 Euler Problems in F# are available here: Jeremy Explores Functional Programming.]

Euler Problem #2
The second Euler problem is not all that complex, but it does have a few steps to it:
Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be: 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ... By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
The biggest challenge is to create a Fibonacci sequence. I've run into issues with this before, so I knew that this would be the hardest part of this challenge.

The Fibonacci Sequence
I started looking for a Fibonacci solution the same way that I did previously: by creating a recursive function. When I was first getting into functional programming, this felt like the right way. But I've since learned that recursion has some issues in this case.

Recursive Implementation
Here is that naive implementation (this shows the script file along with the output from F# Interactive):


This gives us correct values -- the 10th item in the Fibonacci sequence is "55". However, it becomes *very slow* very quickly. This may doesn't seem like a big issue at first, but when we're trying to generate an entire sequence, it is way too slow.

A Better Solution
I spent a little time trying to figure out if I could somehow translate the Haskell solution to F#. It may be possible, but it's beyond my capability at this point.

I went online to look for solutions. My big condition, though, is that I won't use a solution that I do not understand. Here's the solution that I ended up settling on:


This gives us the same answer, but it doesn't suffer from the performance issue that the recursive solution has.

That's because rather than using recursion, it uses a fold. And the fold calculation is simply addition. But let's try to understand this. To do that, we'll pick out 2 of the lines:


I've replaced the "n" (the parameter) with the value of 3. So this starts with a list that consists of the values 1, 2, and 3.

A fold is a way to use an accumulator to calculate an aggregate of some sort. We can think of the accumulator as a running total (although it doesn't have to be a sum). We then have a function to calculate that running total for the list.

The last value on the second line "(0,1)" is our accumulator. This is a tuple that consists of 2 integers: 0 and 1.

The function that we're using "fun (a,b) _ -> b, a + b" is a bit more interesting. The first parameter "(a,b)" represents the accumulator. The second parameter (the underscore) represents the current item from the list. The underscore denotes that we don't really care about that value; we're not using it in the body of the function.

The body of the function "b, a + b" updates the accumulator by giving us a new tuple. The first integer will be whatever the second integer was in our accumulator. And the second integer will be the sum of both integers from the accumulator.

To understand this, let's take a look at the values of the accumulator as we go:

Initial value:          (0, 1)
List item 1: (1, 0+1) = (1, 1)
List item 2: (1, 1+1) = (1, 2)
List item 3: (2, 1+2) = (2, 3)
List item 4: (3, 2+3) = (3, 5)
List item 5: (5, 3+5) = (5, 8)

This gives us the correct values for the Fibonacci sequence.

Back to the "fibonacci" function that we have above, the last function is "fst". This is a built-in function that takes the first value of a tuple. So if we call "fst (2,3)", the result is "2". And that's exactly what's happening (although the parameter order is a bit different since we're using pipelining here).

Shortcomings
This function does have a problem: it only works for 46 items and then the integer overflows:


We won't worry about that here. But if needed, we could change this to use something bigger than an 32-bit integer.

Solving Euler #2
Now that we have this, we can solve Euler problem #2 pretty easily. First, let's use our "fibonacci" function to create a sequence of numbers. I don't have much experience with sequences, So this code will be a bit verbose.

The Fibonacci Sequence
Here's how we can get a Fibonacci sequence from our function:


A sequence in F# is like an IEnumerable in C#. With an iterator, we only get a value when we ask for one. Because of that, we can create an infinite sequence without things getting out of hand.

The "initInfinite" function lets us run a function based on a 0-based index. So this will run "fibonacci 0", then "fibonacci 1", "fibonacci 2", and so on.

If you notice, the output just displays the first few values of the sequence. This keeps us from generating the entire, infinite sequence.

Let's put a limiter on this by asking for just the first 20 values:


The "take" function gives us just the first 20 items from our sequence. I call the "toList" function to force the evaluation of the sequence so that we can see all of the values in the output.

Since the Fibonacci sequence doesn't start with "0", we'll skip the first value:


This gives us the more traditional Fibonacci sequence.

The Starting Value
The Euler problem describes the beginning of the sequence a bit differently. Notice that it shows the values "1, 2, 3, 5, 8". So, we actually want to skip the first "1" that is usually included in the sequence.

That's easy enough by changing our "skip" call:


Now let's move on to the other parts of the problem.

Less Than Four Million
The next part of the problem is that we want to get the terms that are less than four million. For this, we can just update our "take" function to a "takeWhile":


This lets us add a conditional function to determine when we should stop iterating the sequence.

Even Values Only
The next conditional is that we only want the even values. For this, we'll add a "filter":


You'll notice that I've used "x", "y", and "z" for the function parameter names. The primary reason I did this is because these represent different values, and I wanted to make sure that it was clear that they were different.

In this code, "x" represents the numbers from 0 to infinity. "y" represents the values from the Fibonacci sequence. "z" also represents the values from the Fibonacci sequence (so I guess "y" and "z" could probably use the same name here -- that's something to think about).

As a side note, you notice that the "1" was eliminated from the list (since it's not even), so it really doesn't matter if our sequence is "1, 2, 3, 5" or "1, 1, 2, 3, 5".

Summing the Values
The last part of the problem is to sum up all of the values:


We just replaced our "toList" with "sum". And we know the output is correct based on previously looking at this problem.

Final(?) Solution
So here's the solution that I ended up with:


One interesting thing to note here is in the output. F# recognizes that "euler2" has a specific value: 4613732. That's because we don't have any parameters that can alter the outcome. So F# Interactive gives us the evaluated value.

Further Work
There's a few things that I'm not quite happy with here. First, I feel like this is a pretty naive approach to using sequences. I have a feeling that a couple of these functions can be combined. I'll need a bit more experience to work those out.

It's not quite tweetable. Technically the "skip 2" line can be taken out without changing the output. But if I take it out, it will use a different sequence than the one specified by the problem. I don't feel right about that.

Wrap Up
This isn't really about getting to the solution, though. After all, we already know what the answer is, and there are plenty of people who have posted their own implementations online. The point is to get some coding practice and get more experience with language features in F#.

And that's what this has done for me. I did quite a bit of exploring of the "Seq" documentation to try to figure out which functions I should use. The "initInfinite" is pretty cool; that's brand new to me, and I'll be looking at other ways that I can use that.

I'm sure that I'll get quite a bit of feedback on different ways to do this. And I'm looking forward to that. We get better as a community by sharing and learning from each other.

Exploration and practice is a big part of how we learn and how we get better. Also, it's quite a bit of fun.

Happy Coding!

Tuesday, July 12, 2016

One Week Later: Samsung Galaxy S7 edge

So I've had my Samsung Galaxy S7 edge for a week now, and I really like it. There are a couple of features that I've come to like.

The Screen
First off, the screen is beautiful:


It's really hard to describe, and pictures don't do it justice. It's an AMOLED screen, and that means that the blacks are very deep and the colors are very bright. There's no backlight, so when a notification lights up just a part of the screen (like an "edge" notification), only that part of the screen lights up. It's kind of hard to describe, but it's really nice.

In addition, the screen works well in daylight. It's still readable in the sun. With my old phone, I had to put it in the shade to see it.

The Home Button
The home button is a physical button (as opposed to soft button on my old phone). But the cool feature is that it's also a fingerprint reader.


So, I end up clicking the home button with my thumb, and the finger print reader unlocks the phone at the same time. It works fast enough that it's not awkward to use at all (I think it works a bit better than the finger print reader on my iPad, but it may just be because the devices are used differently).

This is much better than constantly entering my unlock pattern. On my old phone, there was a constant streak across the screen that would let you know what the unlock pattern is. No worries about that here.

Health Sensor
The thing that I thought was a bit gimmicky was the health sensor. But I've been using it regularly, and I like it. I'm not sure what it will tell me about my health (really), but tracking things is the first step to finding patterns.

This is a sensor that's right next to the camera:


It will take your pulse and measure your blood oxygen saturation -- similar to how those finger-clip things in hospitals work. (And I just realized by looking at this picture that there's a plastic protector over the camera. When I peeled it off, there was a hole cut out for the lens, so it wasn't actually covering the camera.)

You just put your finger on the sensor:


It shines a light through and picks up your pulse. I can't speak to the accuracy of the blood oxygen measurement (since I don't have another way of measuring that), but the pulse measurement is accurate.

This gets fed into the Samsung health app:


It will also measure exercise and other things. I've got it set up to measure walking since I go for a walk every morning (which is apparently 1.65 miles long). We'll see how long I keep this up.

Battery Life
Battery life has been great. It's really hard to tell what real battery life will be like when you get a new device because you're probably playing with it more than usual. Even so, I haven't gotten below 50% on the battery yet.

I'm sure that normal battery life will be a bit different. And I'll also have to try out the power saving settings. So far, I'm pretty impressed with it.

Size
This is a little bit bigger than my last phone. I didn't think it would make too much of a difference, but I'm finding that I have to stretch my fingers just a little bit too far in some cases. (And I have pretty gigantic hands to start with.) This hasn't been much of an issue. And there are a some features on the phone to make it easier to use one-handed (for people with more normal-sized hands). I haven't had a need for those, but I'll be trying them out from time to time.

Other Stuff
I haven't had a chance to really use the camera yet. I've taken a few picture, but not enough to really judge it. I'm pretty impressed with it so far. I'll take some pictures over the next few weeks so I can give a better review.

I haven't used the "edge" stuff much. I'm still not sure if it's a gimmick or not. It hasn't gotten in the way, either (which is good). So it's not doing any harm right now. It might be useful in the future.

Finally, I'm not sure whether I'll be using a case with it or not. My last phone simply had a plastic cover on the back -- and this was more decorative than anything. I have a rubber shell on it right now. And it's nice to be able to put it face down on a table without the screen touching the table, but it also adds a bit of size to the phone. The phone itself is sleek and nice to look at.

I'm pretty easy on my devices, so I don't really need drop protection or anything like that. (Although the last time I said that, I immediately dropped my phone face down on concrete and cracked the screen.)

All in all, I'm happy with the purchase, and I'm looking forward to lots of use from a device that I carry with me all the time.

Happy Coding!

Monday, July 11, 2016

Some Thoughts on Mob Programming

This past weekend, I had a chance to attend a Mob Programming Workshop with Woody Zuill (@WoodyZuill).



Mob Programming - The Really Short Version
Mob Programming is Pair Programming with more people -- usually between 4 and 8. Just like with pair programming (when done right), the person at the keyboard is typing code based on the direction of someone else. The main idea for this is that the code always goes through at least 2 people's brains before it gets committed.

A mob group consists of programmers, testers, QA, and (as often as possible) a product owner. Meetings are eliminated as everyone is working together and knows the state of the work. When everyone is together, many "blocks" are eliminated (such as "we need more input from the business area before we move forward" or "we need QA to explain the problem they found a bit better").

Advantages
People generally balk at the idea of so many people working on one thing. (Just like some managers don't like the idea of pair programming because 2 developers could be writing twice as much code separately.)

But I don't see it that way. Programming is a creative process; there is a lot of thought and problem solving involved. So having more minds working on the problem could be much better. In addition, mistakes are caught earlier (since there's more than one person looking at it), and misunderstandings or incomplete information that would normally "block" the process get cleared up much more quickly.

Also, there are no need for code reviews (which no one does anyway) because the code is constantly being reviewed.

Another advantage is that everyone is constantly learning from each other, from simple things like keyboard shortcuts to more advanced language features.

Here's an interesting video that shows a typical day of mobbing that was recorded back in 2012: A day of Mob Programming

This is Not Proscriptive
The main thing that I appreciate about the mob programming movement is how Woody presents the idea. Woody tells about how mobbing developed organically in their environment, and it became very successful for their team. (In fact, the company (Hunter Industries) now has 6 teams working the same way.)

So Woody describes something that they were successful with, but he does not say that all teams should work this way. It is something to explore.

The Workshop
I've known Woody for several years, and I've heard him talk about mob programming at meetups and things like that. I've also known many of the developers at Hunter Industries for several years, and I've been invited down to mob with them for a day. Unfortunately, I haven't had a chance to make to down there (it's about 70 miles from where I live and other priorities get in the way). So when I saw the workshop opportunity come up, and it fit into my schedule, I had to jump on it.

I won't go into the details of the workshop or the exercises other than to say that it was designed to show a different way of approaching collaboration and the difficulties and advantages of that. Much of the day was spent split up into mobs (there were 5 people in my group), and it was a good experience to go through.

Specific Teams
I will say that the experience reinforced my view that mob programming is highly dependent on the make up of the teams. There are a couple types of developers who would be toxic to the environment and bring down the productivity. (These are typically the type of people we don't want to work with anyway, but that's a conversation for another day.)

I can also think of people who may or may not thrive in this environment. (I think I might fall into that category; more on that in a bit.)

Successes
The idea of mob programming has spread, and there are teams around the world who are using it successfully. My primary experience is talking to the folks that I know from Hunter Industries in Southern California.

As I mentioned, the idea of mob programming grew organically on one of the programming teams. As they developed the idea and were able to successfully deliver software and be very productive during the process, they decided to expand.

Late last year, they set up a new space to handle more mobs. They currently have 6 mobbing stations set up. You can see what they look like in the picture above: 2 80" monitors (a couple stations have 3 monitors), 2 keyboards/mice (which are hooked up to a single computer), whiteboards, and lots of chairs.

Everyone I know at Hunter really likes the environment and they enjoy working there. (And they are hiring if you're interested: Career Opportunities.)

Is Mob Programming for Me?
I'm still not sure if mob programming is an environment that I would thrive in. I've always like collaboration and working with other developers. But these have all been in relatively short chunks. I'm sure that I would be fine for a few hours at a time, or even a few full days at a time. But as an introvert, I don't know if that level of interaction is sustainable for me.

Aaron Griffith (@Aaron_Griffith), who works at Hunter, has written several articles about the challenges of being an introvert in that environment. He really loves working with the mob, but he does find it somewhat draining and has come up with ways for managing that. Here's one of the articles that is worth a read: Mob Programming for the Introverted.

I'm not sure that I could thrive in that environment. I think that if I have a job where I constantly have to think about managing my energy, then I'm probably not in the right job for me. I would much rather be in a position where my job is energizing. The things that I'm doing regularly are extremely draining (and also extremely rewarding), but they are only a few days at time, so it is very manageable for me.

More Exploration
These are just my thoughts based on the experiences that I've had. I'm planning on doing some more exploration. For example, I would like to more closely observe of a mob programming group to see what the levels of interaction, noise, and collaboration are like in a real environment. I'd also be curious to try mobbing over a several day period to see how it would affect my energy.

Mob programming is an intriguing idea. And I can see how the benefits of constant collaboration would result in faster delivery, fewer bugs, and happier clients.

If it's not for me (or for you), that's fine. And I really appreciate that Woody presents it that way.

Are You Intrigued?
If you're interested in exploring this for yourself, you're in luck. Woody is doing workshops around the world on a regular basis. If you're in Southern California (like I am), then you have a chance to attend a FREE workshop at Hunter Industries on August 20th, 2016:
Mob Programming Workshop, Aug 20, 2016 - San Marcos, CA
Space is limited, so sign up soon.

It's always useful to explore different approaches to software development. That's how we find out what's most effective for us -- especially those things we never would have thought of on our own.

Happy Coding!

Thursday, July 7, 2016

Recognizing Digits - Visually Comparing Techniques

I did a little more work on my Digit Recognizer application so that we can see how two different algorithms compare to each other.

Last time, I added the ability to flag which items are incorrectly identified:


This time, I added code so that we could look at 2 different algorithms side-by-side:


I won't go into the UI code, because that's not the interesting bit here. The interesting bit (at least to me) is how the results differ.

As a reminder, after the application finishes populating the boxes, I had to go through manually and click the incorrect items to flag them. I'd love to be able to do this automatically, but that's kind of the point here -- the computer can't figure out what's right and wrong.

If you'd like to look at the code, head to GitHub and look at the jeremybytes/digit-display project. The code here is from the "Comparison" branch.

Prediction Comparison
The way that this works is that each classifier is trained with the same training set (40,000 bitmaps). Then each classifier will compare each bitmap to the training set to find the closest match.

The idea of what is "closest" is determined by the specific algorithm. I won't go into the details here (you can read Mathias' book for the simplicity and complexity of this -- Machine Learning Projects for .NET Developers (Amazon link).

The first set uses the Manhattan Distance (Wikipedia link for the curious). The second set uses the slightly more complex Euclidean Distance (Wikipedia link).

What I was really curious about when I was first reading about the success of each at predicting hand-written digits, was if one simply made fewer errors (but mostly the same errors) or if one makde completely different errors from the other.

This initial visualization gives the answer to that question.

Each classifier was asked to predict values for the same 300 hand-written digits. You'll notice that the digits are in slightly different orders in each section. That's because the values are being processed in parallel, and the exact order will vary depending on the task scheduler.

Overall
Manhattan Distance: 9 errors out of 300 (97.0% accuracy)
Euclidean Distance: 7 errors out of 300 (97.7% accuracy)

Don't put too much into these results. We're working with a fairly small data set (300 items). We'll need to look at more / different data to come to firm conclusions.

Mostly the Same Errors
In scanning through the results we can see that they had trouble with the same items (click on the image for a larger version):


There were a couple of items where the Euclidean distance was able to successfully identify items that the Manhattan distance got incorrect, in this case an "8":


And here's another example -- also an "8":


This shows an improved accuracy (at least with this training set and this particular data set).

Different Answers
One interesting value was incorrectly identified by both classifiers; however, they came up with different answers:


In both cases, this "7" was incorrectly identified -- and that's understandable; this is a really bad "7". This is what I want to explore further.

Next Steps
I mentioned earlier that I want to add some more features to this to make it easier to explore the results.

This includes adding some inputs to control the size of the training set. A smaller training set means that the predictions will run more quickly, but they will also be less accurate.

In addition, I'd like to add an offset into the data. Right now, we're starting at the beginning of the data set and taking the first 300 values (in this case). I'd like to be able to start at an arbitrary location in the data set so that we can compare different parts of the data side-by-side.

I'll keep adding to this project. The UI code is getting a bit unwieldy already, so there will be some refactoring and clean up along the way as well.

I'm not sure where all of this is headed. But it's interesting for me to see these similarities and differences. And it's interesting to think about other possibilities. Recognizing hand-written digits is really easy for a human and not easy for a machine. This is getting me to think some more about what it really means to be human.

Happy Coding!

Wednesday, July 6, 2016

Diving into F#: Partial Application and Type Inference

I've been threatening to dive into functional programming for a long time. I've been skirting around the edges for the last few years, but I've moved this to the top of my queue. I'm currently going through Tomas Petricek's book Real World Functional Programming (Amazon link).

I did take a shot at this book earlier (I actually mention in back in Feb 2014). Based on my previous bookmark, it looks like I made it about halfway through before I got distracted by something else.

So I started back at the beginning, and I just finished up Chapter 6 today (about higher order functions). I've still got a ways to go, but I thought it would be good to put down some thoughts about the book and also some thoughts about F#.

The Book
Tomas' book has been very helpful for me to get ramped up with F#. Granted, I'm in a bit of a different position today than I was when I first got it. I've been playing a bit with F#, and I also feel like I have a better grip on functional programming concepts in general.

What I Like - Tuples vs. Individual Parameters
One thing that I really like about this book is that it's answering my questions as they come up. For example, in the early chapters, there's a mix between using tuples for parameters and using parameters individually.

Here's an example using a tuple (with the input from a script file and output in F# Interactive):


This shows an example of an "add1" function that takes a tuple as a parameter. The tuple itself consists of 2 integers. When we call the "add1" function, we need to supply a tuple as a parameter (2 integer values inside parentheses in this case).

By looking at the output, we can see that the function signature takes "a:int * b:int" as a parameter. This denotes the tuple that we described above. The output in this case is an integer.

Here's the same function written with separate parameters:


The "add2" function takes 2 separate parameters (both integers). When we call this function, we pass in the 2 integer values separately -- and we don't need parentheses around the parameters.

This brings up the question of which of these approaches should we prefer? And just when I was asking myself that question, Tomas answered that.

Tuples
If we have values that should be kept together (for example, the X & Y coordinates of a point), it makes sense use a tuple. This is a single parameter that happens to contain 2 values. We probably won't be doing partial application on these values (more on partial application in just a bit).

Separate Parameters
If our parameter values do not need to travel together, then it's often better to have separate parameters. This leaves things open to partial application -- where we create a new function that provides some (but not all) of the parameters.

Here's an example of partial application:


The "addTen" function is a partial application of our "add2" function. We supply just one of the parameters (10). This means that to call "addTen" we need to supply the second parameter.

So when we do partial application, we can create functions that have specific functionality. We would not be able to use partial application with the "add1" function because it only takes 1 parameter (the tuple). This example is a bit contrived, but it can be useful when we're trying to write small, reusable functions.

Reading Function Signatures
The other thing that I like about Tomas' book is that it spends time helping us read the function signatures (actually, the type signatures). Let's compare the ones that we've seen so far.

When using the tuple parameter, we get the following signature:


Again, for "add1", we have a single parameter (represented by "a:int * b:int") which is a tuple of two integer values. Then we have the output (denoted by "-> int") which tells us that we get an integer back from this.

Let's compare this to the function with separate parameters:


The signature for "add2" is a bit more interesting (and it takes some getting use to). This a function takes 2 parameters (denoted by "a:int -> b:int") and outputs an integer ("-> int"). This is a bit more confusing since we have the arrow used between all of the values here.

But that's also the point. Technically, we have a function that takes a parameter "a" that returns a function that takes another parameter "b", and that function returns an integer.

And this is what allows us to do partial application. Let's look at the signature for "addTen" again:


This function only takes one parameter (because one parameter has already been "applied"). So this takes an "int" as a parameter and outputs an "int".

It does take a while to wrap your head around -- especially for more complex functions. But this is starting to make sense to me.

What I Can Do Without - C# Examples
The full title of Tomas' book includes "With examples in F# and C#". When I first picked up the book, I was glad to see the C# examples. But as I go through this time, I find that they are just getting in my way.

I'm not going to implement a Tuple class, a functional List class, or a Map function in C#. I would avoid it actually. I understand why the examples are there: they are giving the C# developer something to grab on to. But since these become overly complex in C# (with the use of explicit typing and generics), I've found that it isn't worth my time to understand them.

I'm all about the right tool for the job. Instead of trying to wedge functional types into C#, I'd rather concentrate on F#. So I've been skimming over the C# examples.

Type Inference
You'll notice that in the function declarations above that there are no types for the parameters or the output. This is because F# has a very strong type inference mechanism. This means that most of the time, F# can figure out the type based on how it is used. In these functions, since we are using "+", it makes the assumption that we will be adding numbers together. And "int" is the default number type.

There are ways to explicitly declare types. But it is common to only do this when needed -- meaning, when F# cannot figure out the type based on the context.

This has an added advantage: many functions end up using implicit generic types. This means that the functions will works with a variety of parameter types the same way as if we declare a generic type parameter in C#.

A Bit Concerned
This is a huge feature, and it is really cool. But I have some concerns about it, specifically around readability. When no types are explicitly declared, it can be difficult to figure out what's going on without tracking back through various functions or exploring the types using the editor tooltips in Visual Studio.

Here's an example: when I picked up the Digit Recognizer code again. It took me a while to figure out what was going on. Granted, I didn't write the code originally; I transcribed it from Mathias Brandewinder's book Machine Learning Projects for .NET Developers (Amazon link).

When I did the original transcription, I understood what was going on. But when I picked it up again, I had to do some exploration of the code.

For example, here's the "manhattanClassifier" that was used to create predictions based on the training set (with the tooltip for the "classifier" item):


This shows that "manhattanClassifier" consists of a "classifier" and a "manhattanDistance". When we hover over "classifier", we see that it is a "Distance -> int[] -> string". So this takes a "Distance" and an integer array (that represents the digit to be recognized) and outputs a string (the prediction).

Then we need to look at what a "Distance" is. This happens to be an explicitly declared type:


This represents a function that takes a tuple with 3 values (an integer array, another integer array, and an integer) and outputs an integer. The integer arrays represent the incoming data and a value from the training set (ignore the 3rd value for now -- that was some performance experimentation that I didn't quite complete).

But what about the "manhattanDistance" that we have?


This represents a "Distance" type (notice that it has the same signature as "Distance").

If we take a step back and look at what "classifier" is, we see this declaration:


This refers us to the "train" function which has a pretty complex signature.

This leads us to the declaration for "train":


Here we can see some parameter types that are declared explicitly: "trainingset" is an array of Observations, and "dist" is a Distance.

If we follow these declarations back up, we can see that the "classifier" function is a partial application of the "train" function. And "manhattanClassifier" completes that application by providing the "Distance" parameter that "train" needs.

The result is that we have very flexible code. We can use and reuse these functions over and over. In fact, many of these functions are re-used to declare a "euclideanClassifier".

Readability?
My big concern here is readability. I'm sure that this is something that I will get used to as I get more comfortable with functional programming in general and F# in particular. But what does this mean for other developers who are walking up to this code? How approachable is it?

I've written a little bit about this before when talking about the "var" keyword. "var" allows for type inference in C# (although extremely limited compared to what's available in F#). I try to constrain the use of "var" in my code to make sure that the types are easy to see just by looking at the code. (Check the previous article for some examples there.)

And that leaves me really torn when it comes to F#. Type inference is extremely powerful, and it makes code very compact. But it also hinders readability. This is particularly true when we don't have a programming environment available to us.

I generally like code to be readable in a text editor -- meaning that if I just have Notepad (or even a printout of the code), I like the code to be understandable. But this is not possible when we're relying on type inference as heavily as we do with F#.

To see this for yourself, just take a look at the code samples above directly on GitHub: jeremybytes/digit-display/.../FunRecognizer.fs. It can be tricky to follow without any tooltips or compiler hints.

Withholding Judgment
For now, I'll withhold judgment. I know a lot of F# developers who are big fans of the type inference system. And I have to believe that this is something that you do get used to with enough practice and experience.

At the same time, I think about how I will teach other developers how to use this. If I find F# so awesome (which is what's happening at the moment), I'll want to share this with other developers. There are a lot of hurdles to get over when moving from OO programming to functional programming (it's definitely a shift in mindset).

I'm worried that type inference just makes things harder to approach -- particularly when you're brand new to the environment.

Wrap Up
So I am actually doing my deep dive into F#. I'm planning on finishing up Tomas' book, and then heading on to Dave Fancher's The Book of F# (Amazon link). I'm also going to get back to Mathias' machine learning book as well. (Last time, I kind of petered out when the math started to get a bit complex. But I need to hunker down and work on understanding it.)

Functional programming is definitely keeping me interested. And it's making me happy (particularly compared to some other technologies that I've been trying to stay away from). I'll keep exploring, and I'm sure that I'll come to grips with the things that work for me and the things that I'll start to recommend to others.

But I don't feel like I can make any real recommendations until I understand what I'm doing quite a bit better.

Happy Coding!

Tuesday, July 5, 2016

Goodbye HTC, Hello Samsung

It doesn't seem that long ago since I got my HTC One (M8). It actually wasn't all that long ago (April 2014). I generally keep my devices for a while, but it was time to upgrade.

I had a few devices in mind, so I sent out a call for recommendations:


I got back really high recommendations from Cory House (@housecor), Jon Mills (@jonathanfmills), and Cori Drew (@coridrew) for the Samsung Galaxy S7 Edge. This was one of the devices on my list, and I also saw some folks with them when I was at KCDC a couple weeks ago.

BTW, the runner up seemed to be the Nexus 6P (if you want a big phone) or the Nexus 5X. A big thanks to everyone who replied.

Hello Samsung
So my new phone arrived today. Here it is next to the outgoing HTC One (M8):

Samsung Galaxy 7 Edge (left) and HTC One M8 (right)

The phones are about the same physical size (weight is about the same as well) -- this will be great since I'm used to carrying a device this size. But the screen on the Samsung is quite a bit bigger. Also, the Samsung is a tiny bit thinner (which I think I'll like as well).

It was expensive. But this is a device that I have with me all the time. I'm planning on keeping it a long time. I don't upgrade often, so I figure getting a "flagship" will give me a bit more life out of it in the long run.

There are a couple features that I'm interested in exploring, including Samsung Pay. This is capable of paying over NFC like Android Pay (and Apple Pay), but it also can generate a magnetic field that mimics a credit card swipe. I'm not sure if I'll actually use that, but I've heard that it seems kind of magical the first time you try it.

I'm not sure about the "Edge" part of the device. I'll have to spend some time with it to see if I really like it or if it's just a gimmick.

Update: I just discovered that the camera has a "Food" option. I think I may be too un-hip to own this phone...



Goodbye HTC
I really like my HTC One M8. It has served me well, been stable, and has received Android updates during the time I've had it. I considered the M10 (or M9), but unfortunately, people who went from the M8 to one of these other devices didn't have good things to say about it.

I generally keep my devices for a while. I've only had the HTC for a little over 2 years. I wasn't planning on retiring it so soon, but it developed a bit of a bulge:

Getting big around the middle
Yikes!

I first noticed this about 2 months ago. And it's slowly been getting worse. This points to a swelling battery, and I probably should have replaced it right away. But I put it off because of the travel that I've been doing. I guess I should consider myself lucky that the battery didn't burst into flames while it was in my pocket.

So, Goodbye HTC. You served me well. Thank you for the memories.

Why Not Microsoft?
When I got my last phone, I asked the question: Why not Microsoft? It seems like a question that doesn't need to be asked anymore.

Looking Forward
So, here's looking forward to years of memories with the Samsung. I'm still getting things set up, and I'm sure that it will take me a while to get used to things. But from what I've seen so far, I'm happy with the purchase.

Happy Coding!