Wednesday, February 11, 2015

Functional Programming and Domain Driven Design

I was in a meeting full of senior engineers a few months ago, and we were discussing the state of our Javascript which lead to the topic of Functional Programming.  I mentioned that I thought we were spending a lot of time writing packages of functions that were fairly composable, but we were having trouble reducing duplication because our code was organized by project, specific to the problem being solved at any given time, with no concept of problem domains.  I suggested we apply the principals of Domain-Driven Design to raise the level of abstraction and reduce duplication.

Unanimous laughter followed.  Buried inside the laughter was the comment, "DDD?  What is this, 2008?"

I assumed that I was missing something and that the concepts of DDD were incompatible with FP because all of the core "things" described in DDD have the word "object" in their name.  But, while DDD as described by Eric Evans is implemented in an Object Oriented language in his book, it isn't implied by the fundamental approach.

Then, I stumbled on this video which hypothesizes that DDD is even better with FP.  The speaker asserts that there isn't any reason Functional Programs can't also contain a "ubiquitous language", "bounded contexts", etc.

He doesn't exactly prove the hypothesis.  But I assert that DDD, by my definition, is compatible with FP.  So, below is my attempt to map each DDD buzzword to something that is easy to implement in a Functional program.

Value Objects - Immutable Values are all Value Object in FP.
Entities - Giving a Value Object a specific ID makes it an Entity.  Easy in FP.
Aggregate - A collection.  Functional program is full of these.
Aggregate Root - A function that maps over an Aggregate.  I suppose we can use types to protect our Aggregates from external mutation, but this wouldn't be a necessary if we kept all of our data immutable.
Domain Event - Fans of Big Data will likely find the concept of mapping and reducing over raw data, a very Functional idiom.
Service - Functions that operate on data could be considered services.
Repository - In the process of isolating non-pure database access from pure functional code, programmers often use some sort of repository pattern to abstract the database access behind a composable API.

What does this mean? It means that we OO expats, shouldn't throw out everything we were doing to organize our domain.  We should be taking the most important and useful OO tools with us as we assimilate into our new FP world and only deviate once we have proven a superior idiom is available to solve our problems.

Sunday, November 3, 2013

Amazon Kindle: Resetting "Last Page Read"

Somehow, a book that I had just started reading on my kindle jumped to the end.  From that time, all of my Kindle devices showed that the "farthest point read" was that point, and whispersync was effectively broken for that book.  Here's how I was able to reset the "last page read" for that book:
  1. Go to the device where you have the book at the location where you want it to be set (either at the beginning of the book or at a given page) 
  2. On click My Account > Digital Content > Manage Your Kindle. 
  3. Click "Whispersync Device Synchronization". 
  4. Turn Synchronization Off
  5. Go back to your Kindle device and "Sync to furthest page read".
  6. Remove the book from that device.
  7. Re-download the book from you "cloud".  On the kindle, go home and tap "cloud" to find the book.
  8. Open up the book.
  9. Go back to "Whispersync Device Synchronization"  and turn it back on


Tuesday, October 29, 2013

Google Is Slowly Closing Android

Ars Technica recently posted an article that outlines various ways Google is closing. I think the majority of the article is spot-on, and for the first time, I am seriously disappointed in the Android Open Source Project leadership for allowing this to happen.

If this policy of leaving the OSS project to stagnate continues, I will likely investigate an alternative to Android as my primary operating system.  My hope is that projects like Cyanogenmod can take up the leadership role, or at least threaten Google, such that Android doesn't become completely closed source.

Friday, October 11, 2013

Fixing Lag On The Barnes And Noble Nook HD+ Running Cyanogenmod 10.2

UPDATE: CyanogenMod 10.2.1 has trim enabled. Don't follow these directions. Just install 10.2.1.

I have a Nook HD+, and the only way to love this tablet is to put CyanogenMod on it, because that turns it into a very-near stock android tablet - no special Barnes & Noble stuff, and it gets really really fast.

This tablet has one huge flaw.  The memory controller has a tendency to fail when the system runs a trim operation, something that all modern Android devices have that helps keep them from slowly starting to lag more and more over time.  Here is a decent description of what trim is and why you want to have it on this device. The solution until now, even on the stock HD+ from what I can tell, is to just disable trim completely.  So, what happens is that, regardless of if you are running the stock firmware from Barnes & Noble, or if you have upgraded this tablet to CyanogenMod 10.2, this tablet will progressively get slower and slower until it is nearly unusable.

