toandv
toandv @ Snip2Code
4 Snippets  (184th place)
Published
1 Channel
Created
1 Channel
Following
3 points  (21185th place)
Reputation
Junior Code Generator
Junior Popular Coder
Junior Autobiographer
Senior Autobiographer

## Recent Snippets See all snippets by toandv

### Array Covariance

Array Covariance: ArrayCovariance.scala
```// Arrays are covariant in Java, but it's not necessary.
String[] s = new String[2];
Object[] o = s;
o[0] = 1; // ArrayStoreException

// Arrays in Scala are not covariant
val a: Array[NonEmpty] = Array(new NonEmpty(1, Empty, Empty))
val b: Array[IntSet] = a // Compilation error

```
;

### CharFrequency.java

CharFrequency.java: CharFrequency.java
```/* Given a string of lowercase characters, write a method that will
* return an array of characters in descending order of frequency.
* If multiple characters have the same the number of occurrences, output
* them in alphabetical order.
*
* For example, given:
*
* Result = {'d', 'a', 'b', 'c', 'e'}
* 'd' occurs 5 times,
* 'a', 'b', 'c' occurs 3 times, so they are ordered alphabetically,
* 'e' occurs 1 time
*/
public char[] charFrequency(String s) {
return new char[0];
}

```
;

### Clojure is for type B personalities

