Monday, April 27, 2015

On Missing People

There are many people throughout the course of my life who I have lost touch with and who have never popped up anywhere I can find on the internet.  I am curious about what happened to you in life. So, if you are one of the following people and you run across this please feel free to drop a line.

(If it seems there are more girls than boys, that's probably true. It seems like I've been much more successful at staying in touch with my friends than my girlfriends let alone those who I just had crushes on.)

Kilmer / Sullivan

Howard Joseph - my best friend throughout my Kilmer years.  Last we spoke, you were in the military in Georgia I think.

Ned Trifunovich - my best friend in 8th and 9th grade. Your brother emailed me years ago but somehow I never ended up connecting with you.

Patty Murphy - Oh, did I have a crush on you in 7th & 8th grade. You may not even remember me. But somewhere I have a picture of us dancing in our 7th grade dance lessons that Miss Abdel put in my graduation card from 8th grade.

Ana Eppelbaum - My 9th grade crush whom I was too shy to talk to until after I'd moved to Denver. But we had a great mail correspondence.

Camp Yehuda

Karen Ellis - my first camp girlfriend.  You came to my Bar Mitzvah and you introduced yourself to everyone as my girlfriend which all the adults thought was adorable. (Wow, you connected with me on Facebook.  Glad you did!  Sooner or later, I'll dig out a picture of you at my Bar Mitzvah!)

Aliza Shuster - the other of my big camp girlfriends.  You may have been a twin, but I thought you were one of a kind.

Merle Kahn - you were a good friend to me, better than I was to you but I appreciated your friendship.

George Washington

Grant Huff - my best friend through high school.  You dropped out and moved to Capital Hill and we lost touch. I am afraid that you died in Dallas in the 80s.

David Arnold - You moved in as Grant was moving out.  Some months I remember your last name, some months I forget.  Forgive me, I am bad with names. But I will never forget driving around all the alleys in Denver in your VW bug.

Julie Field - another crush who never knew.  We took honors classes together over the years and Field usually followed Fear in the alphabetic list of students so...

BBYO

Teri Goldman - My 11th grade girlfriend.  I'm still in touch with people who are still in touch with you. I understand you don't do the technology thing. But if you ever do, you can find me here.

Debbie Roth - Although you were from Columbus Ohio, we met at the D2 district convention in Denver.

Megan Ovitz -We dated briefly and, if I had been smart, we would have dated more.  You lived in a great house and loved Paul McCartney and were much cooler than me.

Chipper Libber - On reflection, I suspect that I misheard and that its really Chipper Lippur.  It wasn't really Chipper.  It was really Tziporah and your parent called you Tzippah.  Which to your friends became Chipper.  Was it ILTC or Kallah?  Or perhaps both.

College

Jon Washington - Hey Jon, where are you.  Did you get that CS degree? I know, I hope I wasn't too bad an influence.

David Bernstein - Last I heard, you have transferred to UT in Austin. Do you know how unlikely it is to find a specific David Bernstein from Chicago?

Tammi Baker - A girl in my Group Dynamics course my final semester at CU.

Bell Labs

Sonja Husby - We dated briefly but you became a really good friend. Good enough that you came to our wedding.  I really can't imagine that you didn't get on the internet somewhere.

Mildred Nabbe - You were my first mentor.  And I suppose that you might have passed away in 25 years that have passed.  But I hope not.  I will never forget your candy jar. (Further research suggests that your maiden name was Mrazek and that you passed away in the late '80s.  Too young.)

StorageTek

Peter Bliss - You were my first manager as a manager and I learned a lot from you. Before STK, you had been a development manager at Lotus for the Agenda product - a product that was really ahead of its time.

Joe Lovato - Another of my second levels whom I really respected.  I can't believe you aren't on the internet somewhere.

Scott Allen - You inherited me three different times, so I don't know what you did to piss off the Gods. I heard you left tech for the ministry. I would still love to hear your thoughts on this whole internet thing ;-)

Pretty much everyone else postdates the internet age so we haven't fallen out of touch (that I know of).

If you know me and your name isn't on this list, you have lots of good company. In 50+ years of life you will touch and be touched by lots of people.  So do feel free to drop a line. 

Monday, October 6, 2014

On JavaOne 2014

Conference Summary

I mostly went to 5 kinds of sessions:
  • java 8 features (streams, lambdas)
  • java mechanics (garbage collecting, classloading)
  • groovy (traits, groovy & java 8, groovy futures)
  • code quality (DDD, code reviews, coding culture)
  • client server (websockets, rest)
The big takeaways included:
  • java 8 is really about enabling parallel execution.  Streams was the driving feature. Lambda expressions exist to support streams (and are incomplete) and type inferencing is required to support lambda expressions. Interface default methods exist to extend existing collections to support streams.  Method references are there to support streams.  Yes, the result is that you can do functional things in java 8, but the goal is parallelism not functional programming.  So there are gaps as well.
  • Groovy seems to be stuck.  They don’t seem to have finalized what they want to do about java 8 features.  And, since they already have many similar but not quite compatible features, they seem to be caught in a paradox.  Should they continue to try to make java programs compile mostly as-is in groovy?  Should they make their existing features work like the java 8 counterparts and potentially break backward compatibility?  Should they try to make both work and complicate the language semantics?  There doesn’t seem to be an easy answer.  And they didn’t have a compelling story around why you should continue to use groovy in the face of java 8.
  • I found that even though I knew about lambda expressions and streams, doing the tutorials really helped make all the blocks fit for me.  You may want to see if anyone is doing similar overviews at your jug back home.
  • The ability to mixin small bits of behavoir in the form of capabilities is an increasingly important design technique for object oriented systems. 

Session Summaries (TL;DR)


Collection and Reduction in the Steams API (Tutorial)

Stream: an abstraction representing zero or more values.  Streams can be sequential or parallel. Elements in a  sequential stream will be provided in sequence.  Elements in a parallel stream may be provided across different threads and different processors and will not appear in sequence. [This actually came from a subsequent presentation.)

Stream is organized as a pipeline
  • source
  • intermediate operations (return streams)
    • map, filter, sort
  • terminal operations (return to the non-stream world)
    • collectors - returns collections
    • reducers - returns values
Really designed to parallel-ize work

There are are large number of out-of-the box collectors such as toList(), joining(), toSet(), averaging(), toMap(), partitioningBy(), groupingBy(). (See java.util.stream.Collectors)

You can also write a custom collector.  A custom collector requires four functions:
  • supplier()         // returns function to create of a new result container
  • accumulator()  // returns function to add a new element into the result container
  • combiner()       // returns function to combine two result containers
  • finisher()          // returns function an optional final transform on the container
If you were going to create a collector that put results into a google guava immutable set:
public class ImmutableSetCollector<T>    implements Collector<T, ImmutableSet.Builder<T>, ImmutableSet<T>>

@Override public Supplier<ImmutableSet.Builder<T>> supplier() {
    return ImmutableSet::builder;
}

@Override public BiConsumer<ImmutableSet.Builder<T>, T> accumulator() {
    return (builder, t) -> builder.add(t);
}

@Override public BinaryOperator<ImmutableSet.Builder<T>> combiner() {
    return (left, right) -> {
        left.addAll(right.build());
        return left;
    };
}

@Override public Function<ImmutableSet.Builder<T>, ImmutableSet<T>> finisher() {
    return ImmutableSet.Builder::build;
}

@Override
public Set<Characteristics> characteristics() {
    return EnumSet.of(Characteristics.UNORDERED);
}

There is an accumulator and a combiner so that the stream can be parallelized.


Rethinking API Design with Traits


I had actually seen the slides before going to the presentation.  But I still got a lot out of it.

Traits are a new feature in Groovy 2.3.

Solving the problem of how to create reusable bits of behavior that can be mixed in to objects/classes.  The previous attempt (@Mixin) had too many limitations.

Java 8 solves the same problem with default methods in interfaces.  Groovy traits can have state where interface default methods can’t.
trait FlyingAbility { 
    String fly() { "I'm flying!" }
}
class Bird implements FlyingAbility {} 
assert new Bird().fly() == "I'm flying!"
Think of traits as a way of expressing the capabilities of a class.

Can be mixed in at runtime.

Really pushing the idea of developing classes by having small bits of behavior that can be mixed together with some custom behavior into a class.

Some AST transformations are not trait compatible.


Reactive Streams with Rx


This presentation just blew past anything I was able to easily understand.

(And I took the coursera course Principles of Reactive Programming so I’ve actually used the scala version of Rx.)

After blowing though 8-10 hours of lecture material from Principles of Reactive Programming in the first 20 minutes or so, he discussed a variety of flow control mechanisms in the context of various netflix systems that had no meaning to me.


Unlocking the Magic of Monads in Java 8


At some point, somebody is going to figure out that the single worst way to describe monads is to start with the terminology that comes from Haskell. Explaining monads by writing pure (or return) and bind methods in java is insane.

I am always looking to deepen my understanding of monads and I am particularly interested how to use or implement the various common monads in Java 8.  And I suspect that if I study the code, I will probably learn something from it.  But you can’t actually do that in these sessions (more on that later), so I was disappointed.


Gradle: Harder, Better, Stronger, Faster

This ended up being little more than a commercial for using gradle over maven. It was also live coded so I can’t refer back to tell you anything more about this presentation.


Real-World RESTful Service Development Problems and Solutions (BoF)

Rolled through 44 slides in 45 minutes.  ‘Nuff said.

I’m sure there is good stuff in the slides somewhere….


JAX-RS REST Services and Angular.js: Tools for an Even Better Experience (BoF)

Kind of a throwaway for me. But it was the 8pm BoF so I didn’t think I was going to be too awake by then anyway.  The last half was live coding a demo which, aside from technical difficulties, was pretty interesting.

Did recommend swagger (https://helloreverb.com/developers/swagger) for rest api docs.

Also recommended using DTOs for the collecting REST data.  He worked on a bean mapper project Dozer but recommended a different mapper Orika (http://orika-mapper.github.io/orika-docs/index.html).


Jump-Starting Lambda (Tutorial)

Lambda expressions mostly appear (but are not necessarily implemented as) syntactic sugar for anonymous inner classes.  So, instead of

void robocallEligibleDrivers() {
    robocallMatchingPersons(new PersonPredicate() {
        boolean test(Person p) {
            return p.getAge() >= 16;
        }
    }
}

You can write:

void robocallEligibleDrivers() {
    robocallMatchingPersons(p -> p.getAge() >= 16);
}

In order to implement lambda expressions, they also had to implement type inferencing. (Which they’ve enabled elsewhere as well.)

The type that is inferred for a lambda is a @FunctionalInterface or Single Abstract Method (SAM) interfaces.

There are a set of standard interfaces so defining your own interfaces is rarely necessary. The standard interfaces are:
interface Predicate<T> { boolean test(T t); }
interface Consumer<T> { void accept(T t); }
interface Function<T,R> {R apply(T t); }
Additional interfaces include:

Supplier<T> () ? T
UnaryOperator<T> T ? T
BinaryOperator<T> (T, T) ? T
BiFunction<T,U,R> (T, U) ? R

Note that when you write methods designed to be called with a lambda, you will use one of the types above as the parameter type:

So, for example, if you were going to write something like Jim’s withSession method in java 8, you would have a signature like:

static void withSession(SlingRepository slingRepository, String user, Consumer<Session> lambda) 

() -> 42                                                     // Need empty parens for a supplier
(int a) -> a + 1
int a -> a + 1                                            // Can omit parens for a single param 
int a -> { println(a + 1); return a + 1; }  // Surround multiple statements  
a -> { println(a + 1); return a + 1; }       // Types may be omitted if they can be inferred
(int a, int b) -> a + b                                // need parens with more than one param

Method references are shortcuts to use methods as lambda expressions:  There are 4 kinds of method references:

Integer::parseInt    // Reference to a static method taking the correct number of parameters
aPerson::toString  // Reference to an instance method of a particular object
Person::toString    // Unbound reference which will be bound by the lambda
String::new            // Constructor

Streams

Sources include stream() methods on collections, Stream.empty(), Stream.of(…). Arrays.stream(), Stream.generate(), Stream.iterate(), Stream.range(), various methods in File, String, Pattern. etc
Intermediate operations include forEach, map, filter, substream, limit, sorted, distinct, flatMap
Terminal operations include collect, toArray, count, anyMatch, findFirst

collect() takes a combining collector.  Some common collectors are toList(), joining(), toSet(), averaging(), toMap(), partitioningBy(), groupingBy()

String result = list.parallelStream()
                           .map(String::toUpperCase)
                           .collect(joining(“, "));  // static import of Collections.*

Convert a sequential stream to parallel using .parallel().

Lambdas change the way you design libraries
Streams change the way you write applications

Method References will take over the world because you can code streams like:
String[] output = list.stream()
                               .map(String::toUpperCase)
                               .toArray(String[]::new);

A couple of specific notes from this presentation and other presentations:
  • Lambda expressions must not mutate source collection while stream executes
  • Lambda expressions do not have identity - you can’t use equals()
  • Lambda expressions are not closures.  Java already had closures which restricted access to instance variables to final.  Java 8 has a broader concept of effectively final but the bottom line is you can’t modify instance variables from inside the lambda expression
  • Lambda expressions can be chained:
    Callable<Runnable> c = () -> () -> { System.out.println("hi"); };
  • There is no direct support for currying. (Some people would say currying is a better alternative to closures.)


WebSocket in Enterprise Applications


Ended up being mostly about the Java API for WebSocket and its reference implementation.


Groovy in the Light of Java 8


Lots of minor reasons to continue to use groovy over Java 8 but it felt somewhat contrived:
  • closure parameter defaults
  • duck typing polymorphism
  • more elegant builder syntax
  • memoization
  • tail recursion
  • traits
  • compile time meta annotations
  • elvis operator
  • groovy on android
  • grails, ratpack, griffon, spock, geb, gradle, GPars, 
  • json support
Hasn’t really come to terms with java 8 features.


Coding Culture


You know those annoyingly always upbeat and relentlessly positive people? Hire only those people and then apply a whole bunch of new age techniques that fly in the face of everything we know about human nature.  When everybody is shiny and happy and all group hugging and refusing to do anything wrong in the “doacracy” then Peter Pan will sprinkle magic dust and miracles will happen.


Getting Started with MongoDB and Java

Turned out to be a live coding session that was mostly mostly derailed by detailed questions only vaguely related to the what the speaker was trying to do.


Using Type Annotations to Improve Code Quality

Mostly a discussion about how you could use the checker framework http://types.cs.washington.edu/checker-framework/ with the java 8 annotation extensions.  Some discussion about how it all might be incorporated into IDEs.  He did a nice demonstration using the regex checker to validate regular expressions at compile time.


Java Debugging


Garbage Collection Monitoring
  • might need to pay to use on servers?
  • -XX:+UnlockCommercialFeatures -XX:+FlightRecorder
valgrind - OS level memory profiling

Heap Dump Analysis:
  • -xx:+HeapDumpOnOutOfMemoryError
  • jmap -dump:format=b
  • JConsole
IBM Memory Analyzer supports HotSpot dumps


Understanding Java Garbage Collection

Best presentation hands down. Here is a version of the presentation of the same talk at a previous conference.  http://www.infoq.com/presentations/Java-GC-Azul-C4

I don’t think I can summarize it in any way that would do it justice.  A couple of notes though:
  • Garbage collection is better than you think it is. In particular, it really will find dead objects. Don’t try to help until you’ve proven the need to. "Trying to solve GC problems in application architecture is like throwing knives.”
  • GC stops for ~1 sec for each live GB
  • “Mostly" is the way vm vendors weasel out of GC guarantees.  Mostly means sometimes it isn’t (usually means a different fall back mechanism exists)
  • Generational Hypothesis: most objects die young
    (A consequence this is that most live objects in the system are actually not young)
    • Which means that you can optimize differently for young objects and old objects
  • The amount of empty memory in the heap is the dominant factor controlling the amount of GC work
    • Empty memory controls the frequency of pauses (if the collector performs any Stop-the-world operations)
    • Empty memory DOES NOT control pause times (only their frequency)
    • In Mark/Sweep/Compact collectors that pause for sweeping, more empty memory means less frequent but LARGER pauses
  • The Application Memory Wall - Application instances appear to be unable to make effective use of modern server memory capacities
    • Garbage Collection is a clear and dominant cause
    • [Virtually] All current commercial JVMs will exhibit a multi-second pause on a normally utilized 2-6GB heap.
      • It’s a question of “When” and “How often”, not “If”.
      • GC tuning only moves the “when” and the “how often” around
    • Monolithic stop-the-world operations are the cause of the current Application Memory Wall. Even if they are done “only a few times a day”


Think Async: Embrace and Get Addicted to the Asynchronicity of Java SE 8 and Java EE 7

Ended up being entirely J2EE focused.  Lots of code examples without real problems to motivate them.  Like why would I want an Asynchronous Servlet for example.

I think this topic slide pretty much summarizes the whole press:
  • Long present in JMS
    • To be used almost everywhere
  • Servlet 3.0/ 3.1
    • Asynchronous Servlets
    • Non blocking IO
  • JAX-RS 2.0
    • Server side
    • Client side
  • Asynchronous Session Beans
    • Server side
    • Client side
This was also the second presentation that mentioned but didn’t really describe Server-Sent Events which is a technology that could have some interesting uses on a site like timewarnercable.com


Programmatic WebSocket

This was a walkthrough of a sample program that used java websockets on both client and server.  The program built a custom document-oriented rpc on top of websockets using xdr encoding.  As a result, so much of this was custom code that it was hard to get anything out of the presentation.


DDD in a Rapidly Changing Organization

I wish I had the slides for this. After an intro of DDD and XP, he discussed some lessons learned in that environment.

There was some “DDD sales pitch” kind of stuff particularly about improving communication with the marketing team.

A lot of the lessons were around the problem that their marketing group changes terminology faster than they can change implementations.  Essentially marketing changes terminology because changing the name changes the perception. This caused a number of technical problems.  One example that that they had used mock heavy TDD, so making even simple changes to the model often required changing dozens of tests.  They they resisted making model changes. 

There was another lesson that they had been hurt by too strict adherence to DRY.


Do You Really Get Class Loaders?

This is the same presentation by a different presenter (from the same company): http://www.slideshare.net/guestd56374/do-you-really-get-class-loaders.  (At least until you get to the end.)

Classloaders are organized hierarchically.  And, unless you arrange differently (which OSGI does), classes are loaded from the highest classloader possible.

A class has an identity of three things: a name, a package, and a classloader.

A couple of debugging tricks:
  • You can always get the classloader for an object (or class):
    Class klass = object.getClass();
    ClassLoader classloader = klass.getClassLoader()
  • You can cast a classloader to a URLClassLoader and use the getUrls method to get the paths in the classpath:
    URL[] urls = ((URLClassLoader) classloader).getUrls();
  • You can find which file a class was loaded from:
    URL url = klass.getResource(“/“ + klass.getName().replaceAll("\\.", "/") + ".class”);
  • Someone pointed out that you can also use the following:
    klass.getProtectionDomain().getCodeSource().getLocation();
When you leak a classloader, you leak all the classes it has loaded.


Groovy in 2014 and Beyond


Covered a lot of changes already in 2.3.

Groovy 2.4
  • New groovy-lang.org website
  • Groovy on Android
  • Macro module (maybe)
Groovy 3.0
  • Rewritten Meta-Object protocol
  • New antlr grammar
  • Java 8 language support (definitely not solidified)
  • Can they continue to make valid Java syntax work in groovy?
  • lambdas
  • method references
  • interface default methods


Want Code Quality? Just —The Art of the Code Review

You should do code reviews. And if anyone doesn’t like it, you should manipulate them into liking it.


Closing Keynote

Mostly and advertisement for Intel and various companies using Java.  But the technical part of the opening keynote apparently had run too long so the last half was moved here as well.  The interesting takeaway is that they are working on real value objects (http://openjdk.java.net/jeps/169) for java 10 which apparently will be a big change.  They are also redoing the module system (http://openjdk.java.net/projects/jigsaw/) in java 9.


Conference Review (Really TL;DR)

JavaOne is the tale of The Good, The Bad, and The Ugly

The Good

Several of the presentations were outstanding.  World class presentations by real experts. Even the presenters that weren’t great were certainly experts.  All-in-all the content was good and where it wasn’t I could probably have done a better job of picking sessions. (Yes, I’d like to learn websockets. I’m not sure why I thought I would be able to here.)

The Bad

The conference is too big which effects everything.  Long lines everywhere. Particularly for morning coffee and meals.  

Full sessions which required pre-registration to get in. Which means that you couldn’t get interesting in something and just jump into further sessions on the topic. Nor could you bail on a session and expect to be able to walk into another one.

No meal breaks? Really? All meals to go? Really? Long lines to get meals with no actual meal breaks? Really? I’m not doing the late night drinks at Duke’s Cafe - particularly when sessions run until 8:45 pm.  So meals are when I would expect to be able to meet my peers and swap stories. (Fortunately for me, it just gave me an excuse to run out to various take out places across various streets from the conference hotels which had shorter lines and better food. Definitely try the Filipino place across from the Hilton!)

The "appreciation event".  I didn’t come to the conference to be appreciated. I came to learn things. I really just feel like I missed out on what could have been a couple more interesting presentations. 

The Ugly

Some of the rooms were too small for the number of seats - and all the seats were full. Airplanes seats have more room. I had to leave the first tutorial at the half-way point because I was getting faint in the room. I had to organize the remainder of the conference to get to rooms when they opened entry to get aisle seats where I could make room.

No power. And no tables. I don’t know how they expect anyone to take any real kind of notes.

No slides.  As you can tell from the summaries above, I found some presentations really hard to follow.  If you are going to do a technical presentation, you need to provide slides so that I can glance back and forward to get my bearings when I start to get lost. (And all technical presentations have those moments where you start to get lost.)  And none of these “no more than one word per slide” presentations that provide no information on the slides. If this is a technical presentation, I expect 4-10 bullets per slide or code examples. Otherwise, you’re just Steve Jobs putting on a show. And whoever came up with live-coding should be shot. And then burned. And maybe stabbed for good measure.

My Net Promoter Score - maybe a 5.  Good content but, IMO, extremely poor logistics for a technical conference driven in part by the size of the conference.

Friday, June 22, 2012

On the Hubris of the Modern Software Industry

Here I sit at Uberconf.  While this should be a fun three learning-filled days, I find myself growing increasingly frustrated and disappointed.  I had not realized that my industry had become so filled with hubris, so blinded by the sparkle of the latest, so contemptuous of experience and expertise.

I remember my early 30s, being a unix guy in a mainframe company.  I remember that we certainly believed that we were on a better technology, one that was easier and more fun to use.  What I don't remember was ever believing that we were better or smarter as programmers than the mainframe guys (and a few women) across the hall.  Like us, they were a mixed bag.  Some folks I really respected and some that I wouldn't have let check in code.

So the disdain that our industry now holds for java programmers, or perhaps I should say "just" java programmers came as a complete surprise.  After all, technology (language, tools, frameworks) has as much to do with programming skill as sneakers have to do with basketball.  The hallmarks of great programmers, in my experience, are the ability to think deeply about problems, decompose solutions into pieces that fit neatly together, hold an abundance of detail in mind, and an obsession with the code being right.  There is nothing there that is specific to scala or java or c or lisp.

"But, But," I hear you say, we want programmers who want to "learn".  As if the only thing to learn is the language de jour or the new fad platform.  One of the worst programmers I've worked with was a great learner, an awesome technologist, always up on the latest thing.  We used to say that his expertise ran a mile wide and an inch deep.  The skill I want is not learning but mastery.  I will take someone who has mastered a technology, really mastered it, over anyone content with merely chasing the latest technologies.

Of course, that doesn't mean that any programmer should (or can) stay with a single technology for the bulk of their career.  Technology does change and the languages of my youth are no longer in common use.  But it is also true that new languages, new technologies become easier and easier to learn.  Today's technologies all have their roots in the past and the lessons learned then still apply.

So, really, I just want to say to today's programmers, get over yourselves.  You are neither the best nor the worst nor is your experience unique.  Its great to be obsessed by programming, in my experience all the great programmers are at some point in their careers.  And don't be surprised when life presents other attractions and other challenges, when learning the next big thing takes a back seat to taking care of the little peep in the back seat.  It won't make you any less excellent as a programmer, it just means the 30 somethings will think so.






Saturday, March 3, 2012

On Azitra Restaurant

A couple of weeks ago while we were driving around looking for El Tapatio (a restaurant to avoid), we discovered there was a new Indian restaurant across the street from Flatirons Mall.  Azitra is clearly aiming at providing a more upscale Indian restaurant.  The decor is elegant earth tones, no wall hangings with elephants here.  The usual dishes are on the menu but usually with some twist.  And there is no buffet.  Overall, we enjoyed the dinner but we aren't quite sure about the restaurant so we will have to visit again before deciding whether to add it to our regular Asian night rotation.

The Good: The Chatpata Murg appetizer was very good with the pan glaze adding a nice bit of sweetness to to heat of the dish.  The little glaze that remained on the dish after the chicken was done made a nice condiment for the naan.  My medium heat chicken curry was also nicely balanced.  Northern Indian comfort food, the curry was thick, rich, with a nice hint of coconut milk.

The Bad: Melissa had a mild heat Tandori Chicken Tikka.  I don't know why Melissa gets mild dishes in Indian restaurants - she loves Mexican food and good Colorado green chili.  Apparently mild at Azitra means flavorless.  Our normal strategy at Indian restaurants is to split entrees.  After the first bite of hers, I refused to have any more.

The Ugly: Worst. Chai. Ever.  I realize that chai isn't always served as richly spiced as we have become accustomed to in America.  We learned that at our numerous means on Brick Lane in London.  Still, the chai here tasted completely unspiced.  Little more than black tea with cream.  And much stronger than I take my team.  If your taste in coffee runs to Turkish, you might enjoy the tea here.

The Scary: Big room that never got full on a Friday night.  They've been in this location for 4 or 5 months and I'm not sure whether they will survive or not.  The location is not good for a restaurant.  Its not actually on the flatirons ring road.  Instead it is in the set of building behind near Benihana's.  Flatirons is a regular shopping destination for us (and I've eaten at nearby Jason's Deli several times recently) and we had no idea this was here. This plus the fact that they are aiming at a more upscale experience and are correspondingly more expensive than the usual Indian restaurant, makes it likely this place is going to struggle.  I hope they succeed because Melissa and I would really like to have more Indian options than just Jewel of India (which we like) and Yak and Yeti which we don't.

Sunday, February 5, 2012

On a Jew's View of Muslims in Europe

I have written about this in other forums, but now that I'm maintaining a blog, I thought I would add a post on the topic here.  A friend recently forwarded an article that was purportedly published in a Spanish newspaper (although apparently not) with the thesis that European guilt over the Holocaust has led to a too lenient treatment of Muslim immigrants and that effectively trading Muslims for Jews has been a horrible choice.

Here is my response (slightly modified).

First, tripe about English schools not teaching the holocaust, is just that. It is well debunked and only dedicated racists are still using it.

Second. the description of the Jewish community that was destroyed in the Holocaust is simply wrong. Yes, there was a vibrant and cultured Jewish community in Germany and other Western European countries that was destroyed.  They were educated at fine German universities and produced the kind of brilliant thinkers like Einstein and Freud that German universities of the era produced. And this was a tragedy.  But they were a small minority of Jews killed in the Holocaust. Most were villagers from eastern Europe. There were more Jews from Poland killed in the Holocaust than Jews from the rest of Europe combined. These communities were not cultured, they did not produce brilliant thinkers.  And their destruction was every bit as tragic.  Because the murder of a poor subsistence farmer is every bit as tragic as the murder of brilliant scientist when done simply because the victim has a particular race or religion.

Like all bigots, the Nazis rewrote history to justify their ideology.  And that is just what this author does.

Lumping of all Muslims into a single collective enemy who seeks the destruction of Europe is exactly what the Germans said.  Oh wait, that was the Jews who were bent on the destruction of Europe.  The Jews who were cultural poison.  I won't claim to know much about Islamic immigrant communities in Europe, but I can speak to the ones here.  They have been surveyed extensively and, survey says, they are much like other American immigrants.  Hardworking, patriotic, grateful for the opportunities that America provides. Before 9/11 most were Republicans.  The typical Muslim immigrant in America is no more extremist than my grandfather was.

Are there Islamic extremists?  Obviously.  Saudi Arabia seems to have a national system of education to produce them.  There are also Jewish extremists, or have you missed the growing communities of Haredi in Israel.  There are Christian extremists too, think Randall Terry or Fred Phelps.  To generalize from the small minority of crazy extremists to whole communities is the definition of bigotry.

In all likelihood, it is true that the Islamic immigrant communities in Europe are poor and dirty. That describes immigrant communities throughout history and across the globe. It is not usually the rich and well educated in society who immigrate, it is the poor and uneducated. We idealize it now, but the lower east side was described in its time as hell on earth and the worst place in the world.  And the Jews (and others) who populated were despised by the good citizens of the city.  They were excoriated as anarchists and terrorists, as dirty and uneducated, as trash.  Immigration laws were rewritten to keep them out.  There is nothing said about Muslim immigrants in Europe today that was not said about my great grandparents and their generation in America.

And if Muslim immigrants get help from the government, so to did the Jewish children of those times who escaped the horrors of the lower east side through the beneficence of a government that invested in public education not just for primary school but also the excellent system of higher education, the City Colleges of New York.

It is quite simple, the author argues for racism and bigotry. The kind of racism and bigotry that has ostracized Jews in America and around the world and resulted in the murder of 6 million Jews in Europe.  As a Jew, I find the use of the Jewish experience to justify bigotry (and, let's face it, racism) to be a particularly odious obscenity. It literally spits on the history of my people and my ancestors and I couldn't find it more offensive. Islam isn't the enemy, bigotry and extremism are.

Tuesday, January 24, 2012

On Why Scala is The Perl of JVM Languages

One of my first technical jobs was to develop a system in APL.  There are two lessons I still carry from that experience: one, I can write any program with fewer characters and two, that doesn't make it a better program.   The mark of a great programming language is not the number of characters you can write a program in (see: APL) but how well the language allows the program author communicate with program readers.  Is the meaning of sentences and paragraphs of the language obvious or do I have to "work it out."

Unfortunately, Scala (and most other modern JVM languages) seems to have learned all the wrong lessons from Perl.  When I hear programmers make fun of Perl, I understand that they are really making fun of all those unreadable Perl programs they've had the misfortune to have to have read.  You didn't have to write programs that way in Perl (and I didn't) but it sure seemed like there were too many $s, @s, bless this, and optional parameters that defaulted to $_ and just what did that evaluate to in the middle of a map.

And Scala does all of that.  Implicit conversions.  Methods that use symbols for method names.  A type system that used + and -, :< and >: to differentiate covariant and contravariant type and upper and lower type bounds and who even understands what those things are.  Semicolons are optional except when they're not.  Braces are optional except where they are not and sometimes they become parenthesis.  And too many nifty ideas like case classes that don't work with the rest of the language.

Look, we can all agree that Java suck.  I learned object oriented programming in Smalltalk.  Java really sucks.  And collection classes require functional programming techniques to really work well.  I am certain that you can write code in Scala that is more elegant and more expressive than Java.  And I am equally certain that you can write code in Scala that makes the typical CPAN library seem like a beacon of clarity.  Scala may be a better choice than Java, but that doesn't make it a good language.

And I like programming in Perl.

Sunday, January 22, 2012

On Why is George Karl Still Coaching?

The Nuggets won a close one last night in New York.  Playing their fifth game in seven nights and having arrived at 4:00 am, the team was clearly exhausted in the fourth quarter and overtime.  This was made worse by the short bench of Coach Karl, he played only seven players.  In the back court, this was forced by injuries.  But in the front court, this was a result of inexplicable decisions by the coach.  While Timofay Mozgov had one of his better games, in what universe is he a better player than Chris Anderson who Karl is increasingly reluctant to play?  Here are the per/48 stats:

Raw Stats
MinWP48WinsPTSDRBORBREBASTTOBLKSTLPF
Andersen204.2361.016.09.94.514.40.21.23.52.46.4
Mozgov284.0240.115.28.82.911.72.03.02.50.76.3


And here are the shooting efficiency stats:

Shooting Efficiency
FG%2FG%3FG%FT%eFG%TS%FGA3FGAPPSFTA
Andersen51.2%51.2%0.0%66.7%51.2%57.8%10.10.01.588.5
Mozgov52.1%52.1%0.0%73.7%52.1%55.3%12.30.01.233.2


By the stats, Anderson is not just a better player, he is a MUCH better player.  And he can't get off the bench in a game where the team is playing tired?  A game where they were giving up second and third attempts because they were too tired to rebound.  Really?

The Nuggets are an interesting team this year, a team of a bunch of good but not great players.  The only clearly bad player on the team is Mozgov who is a Doug Moe big stiff.  He's 7'1" and can't rebound.  This team will go only as far as George Karl's personal decisions allow, which is apparently not very far at all.