But, there is a solution, if you are willing to to take a risk.  Apparently, the Nexus 7 has the same memory controller as the Nook HD+, and Google has patched Android to fix the bug.  There hasn't yet been enough confirmation that this is fixed, so it isn't in any mainstream kernels that I can find.  But, if you are running CyanogenMod 10.2, you can flash this kernel right over your CyanogenMod 10.2 nightly and trim will be enabled.  Once it's enabled, you can run this app to fix the lag.  After running the app once, it'll probably be a while before it needs to be run again, so in case there IS a bug, just re-flash CyanogenMod Nightly to put the original kernel back.

So, to recap the steps to make the Nook HD+ not lag when running CyanogenMod 10.2:
  1. Download the patched kernel zip.
  2. Install the lagfix app.
  3. Use CyanogenMod updater to get the latest nightly ready to go.
  4. Reboot into ClockworkMod.
  5. Flash the new kernel and reboot.
  6. Run the lagfix app for all partitions.
  7. Reboot into ClockworkMod again.
  8. Flash the latest nightly zip (which will swap in a kernel without the fix for protection).
  9. Enjoy Fast Tablet.

Wednesday, November 7, 2012

An Anecdotal Review of Monoprice's In-Ear Headphones

I like good sound, but I don't like to pay a ton of money for it. So, I look for headphones that are inexpensive but that I can make sound good. "Good" to me means that I can hear all of the instruments in a fairly complex piece of music and that have enough frequency response that I can get decent highs and lows (even if it takes some equalization). As a drummer, highs and lows are most important to me, especially a nice dull thump from the bass drum without disturbing the rest of the instruments.

In other words, I prefer the drivers to not be overwhelmed by sudden peaks of energy. For me, this is most obvious in the presence of low frequency sounds just after the bass drum is hit.  If, for instance, during a bass drum kick the bass guitar drops out suddenly and just as suddenly restores or, in softer music, the normal echo of the inside of the bass drum after a kick is not present, it's an indication that the driver has been overwhelmed.  Doing a test like this with your favorite music is a great way to evaluate a sub woofer for a theater system by the way.

Finally, I am annoyed by added compression that brings the hard-to-reproduce frequencies into an easier-to-reproduce range because it makes it harder to make out the difference between a high hat roll or the strum of an acoustic guitar (Bose).  This probably won't be a problem in headphones under $20.

I'm not an audiophile.  I don't have a golden ear.  I don't have fancy equipment to objectively assess my findings.  The only expertise I have is that I am a musician using music I am extremely familiar with.  So, obviously, this is a completely subjective analysis.

Monoprice 8320 ($8)
All that being said, in the "sub $20" range, the Monoprice 8320 headphones are well known for being "audiophile quality" to budget consumers like me. I purchased them, and I agree. They sound great. But, the design hurts my outer ears - and, yes, I am wearing them correctly by wrapping them around the back of my ear.  I had the same problem with my old pair of Koss Cans (I think they are called "Pathfinder In-Ear Headphones" now).  The Koss headphones aren't cheap enough for this review, and they aren't nearly as good sounding as my favorite's here anyway.

So, I began my search for something that sounds just as good for the same price.  First up, I tried the Panasonic RP-HJE450 phones.  I searched Amazon for phones that got great reviews under $20, and these popped up. 
Panasonic RP-HJE450 $20

These Panasonic's fit really well, but that's about all they have going for them.  They have great frequency response, and the drums are incredibly clear, but there are NO mids.  It's hard to make out the vocals, and the very faint echo you can hear from the room the music was recorded in is totally lost which makes the audio sound artificial.  Equalizing up the mids really helps, so I'll keep them.  Explosions in movies make my eye balls shake.  So, there's that.  Also, the cable is more than 50% split so I found it catching on everything.

After that experience, I decided to go back to Monoprice and try out their other models.  First up, the Monoprice 8321s.
Monoprice 8321 $5
The difference between the 8320's and 8321's is more than 1 integer.  The specs on Monoprice's site are totally different, and it's obvious.  Regardless of how much you pump into these things, you will NOT be able to hear the bass drum resonate or anything that rings in the high end.  These might as well be the crappy headphones that came with your smartphone - useless for anything other than talk radio.