Clojure is for type B personalities: clojure_is_for_type_b_personalities.md
```The other day, I was wondering why Clojure fits my brain so well. I think I was relaxing on my old couch, drinking cheap beer, eating a gas station pastry, and drawing doodles on a stack of overdue bills I forgot to pay. Little did I realize, these things are all connected.

I have a hypothesis that people choose programming languages based on their personality. For the purposes of this write-up, I’ll use the well-known distinction between type A and type B people. This may be pop psychology stuff, but it’s convenient for my point so in the spirit of American politics I will treat it as fact.

## Type A vs Type B

Type A people are very organized, competitive, punctual, and like to plan ahead. When I was a kid, these were the ones who had perfect grades, competed in track or swimming, and on top of that they were nice people so I couldn't even hate the fuckers. Type B people, on the other hand, are laid back and like to do things spontaneously. Like The Dude from *The Big Lebowski*, they are comfortable with unknowns and rely on serendipity to guide them.

Here's the hypothesis: As programmers, type A people gravitate towards languages that are stricter and require more up-front work to get code to run. This includes static typing and compiler-enforced style rules. In contrast, type B people prefer languages that enforce very little at compile-time. They place more value on the ability to change a live program with a REPL, so they can make quick, spontaneous changes with little pre-planning.

## Top Down vs Bottom Up

Type A people prefer a "top down" methodology, modeling everything in types and planning out the architecture before any functionality is implemented. You see this in the "API first" approach in object-oriented languages like Java. You also see it in ML family languages like Haskell, where you are often advised to follow type-driven development (writing type signatures before implementing anything).

Type B people prefer a "bottom up" methodology, immediately implementing functionality and interactively building on previous work until a larger structure emerges organically. You see this in the Lisp community, where REPL-driven development is the norm. The notion of starting from the bottom is also reflected in the prose of a well-known Canadian rapper who claims to come from humble beginnings.

## Kobe vs Shaq

As a fan of both basketball and pointless sidetracking, I'll take a moment to bring up my favorite example of this psychological dichotomy. Kobe epitomizes the type A persona. He was obsessively competitive and had an [inhuman work ethic](https://www.reddit.com/r/nba/comments/2dzolu/compilation_of_kobe_bryant_stories/). There is no doubt in my mind that Kobe wouldn't even begin building a Twitter clone until he had it all mapped out in diagrams and type signatures, and had all contributors sign a blood pact that their first born would be sacrificed if they violated whitespace conventions.

Shaq was an entirely different beast. His laziness is perhaps equally legendary, and is one of the reasons he [feuded with his teammate](https://en.wikipedia.org/wiki/Shaq%E2%80%93Kobe_feud). It's been said that Shaq played basketball to do all the things he really wanted to do: making terrible movies, rapping about Kobe eating his ass, and [holding things](https://www.reddit.com/r/shaqholdingthings). Shaq's Twitter clone would be running directly out of his own personal REPL session, projected next to his indoor pool so he could hack on production code by shining a laser pointer from his floating lounge chair.

## Better for what?

A top-down approach seems ideal for well-understood problems where correctness is the most important attribute. If you're making accounting software, or the avionics software for a plane, you're not necessarily blazing any trails. You have a list of requirements, and you need to satisfy them with minimal defects -- especially if money and lives are on the line.

A bottom-up approach works well for projects with a lot of unknowns, like artificial intelligence or anything artistic. Paul Simon didn't come up with *The Sound of Silence* from a list of requirements. He sat in his bathroom with the lights off and riffed on his guitar until genius poured out. It's no accident that there are Clojure projects like [Overtone](https://github.com/overtone/overtone) and [Quil](https://github.com/quil/quil). A REPL session is the programmer's guitar riff.

## Culture Shock

Your personality is a deep-seated and, yes, *personal* thing. When you are confronted with someone with an opposite personality, it's not uncommon to feel a visceral reaction. When a type A programmer looks at a type B programmer's code, they see an unmaintainable mess. When the reverse happens, they see an over-architected nightmare. Both may very well be right.

Clojure author Rich Hickey is an obvious example of a type B programmer. He's a brilliant language designer and public speaker, but he has coding habits that drive type A people batty. Clojure's code has a notoriously [weird Java indentation style](https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/ARef.java), he often commits [his personal IntelliJ files](https://github.com/clojure/clojure/commit/36d665793b43f62cfd22354aced4c6892088abd6), and it isn't hard to find his [commented REPL scratch pad](https://github.com/clojure/clojure/blob/59b65669860a1f33825775494809e5d500c19c63/src/clj/clojure/zip.clj#L281) in random places. He also looks a bit like The Dude.

## Stop the War

When looking at languages through this lens, it becomes obvious that a lot of internet flamewars are predicated not on objective disagreements, but subjective personality differences. It explains why some people use a language like Clojure and are immediately smitten, while others have an allergic reaction.

The correct -- though pathetically diplomatic -- take-away from this is that both sides are right. The type A programmers are right that correctness and uniformity is important for building robust, maintainable software. The type B programmers are right that a tight feedback loop and experimentation is important for building simple, innovative software.

Maybe some day we will figure out how to get the benefits of both. If you think we already have, and that your favorite language provides the answer, you probably haven't thought hard enough about the problem. Beneath that cold, rational shell, you are a warm-blooded mammal with a unique emotional tapestry that reveals itself in every line of code you write.

```
;

### Latency numbers every programmer should know

Latency numbers every programmer should know: latency.markdown
```### Latency numbers every programmer should know
L1 cache reference ......................... 0.5 ns
Branch mispredict ............................ 5 ns
L2 cache reference ........................... 7 ns
Mutex lock/unlock ........................... 25 ns
Main memory reference ...................... 100 ns
Compress 1K bytes with Zippy ............. 3,000 ns  =   3 µs
Send 2K bytes over 1 Gbps network ....... 20,000 ns  =  20 µs
SSD random read ........................ 150,000 ns  = 150 µs
Read 1 MB sequentially from memory ..... 250,000 ns  = 250 µs
Round trip within same datacenter ...... 500,000 ns  = 0.5 ms
Read 1 MB sequentially from SSD* ..... 1,000,000 ns  =   1 ms
Disk seek ........................... 10,000,000 ns  =  10 ms
Read 1 MB sequentially from disk .... 20,000,000 ns  =  20 ms
Send packet CA->Netherlands->CA .... 150,000,000 ns  = 150 ms

Assuming ~1GB/sec SSD

![Visual representation of latencies](http://i.imgur.com/k0t1e.png)

Visual chart provided by [ayshen](https://gist.github.com/ayshen)