Monoprice 9398 $12
Monoprice 9397 $13
Monoprice 9396 $7

Finally, there are these three.  The 9396, 9397 and 9398.  The 98, despite having the largest product number is NOT the best sounding.  It has really good metal construction, but it's REALLY bass-heavy and muddy.  Granted, these are intended for "video gaming" so I guess gamers want to loose their low frequency hearing.  With equalization, these sound fairly good for $12, but in comparison to all of the other's in this review, and without equalization, these are nearly as bad as the horrible 8321s.  If you don't turn the bass down on those units, you will find the rest of the audio washed out due to the fact that there is only one driver in these, and all of the movement of the speaker is dedicated to billowing whale sounds into your brain.  They can probably be made to sound as good as the Panasonics with less equalization than the Panasonics.

The 97s have a slightly larger driver than the 98s and are a little bass-heavy.  They are excellent for under $15!  Way better than the Panasonics, or the 98s.

The 9396s sound even better!  Without any equalization, they sound almost as good as (maybe better than) the 8320s!  And, they are more comfortable than the 8320s.  The only real complaints I have are that they are cheaply constructed and it's hard to find which one is the left or right one.  I painted some white-out on the back of the right unit: problem solved.  I think I'll probably purchase a few of these 96's.

So, how do they stack up?  The 8320s and 9396s are the best sounding, but these 9396s are my favorite due to comfort.  The 8320s are my second favorite sounding and the 9397s are my second favorite over all.

  1. Monoprice 9396 - Possibly the best sounding.  The most comfortable from Monoprice.  Cheap construction (buy a few).
  2. Monoprice 9397 - Takes a little equalization to make the mids available.
  3. Monoprice 8320 - Probably the best sounding, but they hurt my outer ear.
  4. Panasonic RP-HJE450 - without equalization, the mids don't exist.  With equalization, there is enough response across the board to get really good sound.  The most comfortable overall.
  5. Monoprice 9398 - I could hear the music somewhere behind the bomb going off inside my head.  After equalization, amazing for $12.
  6. Monoprice 8321 - Seriously, you're paying more for shipping.  Go to the drug store and get some buds - they'll sound just as awful.

Tuesday, August 21, 2012

JQuery: Keeping the UI Responsive During Slow Page Loads With The Event Queue

Let's say we have some really slow operation that works like this:

$("#container").empty(); $(giantArray).each(function(i, element){      verySlowRenderOperation(element).appendTo($("#container"); });

It's possible that this will make the page lock up while the above routine executes.  Most web browsers will even become unresponsive while this happens.  The most popular way to solve this problem is to use setTimeout.  The problem with setTimeout is that things might occur out of order, but the above code should maintain order in some way.  Here's a fairly elegant solution to the problem that uses jQuery's built in function queue to delay processing of any queue of arbitrary functions in order.  We can create a 1ms pause between each call which will free up the page to process other things and do all of our work in a separate thread.

$("#container").clearQueue(); //Prevent race conditions if a previous run is still pending. $("#container").empty(); $(giantArray).each(function(i, element){     $("#container").delay(1).queue(function(){         verySlowRenderOperation(element).appendTo($("#container");         $(this).dequeue();     }); });

More information can be found in jQuery's documentation on queue() and delay().

Monday, July 23, 2012

HTML is Diverging. This is a good thing.

I'm seeing this news piece floating about the web today about HTML5 diverging into two separate standards.  The story was on Slashdot a few days ago and my comment was modded +5, so I figure it's worth reposting here for others to see:

This is the similar to any source tree having a "development branch" and a "stable branch". WHATWG will be responsible for evolving the fast-paced devlopment branch of HTML while W3C will take occasional snapshots and stabilize the features of the development branch into "full standards". I assume that most of the complaints here are related to either bad marketing - WHATWG should just start calling their version HTML6 or "future HTML" or something - or the fact that these bodies (especially the W3C) move slowly and we are in the middle of a new stable branch getting pulled.

By the way, HTML5 isn't, according to the W3C a standard yet. The current HTML standard is 4.0.1. HTML5 is planned to be a "full standard" in 2014. In that time, WHATWG will introduce dozens of new major features into what will probably be called either HTML6 or HTML5.1 when the W3C gets around to pulling another snapshot.


Bookmark and Share