<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3460761117713509776</id><updated>2011-12-26T13:19:37.664-08:00</updated><category term='welocme'/><category term='cooking'/><category term='lectures'/><category term='tübingen'/><category term='reviews'/><category term='linguistics'/><category term='politics'/><category term='rants'/><category term='music'/><category term='lisp'/><category term='philosophy'/><category term='Java'/><category term='Prolog'/><category term='Haskell'/><category term='overheardin'/><category term='Code'/><category term='category theory'/><category term='Computational Semantics'/><category term='german'/><category term='tips'/><category term='unix'/><category term='depressions'/><category term='zsh'/><category term='trivia'/><category term='vim'/><category term='BA thesis'/><category term='LaTeX'/><title type='text'>?- true.</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://a-dimit.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://a-dimit.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>adimit</name><uri>http://www.blogger.com/profile/04917371723395784281</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_h4s_XF6s_5o/SIo9zlI9jjI/AAAAAAAAAAM/pP0yRe0g0SI/S220/dsc00206square.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>25</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3460761117713509776.post-9180238172199974457</id><published>2011-11-22T14:09:00.001-08:00</published><updated>2011-11-23T05:11:07.927-08:00</updated><title type='text'>Re: Highbrow Java; Or: Java Generics and Why I Still Hate Them</title><content type='html'>&lt;div id="TOC"&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="#type-safety-and-type-polymorphism"&gt;Type Safety and Type Polymorphism&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="#erasure"&gt;Erasure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#reifcation"&gt;Reifcation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#generics-have-poor-support-for-arrays"&gt;Generics Have Poor Support for Arrays&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#inner-classes-of-polymorphic-classes-may-not-be-used-as-array-component-types"&gt;Inner Classes of Polymorphic Classes May Not Be Used as Array Component Types&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#no-polymorphism-for-exceptions"&gt;No Polymorphism for Exceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#static-fields-of-generic-types"&gt;Static Fields of Generic Types&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#downcasting-towards-a-polymorphic-type-is-always-unsafe"&gt;Downcasting Towards a Polymorphic Type is Always Unsafe&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#theoretically"&gt;Theoretically…&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;This, well, rant, originated as a more elaborate answer to a &lt;a href="http://texttheater.net/highbrow-java"&gt;comment on an article&lt;/a&gt; I left unanswered for over half a year. I wanted to apologise by coming up with a rather exhaustive answer. Turns out I got exhausted before I could finish complaining, so I'll just post what I have right now and will continue ranting at some later stages.&lt;/p&gt;
&lt;p&gt;Because this is so long, I'll save everyone the trouble and give an abstract: I argue that, while generics were a neccessary and &amp;quot;good&amp;quot; addition to Java, this particular implementation of what is in essence second-order typed lambda calculus, is poor and severly limits the compiler's ability to guarantee run-time type safety. Turns out I'm focussing on arrays (again,) but that was the low hanging fruit. I'll get to the lack of expressive power in a later post.&lt;/p&gt;
&lt;h2 id="type-safety-and-type-polymorphism"&gt;&lt;a href="#TOC"&gt;Type Safety and Type Polymorphism&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Why do we care about static type systems and type safety? I think one can discern two major points, quoting from &lt;a href="http://en.wikipedia.org/wiki/Type_system#Static_typing"&gt;Wikipedia&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Static typing is a limited form of program verification&lt;/li&gt;
&lt;li&gt;Program execution may also be made more efficient by omitting runtime type checks and enabling other optimizations.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I actually only care about the first point: a good type system can catch mistakes in code paths rarely taken, which may have otherwise eluded testing. It may successfully shift some of the debugging effort from &lt;a href="http://www.angelikalanger.com/GenericsFAQ/FAQSections/Fundamentals.html#What%20is%20the%20benefit%20of%20using%20Java%20generics?"&gt;run-time to compile-time&lt;/a&gt;. The merit of any performance gain during run-time is debatable, and certainly not a really strong argument in my opinion.&lt;/p&gt;
&lt;p&gt;What object-oriented programmers refer to as &lt;em&gt;generic programming&lt;/em&gt; is &lt;strong&gt;parametric polymorphism&lt;/strong&gt; (as opposed to ad-hoc or subtype polymorphism, both of which Java also supports.) Parametric polymorphism is also famously captured in &lt;a href="https://en.wikipedia.org/wiki/System_F"&gt;System F&lt;/a&gt;, or polymorphic (or second-order typed) lambda calculus. It introduces &lt;em&gt;universal quantification&lt;/em&gt; over types. There's a similar system developed by &lt;a href="http://theory.stanford.edu/~jcm/papers/mitch-plotkin-88.pdf"&gt;Mitchell &amp;amp; Plotkin (1988)&lt;/a&gt;, which introduces &lt;em&gt;existential quantification&lt;/em&gt; instead.&lt;/p&gt;
&lt;p&gt;Prior to 1.5, Java lacked any kind of &lt;a href="http://en.wikipedia.org/wiki/Type_polymorphism#Parametric_polymorphism"&gt;parametric polymorphism&lt;/a&gt;&lt;sup&gt;&lt;a href="#fn1" class="footnoteRef" id="fnref1"&gt;1&lt;/a&gt;&lt;/sup&gt;. The need for parametric polymorphism in a statically typed programming language should be obvious to any reader: it heightens the expressive power of the type system without compromising on &lt;em&gt;type safety&lt;/em&gt;. Thus, generics were a step in the right direction.&lt;/p&gt;
&lt;p&gt;An important mental note: in OOP terminology, &lt;em&gt;polymorphism&lt;/em&gt; usually refers to &lt;em&gt;subtype polymorphism&lt;/em&gt;. Sometimes polymorphic methods are mentioned, which correspond to &lt;em&gt;ad-hoc polymorphism&lt;/em&gt;. When I refer to &lt;em&gt;polymorphism&lt;/em&gt; in the rest of this text, I will mean the &lt;em&gt;parametric&lt;/em&gt; kind, i.e. &lt;em&gt;generics&lt;/em&gt;.&lt;/p&gt;
&lt;h3 id="erasure"&gt;&lt;a href="#TOC"&gt;Erasure&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In Java, generics are &lt;em&gt;only used at compile-time&lt;/em&gt;. The JVM isn't even aware of the existence of generics. This is called &lt;em&gt;erasure&lt;/em&gt;, and it exists purely for backwards compatibility reasons. It leads to several unfortunate problems with &lt;em&gt;type safety&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;When programming with generics in java, I'm always amazed by the amount of explicit casting one has to perform. Ideally, you'd never want to ever do that. Explicit casts can't generally be checked at compile time — we give up type safety by using them.&lt;/p&gt;
&lt;h3 id="reifcation"&gt;&lt;a href="#TOC"&gt;Reifcation&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The opposite of erasure is &lt;em&gt;reification&lt;/em&gt; — a very fancy name deriving from the latin word &lt;em&gt;res&lt;/em&gt; (&lt;em&gt;thing&lt;/em&gt;.) &lt;a href="http://shop.oreilly.com/product/9780596527754.do"&gt;Naftalin and Wadler&lt;/a&gt; thus call it &lt;em&gt;thingification&lt;/em&gt;. For us, it means that a type carries &lt;em&gt;run-time&lt;/em&gt; information about itself. A &lt;code&gt;Number&lt;/code&gt; knows it's a &lt;code&gt;Number&lt;/code&gt; at run-time, and you can retrieve that information using the reflection API. A &lt;code&gt;List&amp;lt;Number&amp;gt;&lt;/code&gt; only knows it's a &lt;code&gt;List&lt;/code&gt;, but it has no idea about the fact that it's carrying &lt;code&gt;Number&lt;/code&gt;s.&lt;/p&gt;
&lt;p&gt;The &lt;a href="http://gafter.blogspot.com/2006/11/reified-generics-for-java.html"&gt;proposal&lt;/a&gt; for &lt;em&gt;Reified Generics&lt;/em&gt; thus would either completely throw out type erasure, or allow some sort of explicitly reified generics syntax.&lt;/p&gt;
&lt;p&gt;There currently are only a couple of non-reifiable types in Java:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;type variables&lt;/li&gt;
&lt;li&gt;instantiations of polymorphic types (such as &lt;code&gt;List&amp;lt;String&amp;gt;&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;bounded instantiations of polymorphic types (such as &lt;code&gt;List&amp;lt;? extends Number&amp;gt;&lt;/code&gt;)&lt;sup&gt;&lt;a href="#fn2" class="footnoteRef" id="fnref2"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="generics-have-poor-support-for-arrays"&gt;&lt;a href="#TOC"&gt;Generics Have Poor Support for Arrays&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Arrays in Java feel like a wart nowadays, especially in the presence of generics. There is one cruicial constraint on array &lt;em&gt;creation&lt;/em&gt;, which makes it utterly annoying to use them: &lt;em&gt;the component type of an array must be reifiable&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;See, given a type variable &lt;code&gt;T&lt;/code&gt;, &lt;code&gt;T[]&lt;/code&gt; is perfectly valid in Java. The &lt;a href="http://download.oracle.com/javase/6/docs/api/java/util/Collection.html"&gt;&lt;code&gt;Collection&lt;/code&gt; interface&lt;/a&gt; defines a method &lt;a href="http://download.oracle.com/javase/6/docs/api/java/util/Collection.html#toArray(T[])"&gt;&lt;code&gt;&amp;lt;T&amp;gt; T[] toArray(T[] a)&lt;/code&gt;&lt;/a&gt; after all! But there's something fishy about this method: why do I need to pass it an array? And isn't &lt;code&gt;Collection&lt;/code&gt; defined as &lt;code&gt;Collection&amp;lt;E&amp;gt;&lt;/code&gt;? &lt;code&gt;T&lt;/code&gt; is only in scope for this one method, as can be gleaned from the type signature. &lt;code&gt;T&lt;/code&gt; has nothing to do with &lt;code&gt;E&lt;/code&gt;. The following code typechecks:&lt;/p&gt;
&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode java"&gt;Collection&amp;lt;String&amp;gt; cs = &lt;span class="kw"&gt;new&lt;/span&gt; ArrayList&amp;lt;String&amp;gt;();&lt;br /&gt;Number[] na = cs.&lt;span class="fu"&gt;toArray&lt;/span&gt;(&lt;span class="kw"&gt;new&lt;/span&gt; Number[&lt;span class="dv"&gt;10&lt;/span&gt;]);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There's an alternative method &lt;code&gt;Object[] toArray()&lt;/code&gt;, which is more along the lines of what you'd expect such a method to do. It &lt;em&gt;creates&lt;/em&gt; the array for you, (that's the point after all,) but it creates an array of the generic &lt;code&gt;Object&lt;/code&gt; type which you'd have to cast into something more appropriate yourself.&lt;/p&gt;
&lt;p&gt;The cause of this idiosyncracy is simple: you cannot write code that explictly creates arrays with non-reifiable component types. Recalling our earlier list, it means that type variables and (bounded) instantiations of polymorphic types cannot be used for arrays without casting explicitly.&lt;/p&gt;
&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode java"&gt;&amp;lt;T&amp;gt; &lt;span class="dt"&gt;void&lt;/span&gt; &lt;span class="fu"&gt;f&lt;/span&gt;() {&lt;br /&gt;    T[] a              = &lt;span class="kw"&gt;new&lt;/span&gt; T[&lt;span class="dv"&gt;1&lt;/span&gt;]; &lt;span class="co"&gt;// error&lt;/span&gt;&lt;br /&gt;    List&amp;lt;Integer&amp;gt;[] il = { Arrays.&lt;span class="fu"&gt;asList&lt;/span&gt;(&lt;span class="dv"&gt;1&lt;/span&gt;,&lt;span class="dv"&gt;2&lt;/span&gt;) }; &lt;span class="co"&gt;// error&lt;/span&gt;&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Both of these lines will fail with &lt;code&gt;generic array creation&lt;/code&gt; (hooray for descriptive compiler error messages.)&lt;/p&gt;
&lt;p&gt;But wait, how do the collection classes like &lt;code&gt;ArrayList&lt;/code&gt; do it? Don't they have to use arrays with a polymorphic component type internally? Yes, they do. And you &lt;em&gt;can&lt;/em&gt; create generic arrays:&lt;/p&gt;
&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode java"&gt;T[] ta = (T[]) &lt;span class="kw"&gt;new&lt;/span&gt; Object[&lt;span class="dv"&gt;1&lt;/span&gt;]; &lt;span class="co"&gt;// unchecked&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since the compiler cannot ensure the above line will actually work at runtime, it issues an &amp;quot;unchecked&amp;quot; warning for this line of code (see &lt;a href="#downcasting-towards-a-polymorphic-type-is-always-unsafe"&gt;below&lt;/a&gt;.) The compiler is right, too. &lt;code&gt;ta&lt;/code&gt; now has the run-time type &lt;code&gt;Object&lt;/code&gt; not whatever &lt;code&gt;T&lt;/code&gt; is! So if you instantiate &lt;code&gt;T&lt;/code&gt; to, say &lt;code&gt;String&lt;/code&gt;, and try to store it as a &lt;code&gt;String[]&lt;/code&gt;, you will receive a run-time error even though you didn't explicitly cast anything!&lt;/p&gt;
&lt;p&gt;Naftalin &amp;amp; Wadler thus tell you to adhere to the &lt;em&gt;The Principle of Truth in Advertising&lt;/em&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The reified type of an array must be a subtype of the erasure of its static type&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That's quite a mouthful isn't it? I recommend reading the appropriate chapter 6.5 in Naftalin &amp;amp; Wadler (2006) for more information, but the gist is this: The run-time type of any array must be a the same as or a subtype of what is left of its compile-time type &lt;em&gt;after erasure&lt;/em&gt; kicks in. If you don't adhere to this principle, you &lt;em&gt;will&lt;/em&gt; get into trouble selling something as being of type &lt;code&gt;a&lt;/code&gt; where it actually is of a completely different type &lt;code&gt;b&lt;/code&gt; which can be anything. The compiler can't catch this, and it will result in an unchecked run-time exception most likely terminating your entire program. It's &lt;em&gt;your&lt;/em&gt; responsibility (and it shouldn't be.)&lt;/p&gt;
&lt;p&gt;This is the reason writing &lt;code&gt;T[] toArray()&lt;/code&gt; is not advisable; you have to pass &lt;code&gt;toArray&lt;/code&gt; a &lt;code&gt;T[]&lt;/code&gt; parameter that you create yourself, and that &lt;em&gt;you&lt;/em&gt; are responsible for. The compiler can't help you.&lt;/p&gt;
&lt;p&gt;The solution to this is one of: a) don't mix arrays and generics&lt;sup&gt;&lt;a href="#fn3" class="footnoteRef" id="fnref3"&gt;3&lt;/a&gt;&lt;/sup&gt;, it's bad for your mental health, or b) arcane magic aka reflection. I will leave it to the reader to figure out method b)&lt;sup&gt;&lt;a href="#fn4" class="footnoteRef" id="fnref4"&gt;4&lt;/a&gt;&lt;/sup&gt;, since I'm tired of writing this at the moment. It's a pointless exercise anyway: the reality of the matter is, b) doesn't really exist in case you want to write a well-designed library. Why? Well…&lt;/p&gt;
&lt;p&gt;I find the next example particularly devious (from N&amp;amp;W 2006, pp. 87)&lt;/p&gt;
&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode java"&gt;List&amp;lt;Integer&amp;gt;[] ils =&lt;br /&gt;    (List&amp;lt;Integer&amp;gt;[]) &lt;span class="kw"&gt;new&lt;/span&gt; List[] {Arrays.&lt;span class="fu"&gt;asList&lt;/span&gt;(&lt;span class="dv"&gt;1&lt;/span&gt;)}; &lt;span class="co"&gt;// unchecked&lt;/span&gt;&lt;br /&gt;List&amp;lt;? &lt;span class="kw"&gt;extends&lt;/span&gt; Number&amp;gt; nls = ils;&lt;br /&gt;ils[&lt;span class="dv"&gt;0&lt;/span&gt;] = Arrays.&lt;span class="fu"&gt;asList&lt;/span&gt;(&lt;span class="fl"&gt;1.01&lt;/span&gt;) &lt;span class="co"&gt;// storing a Double in an Integer list!&lt;/span&gt;&lt;br /&gt;&lt;span class="dt"&gt;int&lt;/span&gt; n = ils[&lt;span class="dv"&gt;0&lt;/span&gt;].&lt;span class="fu"&gt;get&lt;/span&gt;(&lt;span class="dv"&gt;0&lt;/span&gt;); &lt;span class="co"&gt;// class cast exception&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You just need to inadvertently pass a reference of your array with a non-reifiable type to some devious method and it might put stuff in there that will make your program crash. And the compiler never saw it coming&lt;sup&gt;&lt;a href="#fn5" class="footnoteRef" id="fnref5"&gt;5&lt;/a&gt;&lt;/sup&gt;. N&amp;amp;W thus call for adherence to the &lt;em&gt;Principle of Indecent Exposure&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Never Publicly expose an array where the components do not have a reifiable type&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;These two principles together mean that you should avoid non-reifible component types in both the source and run-time, which means, you should stick rule a) don't mix arrays and generics. At all. Of course the Java standard library doesn't have to follow &lt;a href="http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#getTypeParameters()"&gt;these&lt;/a&gt; &lt;a href="http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/Method.html#getTypeParameters()"&gt;rules&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The way &lt;code&gt;ArrayList&lt;/code&gt; et al. handle the issue internally is to not externally expose any generic array they do very much internally use, which is why you have to pass &lt;em&gt;your own&lt;/em&gt; &lt;code&gt;T[]&lt;/code&gt; to &lt;code&gt;toArray&lt;/code&gt;. This also entails to &lt;em&gt;tread lightly&lt;/em&gt; whenever using generic arrays internally, as well.&lt;/p&gt;
&lt;h3 id="inner-classes-of-polymorphic-classes-may-not-be-used-as-array-component-types"&gt;&lt;a href="#TOC"&gt;Inner Classes of Polymorphic Classes May Not Be Used as Array Component Types&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Now that was a long subsection title. But it really is that silly:&lt;/p&gt;
&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode java"&gt;&lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="kw"&gt;class&lt;/span&gt; C&amp;lt;E&amp;gt; {&lt;br /&gt;    N[] ns = &lt;span class="kw"&gt;new&lt;/span&gt; N[&lt;span class="dv"&gt;10&lt;/span&gt;]; &lt;span class="co"&gt;// *error*: Generic Array Creation&lt;/span&gt;&lt;br /&gt;    &lt;span class="kw"&gt;private&lt;/span&gt; &lt;span class="kw"&gt;class&lt;/span&gt; N { &lt;span class="dt"&gt;int&lt;/span&gt; data; }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will not compile. If you omit the parameter for &lt;code&gt;C&lt;/code&gt;, it's no problem. If you put &lt;code&gt;N&lt;/code&gt; into its own class file, it's fine again. I'm not exactly sure why that is, since the type parameter isn't even used, and &lt;code&gt;N&lt;/code&gt; should be a reifiable type, since it's not parametric.&lt;/p&gt;
&lt;h3 id="no-polymorphism-for-exceptions"&gt;&lt;a href="#TOC"&gt;No Polymorphism for Exceptions&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Type erasure also leads to the awkward consequence that anything deriving from &lt;code&gt;Throwable&lt;/code&gt; &lt;em&gt;cannot&lt;/em&gt; be a generic type, since the JVM couldn't distinguish different instantiations of that type, but it needs to in the case of exception handling.&lt;/p&gt;
&lt;h3 id="static-fields-of-generic-types"&gt;&lt;a href="#TOC"&gt;Static Fields of Generic Types&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;It also makes it impossible to have any &lt;code&gt;static&lt;/code&gt; fields of a class have the same type as a type parameter:&lt;/p&gt;
&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode java"&gt;&lt;span class="kw"&gt;public&lt;/span&gt; &lt;span class="kw"&gt;class&lt;/span&gt; C&amp;lt;A&amp;gt; {&lt;br /&gt;    &lt;span class="dt"&gt;static&lt;/span&gt; A a;&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In order for this to work, the runtime would have to keep track of a value for &lt;code&gt;a&lt;/code&gt; for each instantiation of type &lt;code&gt;A&lt;/code&gt;, which is not possible, since it doesn't even know that &lt;code&gt;A&lt;/code&gt; exists! It only ever knows about the &lt;em&gt;raw type&lt;/em&gt; &lt;code&gt;C&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="downcasting-towards-a-polymorphic-type-is-always-unsafe"&gt;&lt;a href="#TOC"&gt;Downcasting Towards a Polymorphic Type is Always Unsafe&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;And it can result in run-time failures with a &lt;code&gt;ClassCastException&lt;/code&gt; that are far removed from the actual origin of the erroneous code. Consider the following snippet, loosely based on &lt;a href="http://www.angelikalanger.com/GenericsFAQ/FAQSections/ParameterizedTypes.html#Can%20I%20cast%20to%20a%20parameterized%20type?"&gt;FAQ005&lt;/a&gt;:&lt;/p&gt;
&lt;pre class="sourceCode"&gt;&lt;code class="sourceCode java"&gt;&lt;span class="dt"&gt;void&lt;/span&gt; &lt;span class="fu"&gt;f&lt;/span&gt;() {&lt;br /&gt;    List&amp;lt;Date&amp;gt; dl   = &lt;span class="kw"&gt;new&lt;/span&gt; ArrayList&amp;lt;Date&amp;gt;();&lt;br /&gt;    List&amp;lt;String&amp;gt; sl = (List&amp;lt;String&amp;gt;) ((Object) dl); &lt;span class="co"&gt;// unchecked warning&lt;/span&gt;&lt;br /&gt;    &lt;span class="fu"&gt;g&lt;/span&gt;(sl);&lt;br /&gt;}&lt;br /&gt;&lt;span class="dt"&gt;void&lt;/span&gt; &lt;span class="fu"&gt;g&lt;/span&gt;(List&amp;lt;String&amp;gt; l) { String s = l.&lt;span class="fu"&gt;get&lt;/span&gt;(&lt;span class="dv"&gt;0&lt;/span&gt;); } &lt;span class="co"&gt;// ClassCastException&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above code will always issue a warning, and we see why: the compiler cannot generally ensure that the code won't lead to a runtime error. The problem is: there are scenarios were doing this is actually useful, and legal: given &lt;code&gt;Token&lt;/code&gt;, a subtype of &lt;code&gt;Annotation&lt;/code&gt;, casting a &lt;code&gt;List&amp;lt;Annotation&amp;gt;&lt;/code&gt; to a &lt;code&gt;List&amp;lt;Token&amp;gt;&lt;/code&gt;, for example, which I have had to do in the context of UIMA very often will always result in a warning. The compiler cannot reason about whether the warning is justified or not.&lt;/p&gt;
&lt;p&gt;Don't just ignore those unchecked warnings, it can end badly, and it will confuse you.&lt;/p&gt;
&lt;h1 id="theoretically"&gt;&lt;a href="#TOC"&gt;Theoretically…&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;I would recommend to anybody further interested in exploring the theory behind (and above!) Java's Generics, to have a look at &lt;a href="http://homepages.inf.ed.ac.uk/wadler/topics/gj.html"&gt;Wadler's page&lt;/a&gt; on them. A lot of very interesting papers are linked there, as well as the authoritative O'Reilly book on &lt;a href="http://naftalin.info/maurice/professional/javaGenericsAndCollectionsReviews.html"&gt;Java Generics&lt;/a&gt;.&lt;/p&gt;
&lt;div class="footnotes"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn1"&gt;&lt;p&gt;Well, that's not exactly true. Technically, the array type does count for a polymorphic type &lt;a href="#fnref1" class="footnoteBackLink"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id="fn2"&gt;&lt;p&gt;Curiously, wildcards are reified, so &lt;code&gt;List&amp;lt;?&amp;gt;&lt;/code&gt; &lt;em&gt;has&lt;/em&gt; full run-time type information, but &lt;code&gt;List&amp;lt;? extends Object&amp;gt;&lt;/code&gt;, which is equivalent, does not. &lt;a href="#fnref2" class="footnoteBackLink"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id="fn3"&gt;&lt;p&gt;Did I mention that &lt;em&gt;varargs&lt;/em&gt; are actually just arrays? Yes, don't mix generics and varargs either; same restrictions apply. Some methods in the standard library use varargs, among them &lt;code&gt;Arrays.asList&lt;/code&gt;. And this &lt;em&gt;does&lt;/em&gt; mean that creating a &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; or &lt;code&gt;List&amp;lt;List&amp;lt;Integer&amp;gt;&amp;gt;&lt;/code&gt; with said method shouldn't be attempted… &lt;a href="#fnref3" class="footnoteBackLink"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id="fn4"&gt;&lt;p&gt;Hint, it involves &lt;code&gt;Arrays.asList&lt;/code&gt; and can't avoid unchecked casts either. &lt;a href="#fnref4" class="footnoteBackLink"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id="fn5"&gt;&lt;p&gt;Well, it did issue a warning alright, but as we know, there is no way around that in case you're dealing with arrays anyway. &lt;a href="#fnref5" class="footnoteBackLink"&gt;↩&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3460761117713509776-9180238172199974457?l=a-dimit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-dimit.blogspot.com/feeds/9180238172199974457/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3460761117713509776&amp;postID=9180238172199974457' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/9180238172199974457'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/9180238172199974457'/><link rel='alternate' type='text/html' href='http://a-dimit.blogspot.com/2011/11/re-highbrow-java-or-java-generics-and.html' title='Re: Highbrow Java; Or: Java Generics and Why I Still Hate Them'/><author><name>adimit</name><uri>http://www.blogger.com/profile/04917371723395784281</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_h4s_XF6s_5o/SIo9zlI9jjI/AAAAAAAAAAM/pP0yRe0g0SI/S220/dsc00206square.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3460761117713509776.post-8532251315562692794</id><published>2011-02-18T16:12:00.000-08:00</published><updated>2011-06-06T15:33:08.536-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cooking'/><title type='text'>Vegetarian Lasagna with Black Beans</title><content type='html'>&lt;!--a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-M_BtYFpS3RY/TV8rEnQbpRI/AAAAAAAAAeE/2ASmIm9e29U/s1600/small_DSCN4381.JPG"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://3.bp.blogspot.com/-M_BtYFpS3RY/TV8rEnQbpRI/AAAAAAAAAeE/2ASmIm9e29U/s320/small_DSCN4381.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5575222221965337874" /&gt;&lt;/a&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-TlEWUCnJ58Q/TV8q02Eb5uI/AAAAAAAAAd8/yh3_dfa78Jo/s1600/small_DSCN4382.JPG"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 300px; height: 400px;" src="http://4.bp.blogspot.com/-TlEWUCnJ58Q/TV8q02Eb5uI/AAAAAAAAAd8/yh3_dfa78Jo/s400/small_DSCN4382.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5575221951063647970" /&gt;&lt;/a--&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-E0fUXSqPRjk/TV8qGeRn9GI/AAAAAAAAAd0/r9mrWiCPqro/s1600/small_DSCN4387.JPG"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://2.bp.blogspot.com/-E0fUXSqPRjk/TV8qGeRn9GI/AAAAAAAAAd0/r9mrWiCPqro/s400/small_DSCN4387.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5575221154402530402" /&gt;&lt;/a&gt;

&lt;style type="text/css"&gt;
 td.dosomething {
 border: 1px solid;
 border-left: none;
 text-align: center;
 font-size: 8pt; }

 td.layer {
 border-bottom:1px dotted;
 text-align: center;
 font-size: 8pt; }

 td.ingredient {
 font-size: 8pt;
 border-top: 1px dotted;
 }
&lt;/style&gt;
&lt;p&gt;
 Nothing tastes quite as good as lasagna Bolognese, one of the &lt;i&gt;very&lt;/i&gt;
 few meat dishes I used to eat when I actually did eat a little meat. Since
 I'm thoroughly grossed out by any form of allegedly 'edible' animal now,
 I've been looking for a lasagna that could compare to 'the real deal.'
 Recently, I found a &lt;a href="http://www.epicurious.com/recipes/food/views/Black-Bean-Lasagna-Kinstlinger-Bruhn-10253"&gt;
  delectable recipe
 &lt;/a&gt; over at epicurious.&lt;/p&gt;
&lt;p&gt;
 The lasagna requires quite a bit of effort. Due to the different cheeses in it, the cost is also relatively high. I tried to make it both as easy as possible, and as cheap as possible.&lt;/p&gt;
&lt;h3&gt;Ingredients&lt;/h3&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/--bWpKvSx7_g/Te1LWcajQ6I/AAAAAAAAAfE/EamK4XgK6W4/s1600/DSCN4343.JPG"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://4.bp.blogspot.com/--bWpKvSx7_g/Te1LWcajQ6I/AAAAAAAAAfE/EamK4XgK6W4/s320/DSCN4343.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5615227159357637538" /&gt;&lt;/a&gt;
&lt;ul&gt;
 &lt;li&gt;200g &lt;a href="http://en.wikipedia.org/wiki/Black_turtle_bean"&gt;black beans&lt;/a&gt; (usually available in any Asia shop.)&lt;/li&gt;
 &lt;li&gt;250g Ricotta (Italian cottage cheese. You can substitute it with pretty much any kind of cottage cheese that doesn't have too strong a taste.)&lt;/li&gt;
 &lt;li&gt;3 balls of mozzarella, around 250 to 300g; (it isn't worth it to buy good buffalo Mozzarella, but don't buy the cheapest stuff either.)&lt;/li&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/--E4dlQ1BRwM/Te1FrguG4OI/AAAAAAAAAe8/PwLhkAoIVgQ/s1600/DSCN4332.JPG"&gt;&lt;img style="float:right; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 240px; height: 320px;" src="http://4.bp.blogspot.com/--E4dlQ1BRwM/Te1FrguG4OI/AAAAAAAAAe8/PwLhkAoIVgQ/s320/DSCN4332.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5615220924220891362" /&gt;&lt;/a&gt;
 &lt;li&gt;Parmesan (or, if you want to save money, &lt;a href="http://en.wikipedia.org/wiki/Grana_Padano"&gt;Grana Padano&lt;/a&gt; is equally good.)&lt;/li&gt;
 &lt;li&gt;1 egg&lt;/li&gt;
 &lt;li&gt;1 onion, some 3 cloves of garlic&lt;/li&gt;
 &lt;li&gt;150g of black olives&lt;/li&gt;
 &lt;li&gt;olive oil&lt;/li&gt;
 &lt;li&gt;some 2-2½ cans of tomatoes in various aggregate states: puréed, skinned and diced, or just cut up.&lt;/li&gt;
 &lt;li&gt;2-3 tsp. ground dried cilantro&lt;/li&gt;
 &lt;li&gt;basil&lt;/li&gt;
 &lt;li&gt;a bay leaf&lt;/li&gt;
 &lt;li&gt;lasagna noodles&lt;/li&gt;
 &lt;li&gt;jalapeños to taste&lt;/li&gt;
 &lt;li&gt;oregano, thyme, ground dried basil&lt;/li&gt;
 &lt;li&gt;salt, pepper, asafoetida, chili powder, sweet pepper powder, dried pomegranate powder&lt;/li&gt;
&lt;/ul&gt;
&lt;table cellspacing=0&gt;
 &lt;tr&gt;
  &lt;td class="ingredient"&gt; &amp;nbsp; &lt;/td&gt;
  &lt;td colspan=6 class="dosomething"&gt; preheat the oven to 180°C &lt;/td&gt;
  &lt;td rowspan=22 class="dosomething"&gt;
   layer:&lt;br/&gt;
   (top to bottom)
   &lt;table cellspacing=0&gt;
    &lt;tr&gt;&lt;td class="layer"&gt;parmesan&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td class="layer"&gt;1/3 béchamel&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td class="layer"&gt;noodles&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td class="layer"&gt;parmesan&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td class="layer"&gt;1/3 mozzarella&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td class="layer"&gt;1/3 tomato sauce&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td class="layer"&gt;1/3 béchamel&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td class="layer"&gt;noodles&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td class="layer"&gt;parmesan&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td class="layer"&gt;1/3 mozzarella&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td class="layer"&gt;1/3 tomato sauce&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td class="layer"&gt;bean cream&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td class="layer"&gt;noodles&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td class="layer"&gt;parmesan&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td class="layer"&gt;1/3 mozzarella&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td class="layer"&gt;1/3 tomato sauce&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td class="layer"&gt;1/3 béchamel&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td class="layer"&gt;noodles&lt;/td&gt;&lt;/tr&gt;
   &lt;/table&gt;
   &lt;br/&gt;
   bake for&lt;br/&gt;30-35min
  &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
  &lt;td class="ingredient"&gt; &amp;nbsp; &lt;/td&gt;
  &lt;td colspan=6 class="dosomething"&gt; oil in a lasagna dish &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
  &lt;td class="ingredient"&gt;
   250 g ricotta
  &lt;/td&gt;
  &lt;td class="dosomething" colspan=4 rowspan=4&gt;
   mix
  &lt;/td&gt;
  &lt;td rowspan=4 colspan=1 class="dosomething"&gt;
   whisk&lt;br/&gt;until creamy
  &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
  &lt;td class="ingredient"&gt;
   1 egg
  &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
  &lt;td class="ingredient"&gt;
   25g grated&lt;br/&gt;Parmesan
  &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
  &lt;td class="ingredient"&gt;
   2-3 tsp.&lt;br/&gt;cilantro&lt;br/&gt;powder
  &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
  &lt;td class="ingredient" colspan=5&gt;
   2 tbsp.&lt;br/&gt;olive oil
  &lt;/td&gt;
  &lt;td class="dosomething" rowspan=2&gt;
   mix and blend&lt;br/&gt;until creamy
  &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
  &lt;td class="ingredient"&gt;
   250g&lt;br/&gt;black beans
  &lt;/td&gt;
  &lt;td class="dosomething" colspan=3&gt;
   cook
  &lt;/td&gt;
  &lt;td rowspan=1 class="dosomething" style="border-bottom: 1px dotted;"&gt;
   separate 1 cup
  &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
  &lt;td colspan=4&gt;
   &amp;nbsp;
  &lt;/td&gt;
  &lt;td class="dosomething" style="border: none"&gt;
   rest of beans
  &lt;/td&gt;
  &lt;td rowspan=11 class="dosomething"&gt;
   fold,&lt;br/&gt;cook until&lt;br/&gt;
   oil separates
  &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
  &lt;td class="ingredient"&gt;
   onion
  &lt;/td&gt;
  &lt;td class="dosomething"&gt;
   dice
  &lt;/td&gt;
  &lt;td rowspan=6 class="dosomething"&gt;
   mix
  &lt;/td&gt;
  &lt;td rowspan=7 class="dosomething"&gt;
   fry until onions&lt;br/&gt;are soft
  &lt;/td&gt;
  &lt;td rowspan=8 class="dosomething"&gt;
   mix, fry 2-3 min
  &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt; &lt;td class="ingredient"&gt; salt, pepper &lt;/td&gt; &lt;/tr&gt;
 &lt;tr&gt; &lt;td class="ingredient"&gt; bay leaf &lt;/td&gt; &lt;/tr&gt;
 &lt;tr&gt; &lt;td class="ingredient"&gt; spices &lt;/td&gt; &lt;/tr&gt;
 &lt;tr&gt; &lt;td class="ingredient"&gt; chili powder&lt;br/&gt;to taste &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
  &lt;td class="ingredient"&gt; 3-4 cloves&lt;br/&gt;of garlic &lt;/td&gt;
  &lt;td class="dosomething"&gt; press &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
  &lt;td class="ingredient"&gt; 2 spoons&lt;br/&gt;olive oil &lt;/td&gt;
  &lt;td class="dosomething"&gt; heat in frying pan &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
  &lt;td class="ingredient"&gt; jalapeños&lt;br/&gt;(to taste) &lt;/td&gt;
  &lt;td class="dosomething"&gt; remove stems&lt;br/&gt;and seeds, dice &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt; &lt;td class="ingredient"&gt; 150g olives &lt;/td&gt;
  &lt;td class="dosomething"&gt; remove kernels&lt;br/&gt;if necessary &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt; &lt;td class="ingredient"&gt; 2 cans of&lt;br/&gt;assorted&lt;br/&gt;tomatoes &lt;/td&gt;
  &lt;td class="dosomething"&gt; dice&lt;br/&gt; purée &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt; &lt;td class="ingredient"&gt; 3 balls of&lt;br/&gt;mozzarella &lt;/td&gt; &lt;/tr&gt;
 &lt;tr&gt; &lt;td class="ingredient"&gt; grated&lt;br/&gt;Parmesan &lt;/td&gt; &lt;/tr&gt;
 &lt;tr&gt; &lt;td class="ingredient"&gt; lasagna&lt;br/&gt;noodles &lt;/td&gt; &lt;/tr&gt;
&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3460761117713509776-8532251315562692794?l=a-dimit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-dimit.blogspot.com/feeds/8532251315562692794/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3460761117713509776&amp;postID=8532251315562692794' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/8532251315562692794'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/8532251315562692794'/><link rel='alternate' type='text/html' href='http://a-dimit.blogspot.com/2011/02/vegetarian-lasagna-with-black-beans.html' title='Vegetarian Lasagna with Black Beans'/><author><name>adimit</name><uri>http://www.blogger.com/profile/04917371723395784281</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_h4s_XF6s_5o/SIo9zlI9jjI/AAAAAAAAAAM/pP0yRe0g0SI/S220/dsc00206square.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-E0fUXSqPRjk/TV8qGeRn9GI/AAAAAAAAAd0/r9mrWiCPqro/s72-c/small_DSCN4387.JPG' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3460761117713509776.post-3290803863890674755</id><published>2010-12-30T10:51:00.000-08:00</published><updated>2010-12-30T12:02:51.224-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='zsh'/><title type='text'>The Perfect Prompt</title><content type='html'>&lt;p&gt;Long ago I switched to &lt;a href="http://www.zsh.org"&gt;zsh&lt;/a&gt; from &lt;a href="http://www.gnu.org/software/bash/"&gt;bash&lt;/a&gt; for my hacking needs. I think at the time I just needed a new toy. However, over the years, zsh has proven to be a very good shell, with excellent flexibility, a healthy "Do what I Mean" attitude, and overall much more powerful globbing, auto-complete, keybinding and scripting capabilities than bash.&lt;/p&gt;

Part of the usual appeal of zsh are the &lt;a href="https://github.com/robbyrussell/oh-my-zsh/wiki/themes"&gt;ridiculously&lt;/a&gt; &lt;a href="http://zshwiki.org/home/config/prompt"&gt;fancy prompts&lt;/a&gt; you can make it display. I was never a fan of those. My prompts have to be &lt;em&gt;simple&lt;/em&gt;, since I'm staring at them all the time. Don't show me anything I don't &lt;em&gt;need,&lt;/em&gt; to know! I find it hard to concentrate on something anyway, without my shell telling me how many emails I have left in my Inbox.

So I created the perfect minimalist prompt that does exactly what I need it to do:
&lt;ul&gt;
&lt;li&gt;Display whether I'm root or not&lt;/li&gt;
&lt;li&gt;How many jobs are there running in the background (if any?)&lt;/li&gt;
&lt;li&gt;Did the last command finish successfully, or did the damn thing just die silently?&lt;/li&gt;
&lt;li&gt;Since I'm using vi keybindings, am I in insert mode or in normal mode?&lt;/li&gt;
&lt;li&gt;What machine is this shell on?&lt;/li&gt;
&lt;li&gt;What directory is this shell in?&lt;/li&gt;
&lt;/ul&gt;

Almost all of these have defaults I don't expect to be mentioned. Usually, I have nothing running in the background, I'm on my local machine, and the last command finished successfully. At that point, I don't need to be reminded that &lt;em&gt;all is well&lt;/em&gt;. Hide it!

So here's a picture:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_h4s_XF6s_5o/TRzi7chPlQI/AAAAAAAAAdA/JySXlJUVYMM/s1600/shell.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 161px;" src="http://3.bp.blogspot.com/_h4s_XF6s_5o/TRzi7chPlQI/AAAAAAAAAdA/JySXlJUVYMM/s400/shell.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5556565551164134658" /&gt;&lt;/a&gt;

Let's go over the features one-by one. I don't like directories to be on the left-hand side prompt, since that'll move your prompt all the way to the right when you're in a deeply nested directory. So they're on the right, where they don't bother me, but I can still look them up easily (the blue string on the right will disappear if the cursor gets too close.)

&lt;a href="http://zsh.sourceforge.net/Guide/zshguide02.html#l20"&gt;Named directories&lt;/a&gt; are zsh's handy way to provide directory shortnames. Instead of going to the lengthy &lt;tt&gt;~/Documents/src&lt;/tt&gt; I can just go to &lt;tt&gt;~src&lt;/tt&gt;. I can define similar hashes for projects I'm working on, say &lt;tt&gt;~myproject&lt;/tt&gt; for &lt;tt&gt;~/Documents/src/java/myproject&lt;/tt&gt;.

Whenever there's a background job (like &lt;tt&gt;sleep&lt;/tt&gt; in this example) I get a yellow number before my prompt mark. This is a counter for the background jobs. It disappears if there aren't any.

The shell checks the variable &lt;tt&gt;SSH_CLIENT&lt;/tt&gt; to see if it's on a remote or local machine. On a local machine, nothing happens, but on a remote machine (i.e. a machine I'm accessing via SSH — the client always sets &lt;tt&gt;SSH_CLIENT&lt;/tt&gt; when connecting) it displays the leftmost part of the machine's subdomain. I don't need to know I'm on a local machine when I'm sitting in front of it! But I do want to know if a shell &lt;em&gt;doesn't&lt;/em&gt; belong to the machine I'm currently working on.

Similarly to the background job display, I don't want to always know every program's return code. I'm interested in the ones that failed. If a program returns non-zero, I see a big fat red number signalizing error.

Finally I like to know which mode I'm in. The blue &lt;tt&gt;&amp;gt;&lt;/tt&gt; indicates insert mode, and a yellow &lt;tt&gt;∙&lt;/tt&gt; indicates normal mode. Like this: &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_h4s_XF6s_5o/TRzd1obD1yI/AAAAAAAAAcw/XribthRVVc4/s1600/shell-vim.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 45px; height: 37px;" src="http://4.bp.blogspot.com/_h4s_XF6s_5o/TRzd1obD1yI/AAAAAAAAAcw/XribthRVVc4/s320/shell-vim.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5556559953722070818" /&gt;&lt;/a&gt;

There's more to the configuration than just what I've mentioned here, but this is already longer than I expected it to be! So I'll link you to my &lt;a href="http://github.com/adimit/config/blob/master/zshrc"&gt;&lt;tt&gt;.zshrc&lt;/tt&gt;&lt;/a&gt;. Maybe someone will find something useful there :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3460761117713509776-3290803863890674755?l=a-dimit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-dimit.blogspot.com/feeds/3290803863890674755/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3460761117713509776&amp;postID=3290803863890674755' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/3290803863890674755'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/3290803863890674755'/><link rel='alternate' type='text/html' href='http://a-dimit.blogspot.com/2010/12/perfect-prompt.html' title='The Perfect Prompt'/><author><name>adimit</name><uri>http://www.blogger.com/profile/04917371723395784281</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_h4s_XF6s_5o/SIo9zlI9jjI/AAAAAAAAAAM/pP0yRe0g0SI/S220/dsc00206square.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_h4s_XF6s_5o/TRzi7chPlQI/AAAAAAAAAdA/JySXlJUVYMM/s72-c/shell.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3460761117713509776.post-9006999908690731401</id><published>2010-09-12T08:58:00.000-07:00</published><updated>2010-09-12T09:09:32.446-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lectures'/><category scheme='http://www.blogger.com/atom/ns#' term='category theory'/><title type='text'>The Catsters YouTube Channel: Lectures on Category Theory</title><content type='html'>&lt;p&gt;Just quickly posting to mention my finding a neat little YouTube channel with lectures on Category Theory: &lt;a href="http://www.youtube.com/user/TheCatsters#p/u/3/4QgjKUzyrhM"&gt;The Catsters&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The folks on the channel giving the lectures are enthusiastic nerds (what else?) and their lectures are actually really well done. One can even read what they scribble on the board. Usually.&lt;/p&gt;
&lt;p&gt;The quality of the videos is pretty poor though, and the buzzing of the sound and poor balance of voice and ambient noises, as well as the amplification problems (sometimes, especially on the Monads video, the voice just blows out the mic amp's range) make it a little hard to follow the lectures. It won't, of course, prevent a real enthusiast from watching them. The explanations' quality is good (as far as I could tell.)&lt;/p&gt;
&lt;p&gt;I increasingly find the lecture format of Internet videos a little nicer than your average run-of-the-mill lecture, where you sit with some 100 folks in one room. Granted, my own course of studies usually put me into rooms of no more than 20 people, but I still find it quite useful to be able to view lectures &lt;em&gt;on demand&lt;/em&gt;. There's something to be said for both formats.
&lt;/p&gt;
&lt;p&gt;Go check it out! And I'll try to find some original content to post again :-P&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3460761117713509776-9006999908690731401?l=a-dimit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-dimit.blogspot.com/feeds/9006999908690731401/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3460761117713509776&amp;postID=9006999908690731401' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/9006999908690731401'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/9006999908690731401'/><link rel='alternate' type='text/html' href='http://a-dimit.blogspot.com/2010/09/catsters-youtube-channel-lectures-on.html' title='The Catsters YouTube Channel: Lectures on Category Theory'/><author><name>adimit</name><uri>http://www.blogger.com/profile/04917371723395784281</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_h4s_XF6s_5o/SIo9zlI9jjI/AAAAAAAAAAM/pP0yRe0g0SI/S220/dsc00206square.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3460761117713509776.post-8369627201939773361</id><published>2010-07-06T06:44:00.000-07:00</published><updated>2010-07-06T07:02:50.681-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Generalised Algebraic Data Types in Haskell</title><content type='html'>&lt;p&gt;&lt;i&gt;I will just ignore the fact that I haven't posted anything here in more than 1.5 years. It's still my blog :-) Maybe there's gonna be a follow-up on how/what I was doing, but right now, I'll skip right over it.&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;
Heinrich Apfelmus has posted an absolutely &lt;em&gt;enlightening&lt;/em&gt; &lt;a href="http://www.vimeo.com/12208838"&gt;video explanation&lt;/a&gt; of Haskell's generalised algebraic data type system on &lt;a href="http://apfelmus.nfshost.com/"&gt;his blog&lt;/a&gt;. It gives a newcomer quite a nice perspective on &lt;em&gt;why&lt;/em&gt; GADTs are so powerful, and how one can use them. There's a couple of caveats: first, if you're &lt;em&gt;totally&lt;/em&gt; new to &lt;a href="http://www.haskell.org"&gt;Haskell&lt;/a&gt; this won't make too much sense to you. You'll have to understand at least &lt;a href="http://en.wikibooks.org/wiki/Haskell/Type_declarations"&gt;data type declarations, type constructors&lt;/a&gt; and maybe the &lt;a href="http://www.haskell.org/haskellwiki/Infix_operator"&gt;infix function notation&lt;/a&gt; (and the fact that every type constructor is a function!)
&lt;/p&gt;
&lt;p&gt;
The example he chose (algebraic expressions) is quite nice &amp; simple, but it's also a toy example. It would be nice to see GADTs used in an example that is still intuitive but maybe a little more... engaging. I'm thinking of 2-sorted Typed logic, and/or typed lambda-calculus with embedded FOPL. I'm currently implementing something along those lines and hope to release the code soon :-)&lt;/p&gt;
&lt;p&gt;EDIT: I just discovered a &lt;a href="http://apfelmus.nfshost.com/blog/2010/07/02-fixed-points-video.html"&gt;newer post&lt;/a&gt; of his about the fixed point combinator; and it even taught me some new and interesting things! I really like the style of his videos... and his cute accent ^^.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3460761117713509776-8369627201939773361?l=a-dimit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-dimit.blogspot.com/feeds/8369627201939773361/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3460761117713509776&amp;postID=8369627201939773361' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/8369627201939773361'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/8369627201939773361'/><link rel='alternate' type='text/html' href='http://a-dimit.blogspot.com/2010/07/generalised-algebraic-data-types-in.html' title='Generalised Algebraic Data Types in Haskell'/><author><name>adimit</name><uri>http://www.blogger.com/profile/04917371723395784281</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_h4s_XF6s_5o/SIo9zlI9jjI/AAAAAAAAAAM/pP0yRe0g0SI/S220/dsc00206square.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3460761117713509776.post-3298668279923425666</id><published>2008-12-04T15:44:00.000-08:00</published><updated>2008-12-04T22:00:24.236-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='politics'/><title type='text'>The Good the Bad and the Funny</title><content type='html'>&lt;p&gt;Credit where credit is due. Vladimir Putin may be a despisable person, but, damn, he's so Russian, he sweats Vodka:&lt;/p&gt;
&lt;blockquote&gt;
French media had quoted Putin as saying in a heated conversation with French President Nicolas Sarkozy in Moscow on August 12 that Saakashvili should be "hung by his balls" for starting the war which was roundly condemned by the West.&lt;br/&gt;&lt;i&gt;&lt;a href="http://www.reuters.com/article/worldNews/idUSTRE4B352V20081204"&gt;Source: Reuters&lt;/a&gt;&lt;/i&gt;
&lt;/blockquote&gt;
&lt;p&gt;The Russian soul is an intrepid one. They like their unbashed, dauntlessly honest attitude, they sell it as a feature, where some might consider it outright rude. Can't say I blame them for that. Hearing one of the most "important" persons on the world talking like that does find favor with me. That's probably my Slavic side, or maybe even the faint Mongolic or Thrakian genes, so I don't expect you westerners to understand that. It's great, because it's stupid, but it's manly, which is even more stupid, and that in turn, makes it
  great again.
&lt;/p&gt;
&lt;p&gt;
  He goes on:
  &lt;blockquote&gt;
"Seriously speaking, both me and you know about tragic events in another region of the world, in Iraq, invaded by American troops due to a concocted pretext of searching for weapons of mass destruction," said Putin.
&lt;br/&gt;&lt;br/&gt;
"They found no weapons, but hanged the head of state, albeit on other charges ... " said Putin, referring to the 2006 execution of former Iraqi President Saddam Hussein.
&lt;br/&gt;&lt;br/&gt;
"I believe it is up to Georgia's people to decide what kind of responsibility must be borne by those politicians who led to these harshest and tragic consequences," he said.&lt;br/&gt;
&lt;i&gt;&lt;a href="http://www.reuters.com/article/worldNews/idUSTRE4B352V20081204"&gt;ibid&lt;/a&gt;&lt;/i&gt;
&lt;/blockquote&gt;
&lt;p&gt;No matter what you may think about Mr. Putin, it does take quite some self-confidence to accuse the Americans so openly of wrongdoing. Demanding to hang the Georgian president by his balls for attacking another country under "false" premises is indirectly asking to do the same thing to George. Bush. Jr. Not that I would mind.
&lt;/p&gt;
&lt;p&gt;
  And I'd like to take that as an opportunity to remind everybody that, despite these brutish words, Putin is a man of extreme subtlety, and no doubt even those words were duly prepared and carefully placed (…or maybe I overestimate him?) I still think he's one of the most dangerous people on this planet (known to me, anyway) and I'm watching the current political "developments" in Russia with great unease.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3460761117713509776-3298668279923425666?l=a-dimit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-dimit.blogspot.com/feeds/3298668279923425666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3460761117713509776&amp;postID=3298668279923425666' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/3298668279923425666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/3298668279923425666'/><link rel='alternate' type='text/html' href='http://a-dimit.blogspot.com/2008/12/good-bad-and-funny.html' title='The Good the Bad and the Funny'/><author><name>adimit</name><uri>http://www.blogger.com/profile/04917371723395784281</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_h4s_XF6s_5o/SIo9zlI9jjI/AAAAAAAAAAM/pP0yRe0g0SI/S220/dsc00206square.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3460761117713509776.post-6102735813233733402</id><published>2008-11-20T16:22:00.000-08:00</published><updated>2008-11-26T03:06:48.077-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='philosophy'/><title type='text'>Tough Questions</title><content type='html'>&lt;p&gt;Apparently, it's been "Philosopher Day" recently. Not that I noticed. BBC took it as an excuse to feature an &lt;a href="http://news.bbc.co.uk/2/hi/uk_news/magazine/7739493.stm"&gt;article on "Four Philosophical Questions that will Make Your Brain Hurt."&lt;/a&gt; So far, my brain feels fine, and I'm only slightly amused. Let's consider them in turn.

&lt;h4&gt;Should we kill healthy people for their organs?&lt;/h4&gt; &lt;p&gt;I first misread that as &lt;i&gt;"Should we kill &lt;b&gt;wealthy&lt;/b&gt; people for their organs"&lt;/i&gt; and thought to myself: "My, what a good idea! that's no hard question at all." Unfortunately, on second glance, the question turns out to be the same old utilitarian vs. moralistic clash. And mind you, that's not strict philosophy, it's more like ethics.&lt;/p&gt;

&lt;p&gt;You cannot justify utilitarian reasoning with moral doctrine. But you can doubt the utilitarian thought on other grounds: Since there is no way of predicting the future, utilitarian maximes will always be based on assumptions and guesswork. See the world as a system of interdependent states. Killing someone is quite an action on this system, and can have unpredictable consequences. Letting someone die of natural cause might be seen as part of the system, and will have the usual consequences.
&lt;/p&gt;
&lt;p&gt;Trying to answer this question without having a look at the big picture isn't sensible, but that's what they're  doing here. And that's stupid. The big picture doesn't care about one person or five. WWII eradicated the same amount in Millions, per year. Humanity recovered. The human race is such that it can compensate for the loss of individuals. The current human (Western) society is such that it cannot (easily) compensate for the (open) loss of individual values. On the other hand, doing such things implicitly, is perfectly valid, even in the most "civilized" of nations. Or when did you last flush your fecal matter down the toilet, while children in other parts of the world die because of the lack of (clean) water.
&lt;/p&gt;
&lt;h4&gt;Are you the same person who started reading this article?&lt;/h4&gt; Ugh. Not again that ol' "Who am I?" question. Heraklit (sortof) says: "You cannot go into the same river twice, since the river always changes." The question is the definition of "same." Ergo, the definition of individuality. If you like to think of time as nothing more than another dimension, you'll just say, it's me, over there. A state change does not indicate a change in kind. Or does it? Anyway, this doesn't make my brain hurt, it merely provides a nice distraction best discussed with friends over some pints of beer.&lt;/p&gt;
&lt;h4&gt;Is that really a computer screen in front of you?&lt;/h4&gt;
Solipsism. How boring. For all I know, yes it is. It is safe to assume it is. If I'm mistaken, so be it. Conventionalism is the keyword here. Yes, senses can be fooled, but, what isn't perceived isn't there. What isn't perceived by me, isn't there for me. Since I call it a computer screen, and you call it a computer screen, it is a computer screen. If it turns out to be a sentient life form, disguising itself as something useful, I'd probably still call it a computer screen, at least until I find a better name &lt;i&gt;and&lt;/i&gt; use for it.
&lt;h4&gt;Did you really choose to read this article?&lt;/h4&gt;
Quoth the article:
&lt;blockquote&gt;Suppose that Fred existed shortly after the Big Bang. He had unlimited intelligence and memory, and knew all the scientific laws governing the universe and all the properties of every particle that then existed. Thus equipped, billions of years ago, he could have worked out that, eventually, planet Earth would come to exist, that you would too, and that right now you would be reading this article.&lt;/blockquote&gt;
&lt;p&gt;Ever heard of quantum physics? This scenario is as absurd as it is impossible, because there is no way of knowing all state in the universe. Even if you did, there is no way of predicting how that state would evolve.  &lt;br/&gt;But I like the idea of calling god 'Fred.'&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3460761117713509776-6102735813233733402?l=a-dimit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-dimit.blogspot.com/feeds/6102735813233733402/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3460761117713509776&amp;postID=6102735813233733402' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/6102735813233733402'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/6102735813233733402'/><link rel='alternate' type='text/html' href='http://a-dimit.blogspot.com/2008/11/tough-questions.html' title='Tough Questions'/><author><name>adimit</name><uri>http://www.blogger.com/profile/04917371723395784281</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_h4s_XF6s_5o/SIo9zlI9jjI/AAAAAAAAAAM/pP0yRe0g0SI/S220/dsc00206square.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3460761117713509776.post-7906288186540477217</id><published>2008-11-20T15:17:00.000-08:00</published><updated>2008-11-26T03:07:12.289-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tips'/><category scheme='http://www.blogger.com/atom/ns#' term='LaTeX'/><title type='text'>TeX on Blogger</title><content type='html'>&lt;p&gt;
It's done! After about an hour of desperately trying to set it up using various
approaches, I finally came across &lt;a
    href="http://yourequations.com"&gt;Yourequations.com&lt;/a&gt;. Sounds very Web2.0,
but it works!
&lt;pre lang="eq.latex"&gt;\mathbf{Proof.\mbox{ }}\mathrm{ By\mbox{ }example:} \sum_{n\in\mathbm{N}} p. \mbox{ }\Box&lt;/pre&gt;
Now that was one one-liner! Two problems remain: in-line (in-text) LaTeX symbols (this script requires the use of &amp;lt;pre&amp;gt; tags, which, by definition, open a new line) and the fact that I have to first &lt;i&gt;publish&lt;/i&gt; the post, before I see the results.
&lt;p&gt;
I had hoped to take Blogspot's lacking LaTeX support as an excuse to roll out my own server and CMS. Meh, now I'll have to find another reason.&lt;p&gt; Like, nicer fonts in the equations, using my favorite font package. Yes, that's it!

&lt;h4&gt;Update:&lt;/h4&gt; Reading the source code, it may be possible to do in-line &lt;code lang="eq.latex"&gt;\LaTeX{}&lt;/code&gt; after all. Yeah. Just use the &lt;tt&gt;&amp;lt;code&amp;gt;&lt;/tt&gt; tags instead.
&lt;p&gt;
Now you can expect to see several posts that have been rotting in my drafts section for a while due to lack of  formula support. Let's just hope I don't promis you too  much.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3460761117713509776-7906288186540477217?l=a-dimit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-dimit.blogspot.com/feeds/7906288186540477217/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3460761117713509776&amp;postID=7906288186540477217' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/7906288186540477217'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/7906288186540477217'/><link rel='alternate' type='text/html' href='http://a-dimit.blogspot.com/2008/11/pto-q.html' title='TeX on Blogger'/><author><name>adimit</name><uri>http://www.blogger.com/profile/04917371723395784281</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_h4s_XF6s_5o/SIo9zlI9jjI/AAAAAAAAAAM/pP0yRe0g0SI/S220/dsc00206square.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3460761117713509776.post-2202771140135607523</id><published>2008-11-19T08:55:00.000-08:00</published><updated>2009-05-05T18:38:55.654-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='overheardin'/><category scheme='http://www.blogger.com/atom/ns#' term='tübingen'/><category scheme='http://www.blogger.com/atom/ns#' term='german'/><title type='text'>Overheard in Tübingen</title><content type='html'>"Ja, es gibt ja halt Zahlen."&lt;br/&gt;
"Ja."&lt;br/&gt;
"Und mit denen kannst Du dann rechnen."&lt;br/&gt;
"Jaaa."&lt;br/&gt;
"Und damit kannst Du dann halt so Daten verschlüsseln."&lt;br/&gt;
"Aha."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3460761117713509776-2202771140135607523?l=a-dimit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-dimit.blogspot.com/feeds/2202771140135607523/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3460761117713509776&amp;postID=2202771140135607523' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/2202771140135607523'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/2202771140135607523'/><link rel='alternate' type='text/html' href='http://a-dimit.blogspot.com/2008/11/overheard-in-tbingen.html' title='Overheard in Tübingen'/><author><name>adimit</name><uri>http://www.blogger.com/profile/04917371723395784281</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_h4s_XF6s_5o/SIo9zlI9jjI/AAAAAAAAAAM/pP0yRe0g0SI/S220/dsc00206square.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3460761117713509776.post-3209492211755467921</id><published>2008-10-11T13:41:00.000-07:00</published><updated>2008-10-11T13:49:54.144-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lisp'/><title type='text'>(defun perspective (person) ( … ))</title><content type='html'>&lt;a href="http://www.cis.upenn.edu/~dbikel/"&gt;Dan Bikel&lt;/a&gt; has written a nice statistical CYK parser for Java, and it reads and writes Lisp syntax, namely &lt;a href="http://en.wikipedia.org/wiki/Sexp"&gt;&lt;b&gt;Sexp&lt;/b&gt;&lt;/a&gt;s. While I was coding on a &lt;a href="http://github.com/adimit/werti/tree/master"&gt;project&lt;/a&gt; today, I was being watched and supported by a colleague. When I used Dan Bikel's Sexp class, hilarity ensued.
&lt;br/&gt;
I countered her chuckles with an explanation of basic Lisp syntax. This prompted a curious reply of hers:
&lt;blockquote&gt;
The inventors must have been lonely people.
&lt;/blockquote&gt;
Well, contracting 'symbolic expressions' to a word reminiscent of what computer freaks stereotypically lack may seem an awkward coincidence to some, but drawing a connection may seem like a stretch to others. Sadly, there probably is a grain of truth in such… assumptions.
&lt;br/&gt;
Upon demonstrating to her some real world examples of Lisp code, and after the inevitable "all those parens!", she uttered
&lt;blockquote&gt;
The inventors really must have been lonely people. And bored ones at that.
&lt;/blockquote&gt;
Poor Lisp. Is that what people think of you today?
&lt;br/&gt;
Lisp is old. &lt;a href="http://en.wikipedia.org/wiki/Lisp_programming_language#History"&gt;Very old&lt;/a&gt;. But just as Prolog, it is still around, and that alone justifies its use. In fact, most of what people use XML for nowadays should rather be done in Lisp syntax.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3460761117713509776-3209492211755467921?l=a-dimit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-dimit.blogspot.com/feeds/3209492211755467921/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3460761117713509776&amp;postID=3209492211755467921' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/3209492211755467921'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/3209492211755467921'/><link rel='alternate' type='text/html' href='http://a-dimit.blogspot.com/2008/10/defun-perspective-person.html' title='(defun perspective (person) ( … ))'/><author><name>adimit</name><uri>http://www.blogger.com/profile/04917371723395784281</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_h4s_XF6s_5o/SIo9zlI9jjI/AAAAAAAAAAM/pP0yRe0g0SI/S220/dsc00206square.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3460761117713509776.post-2966086363280802167</id><published>2008-10-08T07:38:00.000-07:00</published><updated>2008-10-09T03:18:28.195-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='rants'/><category scheme='http://www.blogger.com/atom/ns#' term='Code'/><title type='text'>Thou Shalt not Forget Those Who Are Afraid of Upgrades</title><content type='html'>&lt;p&gt;I don't know how often I will have to curse about type erasure in the Java HotSpot VM. It is a pain in the… &lt;em&gt;EVERYTHING&lt;/em&gt;. And the only reason for it is, of course, our sacred backward compatibility.&lt;br/&gt;
Some core library functionalities are utterly broken. How can a parameterized &lt;code&gt;ArrayList&lt;/code&gt;'s &lt;code&gt;.toArray()&lt;/code&gt; return &lt;code&gt;Object[]&lt;/code&gt;?&lt;br/&gt;&lt;b&gt;&lt;em&gt;WHY??&lt;a href="#foot1"&gt;*&lt;/a&gt;&lt;/em&gt;&lt;/b&gt;&lt;br/&gt;
All because of type erasure. &lt;code&gt;class Foo&lt;T&gt; {{T[] = new T[42]; }}&lt;/code&gt; is illegal, because the runtime would have no clue as to what constructor to call for the array (it doesn't know its type). It boils down to: &lt;em&gt;you cannot instantiate Generics&lt;/em&gt;. OK, you say, it wouldn't make too much of a sense anyway, but you see, it has side effects. Ever bothered to read the code of &lt;code&gt;ArrayList&lt;/code&gt; and other parameterized standard collection types that use an array as a back end? Don't, if you want to retain your sanity. The heart of it is a lot of dirty casting, made necessary because of the way Generics are implemented (oh, the irony.)&lt;br/&gt;
One of the proposed features for Java 7 are &lt;a href="http://tech.puredanger.com/java7#reified"&gt;Reified Generics&lt;/a&gt;, but somehow I doubt they'll make it into the language anytime soon. There's just still too many people around using a 1.4 VM (YES, Apple, we're looking at &lt;em&gt;YOU&lt;/em&gt;) and introducing another substantial change to the way Generics work would make them even more complex than &lt;a href="http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html"&gt;they already are&lt;/a&gt; (Yes, that PDF has more than 500 pages. Yes, it's mostly about Generics.) So, probably we'll have to just keep up with that crap. Microsoft did it right in .NET. Pity it's a closed platform.&lt;p&gt;
&amp;lt;/rant&amp;gt;
&lt;hrule/&gt;
&lt;a name="foot1"&gt;[1]&lt;/a&gt; You have to first create an Array of your Type T (a &lt;em&gt;literal&lt;/em&gt; type, not a Generic one) and then pass it to the overloaded &lt;code&gt;.toArray(T[])&lt;/code&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3460761117713509776-2966086363280802167?l=a-dimit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-dimit.blogspot.com/feeds/2966086363280802167/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3460761117713509776&amp;postID=2966086363280802167' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/2966086363280802167'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/2966086363280802167'/><link rel='alternate' type='text/html' href='http://a-dimit.blogspot.com/2008/10/thou-shalt-not-forget-those-who-are.html' title='Thou Shalt not Forget Those Who Are Afraid of Upgrades'/><author><name>adimit</name><uri>http://www.blogger.com/profile/04917371723395784281</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_h4s_XF6s_5o/SIo9zlI9jjI/AAAAAAAAAAM/pP0yRe0g0SI/S220/dsc00206square.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3460761117713509776.post-2229189948448690263</id><published>2008-08-19T14:01:00.000-07:00</published><updated>2008-08-19T14:06:54.019-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='trivia'/><title type='text'>Luv Github</title><content type='html'>You gotta love &lt;a href="http://github.com"&gt;github&lt;/a&gt; at least for their error messages:

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_h4s_XF6s_5o/SKs1qufIgyI/AAAAAAAAAAY/Wsj_8LO2F-k/s1600-h/gituhb.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_h4s_XF6s_5o/SKs1qufIgyI/AAAAAAAAAAY/Wsj_8LO2F-k/s320/gituhb.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5236337999897723682" /&gt;&lt;/a&gt;

I know whom I have to blame that I can't but think about tentacle rape porn now...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3460761117713509776-2229189948448690263?l=a-dimit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-dimit.blogspot.com/feeds/2229189948448690263/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3460761117713509776&amp;postID=2229189948448690263' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/2229189948448690263'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/2229189948448690263'/><link rel='alternate' type='text/html' href='http://a-dimit.blogspot.com/2008/08/luv-github.html' title='Luv Github'/><author><name>adimit</name><uri>http://www.blogger.com/profile/04917371723395784281</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_h4s_XF6s_5o/SIo9zlI9jjI/AAAAAAAAAAM/pP0yRe0g0SI/S220/dsc00206square.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_h4s_XF6s_5o/SKs1qufIgyI/AAAAAAAAAAY/Wsj_8LO2F-k/s72-c/gituhb.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3460761117713509776.post-2171465046756128869</id><published>2008-08-10T10:42:00.000-07:00</published><updated>2008-08-10T11:30:24.678-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='politics'/><title type='text'>What Do You Want To Live For?</title><content type='html'>&lt;p&gt;There he is, the mid-twen, contemplating the meaning of life. Take care of your career, or go farming the fields? Why not do both? Why live at all?  &lt;br/&gt;You're not asking yourself these questions?&lt;/p&gt;&lt;p&gt;You &lt;a href="http://www.mediastorm.org/0022.htm"&gt;should&lt;/a&gt;.&lt;br/&gt; And then &lt;a href="http://www.mediastorm.org/0020.htm"&gt;some&lt;/a&gt; &lt;a href="http://www.mediastorm.org/0021.htm"&gt;more&lt;/a&gt;.  &lt;br/&gt;It seems &lt;a href="http://www.mediastorm.org/"&gt;MediaStorm&lt;/a&gt; is an invaluable resource of doubt. Doubt every breath you dare to take, every word you write. Doubt them as being privileges you haven't done jack for.&lt;/p&gt; &lt;p&gt;&lt;i&gt;"What are you complaining about? That's the best system we have, and don't tell me it's not working fine!"&lt;/i&gt; Being equally ignorant as the feudal ruling class, people fail to see what's happening &lt;a href="http://8in.org/beijing-olympics-one-world-one-dream-this-is-sad-pic/"&gt;outside their parks&lt;/a&gt;, castles and palaces.&lt;br/&gt; Only the dimensions have shifted. It's a global village now, The West being an enormous castle of nescience, feeding on everybody else.  &lt;/p&gt; But what do I do for it? Nothing. Yet?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3460761117713509776-2171465046756128869?l=a-dimit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-dimit.blogspot.com/feeds/2171465046756128869/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3460761117713509776&amp;postID=2171465046756128869' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/2171465046756128869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/2171465046756128869'/><link rel='alternate' type='text/html' href='http://a-dimit.blogspot.com/2008/08/what-do-you-want-to-live-for.html' title='What Do You Want To Live For?'/><author><name>adimit</name><uri>http://www.blogger.com/profile/04917371723395784281</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_h4s_XF6s_5o/SIo9zlI9jjI/AAAAAAAAAAM/pP0yRe0g0SI/S220/dsc00206square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3460761117713509776.post-8156835797555688607</id><published>2008-07-26T06:43:00.000-07:00</published><updated>2008-07-26T06:49:50.844-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rants'/><title type='text'>The Power of ASP.NET</title><content type='html'>To all you web admins and coders of web servers: &lt;i&gt;please make sure to &lt;b&gt;fail gracefully&lt;/b&gt;&lt;/i&gt;. What does that mean? Well, you shouldn't present your potential readers with such hilarious demonstrations of your own incompetence:
&lt;pre&gt;&lt;code&gt;HTTP/1.1 404 Connection: close Date: Sat, 26 Jul 2008 13:35:29 GMT 
    Server: Microsoft-IIS/6.0 X-Powered-By: ASP.NET &lt;/code&gt;&lt;/pre&gt;
What's that? A decent 404 message? No! A decent 404 message should include at least an excuse, a clear description of the problem, (not everyone knows how to make sense of something like &lt;tt&gt;HTTP/1.1 404 Connection: closed.&lt;/tt&gt;) and probably a sitemap or search resource to find the content the user came to your web page for in the first place!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3460761117713509776-8156835797555688607?l=a-dimit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-dimit.blogspot.com/feeds/8156835797555688607/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3460761117713509776&amp;postID=8156835797555688607' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/8156835797555688607'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/8156835797555688607'/><link rel='alternate' type='text/html' href='http://a-dimit.blogspot.com/2008/07/power-of-aspnet.html' title='The Power of ASP.NET'/><author><name>adimit</name><uri>http://www.blogger.com/profile/04917371723395784281</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_h4s_XF6s_5o/SIo9zlI9jjI/AAAAAAAAAAM/pP0yRe0g0SI/S220/dsc00206square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3460761117713509776.post-2187036332917764601</id><published>2008-07-25T14:09:00.000-07:00</published><updated>2008-11-20T14:12:16.627-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tips'/><category scheme='http://www.blogger.com/atom/ns#' term='unix'/><title type='text'>Safer startx</title><content type='html'>&lt;p&gt;
  Many people claim one should be using a display manager for starting one's &lt;tt&gt;X&lt;/tt&gt; session. One oft cited reason to do so is that when you use &lt;tt&gt;startx&lt;/tt&gt; to fire it up, a malicious person could just circumvent any lock you may have put on your X-session by &lt;tt&gt;[ctrl]-[alt]-[←]&lt;/tt&gt;'ing the server and then being dropped to the console.
  &lt;br/&gt;
  However, you can just use the following command:
  &lt;pre&gt;&lt;code&gt; startx;exit &lt;/code&gt;&lt;/pre&gt;
  This will exit your session once &lt;tt&gt;startx&lt;/tt&gt; exits. Since X traps all signals, switching to the tty and trying to suspend it won't work.  &lt;br/&gt;
  There's one catch though: my default shell (zsh) will warn you about programs you may still have running in the same shell before exiting and thus prevent the &lt;tt&gt;exit&lt;/tt&gt; command from actually doing its job. So you should be careful about this, or just alias &lt;tt&gt;startx&lt;/tt&gt; so that it first turns off the offending shell option.
  &lt;br/&gt;
  This is, of course, also handy for safely giving away restricted prompts to other users (&lt;tt&gt;su &lt;i&gt;someuser&lt;/i&gt;&lt;/tt&gt; comes to my mind).
&lt;/p&gt;
&lt;p&gt;
  If someone knows a reason this is &lt;i&gt;not&lt;/i&gt; safe, please tell me :-)
&lt;/p&gt;
&lt;p&gt;
Edit: I initially thought the pun in this post's title would work only in German, but it appears to be OK for English, too. Thanks to ke for pointing this out.
&lt;/p&gt;
&lt;p&gt;
&lt;h4&gt;Update:&lt;/h4&gt;
&lt;p&gt;I'm such a jerk. Just use the shell's built-in &lt;tt&gt;exec&lt;/tt&gt;. &lt;i&gt;Sheesh&lt;/i&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3460761117713509776-2187036332917764601?l=a-dimit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-dimit.blogspot.com/feeds/2187036332917764601/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3460761117713509776&amp;postID=2187036332917764601' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/2187036332917764601'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/2187036332917764601'/><link rel='alternate' type='text/html' href='http://a-dimit.blogspot.com/2008/07/safer-startx.html' title='Safer &lt;tt&gt;startx&lt;/tt&gt;'/><author><name>adimit</name><uri>http://www.blogger.com/profile/04917371723395784281</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_h4s_XF6s_5o/SIo9zlI9jjI/AAAAAAAAAAM/pP0yRe0g0SI/S220/dsc00206square.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3460761117713509776.post-686993110225178460</id><published>2008-07-23T05:01:00.000-07:00</published><updated>2008-07-23T10:32:41.334-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Prolog'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='Code'/><title type='text'>About the Inertia of Programmers</title><content type='html'>&lt;h3&gt;The Adoption Formula&lt;/h3&gt;
&lt;p&gt;
  Over at the &lt;a href="http://arcfn.com/"&gt;Arc Language Blog&lt;/a&gt;, there's a &lt;a href="http://arcfn.com/2008/07/why-your-favorite-language-is-unpopular.html" &gt;nice post&lt;/a&gt; trying to give a reason why cool new technologies like Haskell don't catch on nowadays - and why cool old technologies like Lisp didn't catch on some years ago. I'd toss in some Prolog, too - although one reason for Prolog not to be adopted was surely that it was a pain to run on olden days machines.
&lt;/p&gt;
&lt;p&gt; 
  What they say, basically, is that languages like Lisp or Haskell (or Prolog) are solutions in search of a problem. Not that they're not cool. They are. But who needs higher order functions in programming? &lt;br/&gt; The basic problem is a relation between a certain user's &lt;i&gt;crisis&lt;/i&gt; (set of problems, if you so prefer) and the &lt;i&gt;pain of adoption&lt;/i&gt;. Let's face it: programmers are a lazy bunch. We'll try not to deviate from the known path any more than we absolutely have to. We remember what a pain it was getting here in the first place. So we have to have a big crisis and some solution that can &lt;i&gt;easily&lt;/i&gt; solve this crisis by offering us a way to approach our problems that feels similar to what we already know. Since Haskell, Lisp and Prolog all offer solutions to a set of problems most programmers are not even aware they have (and therefore probably don't really have in the first place), not many people bother picking them up. If they offered solutions to problems programmers &lt;i&gt;know&lt;/i&gt; they have, they would see a wider range of adoption.
&lt;/p&gt;
&lt;p&gt;
  To make it a bit more clear, take Linux as an example. When Linux saw the light of day, there was an operating system crisis of some sort: Windows dominated the markets and UNIX-based solutions for home PCs weren't cheap or viable (or at all available). BSD was closed source, the HURD was the same vapor it's today. Linux offered UNIX-geeks an easy way out: an operating system that's &lt;i&gt;the same&lt;/i&gt; in many aspects, &lt;i&gt;except&lt;/i&gt; for &lt;b&gt;those&lt;/b&gt; that weren't good about the &lt;i&gt;old&lt;/i&gt; one. So that's why Linux got big in geek-world.&lt;br/&gt;
  But on the desktop market, where grandma and all those pathetic stereotypical example PEBKACs can't tell the difference between a browser and a mail application, Linux is still largely unheard of. Why? Well, Linux solves problems grandma doesn't even know how to &lt;i&gt;spell&lt;/i&gt;, nevermind realise having them. Free software? DRM? Hardware support? Stability? Security? Who cares?&lt;br/&gt;
Spinning 3D cube? Oooooh, shiny!
&lt;/p&gt;
&lt;h3&gt;That's All Folks... is it?&lt;/h3&gt;
&lt;p&gt;
  I'd argue that there is one more aspect to it: if technologies like Lisp or Prolog didn't get adopted, why are they not forgotten? Heck, even COBOL is still around and COBOL is everything &lt;b&gt;but&lt;/b&gt; cool. There's an easy answer: &lt;i&gt;those languages found a &lt;b&gt;niche&lt;/b&gt;&lt;/i&gt;. Lisp has always been big in AI development. COBOL, who knows. Prolog has always had a nice and warm room in the basement of universities - and is now catching on in NLP. In those niches, people come from a different background. They have a different notion of pain.  For me, managing pointers, &lt;tt&gt;malloc()&lt;/tt&gt; calls and machine code are a pain. I can deal with the first, don't really understand much about the second and have an allergy to the third. But higher order functions? I've had dreams which happened in intensional logic (that was after reading a paper by Groenendijk &amp;amp; Stokhof, I think)! That was a weird feeling waking up, I can tell you.
&lt;/p&gt;
&lt;p&gt;
  Also, our crises are different: we need to interface with inferencing tools, and translate logic and mathematical formulae directly into machine instructions.  Doing this in C is a pain. I have nothing but admiration for the people behind &lt;a href="http://www.cs.unm.edu/~mccune/mace4/"&gt;prover9/mace4&lt;/a&gt;, but I'd argue that Haskell is more suitable for that task. A solution that is less of a pain for us is Prolog. You can program almost the same way you write things down in theory (and quickly see where your theory is failing. Damn). You can then go on debugging your theory and back again to punching it in. To a person doing work in IT business, Prolog will look like a complete disaster. What, &lt;b&gt;no unit tests?&lt;/b&gt;. Well, no. But you have &lt;tt&gt;guitracer/0&lt;/tt&gt; :-).
&lt;/p&gt;
&lt;p&gt;
  So, I don't think that Prolog &lt;i&gt;has to&lt;/i&gt; catch on. It's good enough if it stays around. Haskell is more suitable for an even wider range of tasks (basically everything), but probably even more of a pain to get started with.  But it seems that recently many people got interested in Haskell. &lt;a href="http://programming.reddit.com"&gt;The Programming Reddit&lt;/a&gt; is full of Haskell lately. And there is now a &lt;a href="http://www.haskell.org/mailman/listinfo/beginners"&gt;haskell-beginners&lt;/a&gt; list and it seems that introductory CS courses at T&amp;uuml;bingen University are being taught in Scheme. Functional programming has received a lot of attention lately - let's see what comes out of it.
&lt;/p&gt;
&lt;p&gt;
  Meanwhile, I don't care. As long as Haskell and Prolog continue to be developed and used by a certain niche population, I'm happy. I'll be using them happily. They solve some crises I have, they are not a big pain to adopt if you come with a strong background in logics and sorted type theory. And every time I cuss at Prolog, I have to remember: would it be any better doing &lt;i&gt;this&lt;/i&gt; in &lt;b&gt;&lt;i&gt;Java&lt;/i&gt;&lt;/b&gt;? Probably not.
&lt;/p&gt;
&lt;p&gt;
  Oh, and by the way: if you happen to wonder what good books there are on learning logic: Read Gamut's Introduction to Logic and also Volume 2, Introduction to Intensional Logic. Some of the best books I've ever had the pleasure to read. Somewhere next to Camus' Stranger, Dostojewski's Idiot and Nietzsche's Zarathustra.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3460761117713509776-686993110225178460?l=a-dimit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-dimit.blogspot.com/feeds/686993110225178460/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3460761117713509776&amp;postID=686993110225178460' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/686993110225178460'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/686993110225178460'/><link rel='alternate' type='text/html' href='http://a-dimit.blogspot.com/2008/07/about-inertia-of-programmers.html' title='About the Inertia of Programmers'/><author><name>adimit</name><uri>http://www.blogger.com/profile/04917371723395784281</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_h4s_XF6s_5o/SIo9zlI9jjI/AAAAAAAAAAM/pP0yRe0g0SI/S220/dsc00206square.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3460761117713509776.post-5022686244466348062</id><published>2008-07-18T04:20:00.000-07:00</published><updated>2008-07-18T18:00:31.893-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Computational Semantics'/><category scheme='http://www.blogger.com/atom/ns#' term='Prolog'/><category scheme='http://www.blogger.com/atom/ns#' term='BA thesis'/><category scheme='http://www.blogger.com/atom/ns#' term='Code'/><title type='text'>Advertent Curt</title><content type='html'>Wohoo, I handed in my BA thesis topic today:

&lt;h3&gt;From Questions to Queries&lt;/h3&gt;
&lt;h4&gt;Enhancing the Curt System by a Theory and Implementation of Embedded WH-Questions&lt;/h4&gt;

&lt;p&gt;The Curt System is implemented in Prolog and presented in the last chapter of
&lt;a href="http://www.cogsci.ed.ac.uk/~jbos/comsem/book1.html"&gt;Blackurn &amp;amp; Bos (2005)&lt;/a&gt;, a brilliant book about Vincent, who loves Mia, every owner of a hash bar and foot massages. Oh, and computational semantics. And boxers.&lt;/p&gt;
&lt;p&gt;Curt is short for &lt;b&gt;C&lt;/b&gt;lever &lt;b&gt;u&lt;/b&gt;se of &lt;b&gt;r&lt;/b&gt;easoning &lt;b&gt;t&lt;/b&gt;ools. Blackburn &amp;amp; Bos use external inferencing tools, a DCG grammar and an emulation of λ-Calculus in Prolog to put together a nice system that is able to parse sentences according to a toy grammar, construct (discourse) models and logic representations of the discourse. They use inferencing to check the discourse for satisfiability and validity.&lt;/p&gt;
&lt;p&gt;They develop several variants of the Curt System throughout that chapter, gradually introducing external inferencing, satisfiability checks, validity checks, model building, world and situational knowledge, ontologies and, last but not least, a way to interpret questions in their framework. The last version of the system is codenamed "Helpful Curt" - it can answer basic direct WH-questions by substituting the WH-phrase for an existential quantification over an uninstantiated variable and running a bit of inferencing magic on it in order to find a result.&lt;/p&gt;
&lt;h4&gt;Advertent Curt&lt;/h4&gt;
&lt;p&gt;But I found that a bit ad-hoc. Basically, all of the system is a tad ad-hoc (they use Keller Storage for it still!) and it could use some work in order to become &lt;i&gt;really&lt;/i&gt; awesome (although it's already &lt;i&gt;quite&lt;/i&gt; awesome!). I'd like to show in my thesis that it's possible to introduce a formal account of question semantics into the system. I'll be following Groenendijk &amp;amp; Stokhof's analyses for the most part, also arguing about Karttunen's earlier approach. The main reason for me choosing G&amp;amp;K over Karttunen was that the former use Ty2 to describe their system, whereas Karttunen stays in traditional Montague IL, which would be harder to transfer into the Prolog world.&lt;/p&gt;
&lt;p&gt;Ideally, the system should be able to handle the following types of questions:&lt;/p&gt;
&lt;blockquote&gt;
(1) Vincent knows whether Mia loves Marcellus &lt;br/&gt;
(2) Marcellus believes Mia loves Vincent&lt;br/&gt;
(3) Every owner of a hash bar knows who likes hash
&lt;/blockquote&gt;
&lt;h4&gt;But why &lt;i&gt;embedded &lt;/i&gt;questions?&lt;/h4&gt;
&lt;p&gt;Almost all accounts of formal question semantics (I know of) treat direct questions as a subtype of embedded questions (Well, except Hamblin, but that's obvious[ly not adequate here]). Once we solve embedded questions, implementing a few transformation steps to translate (4a) into (4b) should pose no problem.&lt;/p&gt;
&lt;blockquote&gt;
(4 a.) Tell me who owns a hash bar.&lt;br/&gt;
(4 b.) Who owns a hash bar?
&lt;/blockquote&gt;
&lt;p&gt;In this regard I'm taking the very opposite of the more pragmatic approach by Blackburn &amp;amp; Bos, which explicitly handles direct questions only.&lt;/p&gt;
&lt;p&gt;I will try to keep the blog up-to-date with progress and ideas :-)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3460761117713509776-5022686244466348062?l=a-dimit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-dimit.blogspot.com/feeds/5022686244466348062/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3460761117713509776&amp;postID=5022686244466348062' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/5022686244466348062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/5022686244466348062'/><link rel='alternate' type='text/html' href='http://a-dimit.blogspot.com/2008/07/advertent-curt.html' title='Advertent Curt'/><author><name>adimit</name><uri>http://www.blogger.com/profile/04917371723395784281</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_h4s_XF6s_5o/SIo9zlI9jjI/AAAAAAAAAAM/pP0yRe0g0SI/S220/dsc00206square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3460761117713509776.post-5129801399156810452</id><published>2008-07-12T16:09:00.000-07:00</published><updated>2008-07-18T04:20:00.724-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linguistics'/><category scheme='http://www.blogger.com/atom/ns#' term='trivia'/><title type='text'>Anachronism isn't what it Used to Be...</title><content type='html'>&lt;p&gt;I'm not an English native speaker - and sometimes I find myself in a situation where I need to look up a word from the dictionary in order to find more graceful-sounding synonyms, et cetera. But the dictionary is not always very helpful. Consider the following query in a thesaurus:
&lt;blockquote&gt;
Synonyms for &lt;i&gt;begin&lt;/i&gt;:
…
inaugurate
…
&lt;/blockquote&gt;
Well - using &lt;i&gt;to inaugurate&lt;/i&gt; right away would lead to strange results, because it's not really used for anything besides politics nowadays.&lt;/p&gt;

&lt;h3&gt;Concordance and Collocation&lt;/h3&gt;
&lt;p&gt;This means that sometimes you'll have to not only search for the translation or synonyms of a word, but also for &lt;i&gt;usage examples&lt;/i&gt;. A good Dictionary typically provides you with some, but is also usually limited in the amount of examples it can display. This is why looking at occurrances of a word in real text together with their immidiate context is sometimes unaviodable (and in fact the way dictionaries are made). Linguists call that &lt;b&gt;concordance&lt;/b&gt;, for &lt;em&gt;grammatical agreement&lt;/em&gt; (e.g. using the right temporal form or aspect or the right preposition) and &lt;b&gt;collocation&lt;/b&gt; for &lt;em&gt;statistic relatedness&lt;/em&gt; (two or more words that form a phrase or a certain reoccurring pattern in language). What linguists now do to find out &lt;i&gt;how&lt;/i&gt; a word is used, is, they search for the word in &lt;b&gt;corpora&lt;/b&gt; and then classify its context - and patterns thereof.&lt;/p&gt;
&lt;h3&gt;A Poor Man's Corpus-engine: Google&lt;/h3&gt;
&lt;p&gt;But such corpora are usually hard to get or expensive, since virtually every accumulation of a non-trivial amount of text will contain copyrighted material (and it's often not easy (read: expensive) to enhance the signal-to-noise ratio). So, as a poor man, one has to resort to &lt;b&gt;Google&lt;/b&gt; or equivalent search machines. Searching for a particular word or phrase in Google will often give satisfactory results for its most typical usage patterns. Phrase queries often help to narrow the scope of possible collocations.&lt;/p&gt;
&lt;p&gt;… and while doing a bit of research I discovered the following: &lt;b&gt;A word is archaic if the first two pages of Google hits for it return only results from dictionaries.&lt;/b&gt; Try searching for &lt;i&gt;advertent&lt;/i&gt; (heck, it's not even in vim's default word file on Debian anymore…) as an example...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3460761117713509776-5129801399156810452?l=a-dimit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-dimit.blogspot.com/feeds/5129801399156810452/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3460761117713509776&amp;postID=5129801399156810452' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/5129801399156810452'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/5129801399156810452'/><link rel='alternate' type='text/html' href='http://a-dimit.blogspot.com/2008/07/anachronism-isnt-what-it-used-to-be.html' title='Anachronism isn&apos;t what it Used to Be...'/><author><name>adimit</name><uri>http://www.blogger.com/profile/04917371723395784281</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_h4s_XF6s_5o/SIo9zlI9jjI/AAAAAAAAAAM/pP0yRe0g0SI/S220/dsc00206square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3460761117713509776.post-1204827708238038879</id><published>2008-07-12T05:54:00.000-07:00</published><updated>2008-07-12T06:17:23.910-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Prolog'/><category scheme='http://www.blogger.com/atom/ns#' term='Code'/><title type='text'>At Night, Alone with the Computer...</title><content type='html'>&lt;p&gt;My favorite Prolog dialog&lt;/p&gt;
&lt;code&gt;
?- true.
true.
&lt;/code&gt;
&lt;p&gt;
A lonesome bungalow in the forest; a man; his computer. A conversation arises.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3460761117713509776-1204827708238038879?l=a-dimit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-dimit.blogspot.com/feeds/1204827708238038879/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3460761117713509776&amp;postID=1204827708238038879' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/1204827708238038879'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/1204827708238038879'/><link rel='alternate' type='text/html' href='http://a-dimit.blogspot.com/2008/07/at-night-alone-with-computer.html' title='At Night, Alone with the Computer...'/><author><name>adimit</name><uri>http://www.blogger.com/profile/04917371723395784281</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_h4s_XF6s_5o/SIo9zlI9jjI/AAAAAAAAAAM/pP0yRe0g0SI/S220/dsc00206square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3460761117713509776.post-8845172771751778772</id><published>2008-07-12T05:39:00.000-07:00</published><updated>2008-07-12T05:42:20.744-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='welocme'/><title type='text'>Welcome.</title><content type='html'>&lt;h1&gt;Welcome&lt;/h1&gt;
&lt;p&gt;This is probably just a temporary location, 'till I find some other place on the Net. My blog used to be hosted at &lt;a href="http://baywords.com"&gt;Baywords&lt;/a&gt;, but they seem to have screwed up something.&lt;/p&gt;
&lt;p&gt;So long, have fun.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3460761117713509776-8845172771751778772?l=a-dimit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-dimit.blogspot.com/feeds/8845172771751778772/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3460761117713509776&amp;postID=8845172771751778772' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/8845172771751778772'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/8845172771751778772'/><link rel='alternate' type='text/html' href='http://a-dimit.blogspot.com/2008/07/welcome-this-is-probably-just-temporary.html' title='Welcome.'/><author><name>adimit</name><uri>http://www.blogger.com/profile/04917371723395784281</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_h4s_XF6s_5o/SIo9zlI9jjI/AAAAAAAAAAM/pP0yRe0g0SI/S220/dsc00206square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3460761117713509776.post-1141495504552365502</id><published>2008-06-07T05:46:00.000-07:00</published><updated>2008-07-13T03:17:39.779-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><category scheme='http://www.blogger.com/atom/ns#' term='tips'/><category scheme='http://www.blogger.com/atom/ns#' term='Code'/><title type='text'>Folding in VIM</title><content type='html'>&lt;h2&gt;Code Folding in VIM&lt;/h2&gt;
&lt;a href="http://vi-improved.org"&gt;Vim&lt;/a&gt; is arguably one of the most awesome editors around. I use it exclusively, extending it with many plugins. As of version 6.0 Vim supports &lt;a href="http://www.vim.org/htmldoc/fold.html"&gt;code folding&lt;/a&gt;, a nice way to hide blocks you don't need to see and thus reduce the visible complexity of the code you're editing.&lt;/p&gt;
&lt;p&gt;
Vim accomplishes this using a &lt;em&gt;foldmethod&lt;/em&gt; which can guess where to fold the code based on &lt;strong&gt;syntactic&lt;/strong&gt; hints (defined in the syntax file of the FileType you're using), &lt;strong&gt;indentation&lt;/strong&gt; and other methods, including manual mark-up of foldable regions. It then calls a function stored in &lt;em&gt;foldtext&lt;/em&gt; that computes a text to display instead of the text region folded away. You can see vim's default foldtext in action here:
&lt;/p&gt;&lt;p&gt;

&lt;blockquote&gt;
Here used to be a screenshot showing some code blocks in VIM, but &lt;a href="http://omploader.org"&gt;omploader.org&lt;/a&gt; think it's funny to molest people into not using their service, rather than just telling them...&lt;br/&gt;
I'll try to replace it soon.
&lt;/blockquote&gt;

&lt;blockquote&gt;
Here used to be a screenshot showing VIM's default code folding routine in action, but &lt;a href="http://omploader.org"&gt;omploader.org&lt;/a&gt; think it's funny to molest people into not using their service, rather than just telling them...&lt;br/&gt;
I'll try to replace it soon.
&lt;/blockquote&gt;
&lt;h3&gt;Rolling your own&lt;/h3&gt;
&lt;p&gt;I find Vim's default foldtext a bit hideous. Most importantly it messes up indentation and I'm &lt;em&gt;very&lt;/em&gt; religious abuot indentation, given I'm a horizontal reader and use 8 spaces (one traditional tab) for indentation. So I tried to came up with something minimalistic that would preserve indentation on collapsed folds, using my traditional fold method &lt;em&gt;syntax&lt;/em&gt;. I failed, but &lt;a href="http://www.infynity.spodzone.com/"&gt;Heptite&lt;/a&gt; I met in &lt;em&gt;#vim&lt;/em&gt; on irc.freenode.net helped me out with this code:&lt;/p&gt;
&lt;code&gt;
set foldtext=MyFoldText()
&amp;nbsp;
" Folds preserving indentation and without clutter
function! MyFoldText()
let i = indent(v:foldstart)
return repeat(' ', i) . substitute(getline(v:foldstart), '^\s\+', '', '')
endfunction
&amp;nbsp;
" Reload folding
nmap &amp;lt;F3&amp;gt; :syn sync fromstart
&lt;/code&gt;
&lt;p&gt;
The function &lt;em&gt;MyFoldText()&lt;/em&gt; was his idea of approaching the problem. I had some trouble coming up with one myself because &lt;em&gt;getline(v:foldstart)&lt;/em&gt; seems to include a leading indent which messed up the folding when a syntax element triggering folding (as defined in the syntax file) would be split across more than one line (like a bloated method declaration featuring many throws or arguments). I really think that this is a bug in Vim's folding method and eliminating leading spaces with a &lt;em&gt;substitute&lt;/em&gt; command is just a workaround, but it works quite well for now and gives very pleasing results:&lt;/p&gt;
&lt;p&gt;

&lt;blockquote&gt;
Here used to be a screenshot showing my current code folding routine in action, but &lt;a href="http://omploader.org"&gt;omploader.org&lt;/a&gt; think it's funny to molest people into not using their service, rather than just telling them...&lt;br/&gt;
I'll try to replace it soon.
&lt;/blockquote&gt;

&lt;i&gt;&lt;br&gt;A look at a Tagger with code folding enabled.&lt;/i&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3460761117713509776-1141495504552365502?l=a-dimit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-dimit.blogspot.com/feeds/1141495504552365502/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3460761117713509776&amp;postID=1141495504552365502' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/1141495504552365502'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/1141495504552365502'/><link rel='alternate' type='text/html' href='http://a-dimit.blogspot.com/2008/07/folding-in-vim.html' title='Folding in VIM'/><author><name>adimit</name><uri>http://www.blogger.com/profile/04917371723395784281</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_h4s_XF6s_5o/SIo9zlI9jjI/AAAAAAAAAAM/pP0yRe0g0SI/S220/dsc00206square.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3460761117713509776.post-4491633199516964116</id><published>2008-06-06T04:44:00.000-07:00</published><updated>2008-07-13T03:14:45.162-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rants'/><category scheme='http://www.blogger.com/atom/ns#' term='Code'/><title type='text'>Shit happens.</title><content type='html'>... only to you and when you'd need to get stuff done as quickly as possible

&lt;blockquote&gt;
Here used to be a screenshot showing one of IBM's documentation resources about UIMA down, but &lt;a href="http://omploader.org"&gt;omploader.org&lt;/a&gt; think it's funny to molest people into not using their service, rather than just telling them...
&lt;/blockquote&gt;

Ah well, I'll need to remember that docs myself now. That'll teach me to sync documentation offline.

BTW. Another great example why creating a dark-net to store something as harmless as documentation and/or howtos is braindead. If they hadn't forced me to sign up for their service, I could've used &lt;a href="http://archive.org"&gt;The Internet Archive&lt;/a&gt; or the Google cache.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3460761117713509776-4491633199516964116?l=a-dimit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-dimit.blogspot.com/feeds/4491633199516964116/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3460761117713509776&amp;postID=4491633199516964116' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/4491633199516964116'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/4491633199516964116'/><link rel='alternate' type='text/html' href='http://a-dimit.blogspot.com/2008/06/shit-happens.html' title='Shit happens.'/><author><name>adimit</name><uri>http://www.blogger.com/profile/04917371723395784281</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_h4s_XF6s_5o/SIo9zlI9jjI/AAAAAAAAAAM/pP0yRe0g0SI/S220/dsc00206square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3460761117713509776.post-8480175848358240607</id><published>2008-05-25T05:49:00.000-07:00</published><updated>2008-07-12T05:50:58.715-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='reviews'/><category scheme='http://www.blogger.com/atom/ns#' term='music'/><title type='text'>Uncanny Rattles at Night Time: Johansson Sings Waits</title><content type='html'>&lt;p&gt;So I decided to write something up about this new album I recently downloaded after hearing about it from people at &lt;a href="http://kaioo.com"&gt;kaioo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I've been a huge Waits fan ever since I listened to &lt;i&gt;Frank's Wild Years&lt;/i&gt; for the first time. His exotic grumpiness, his vocals, lax and stern at the same time have fascinated me from the beginning. The music is alsways a bit chaotic, most of the time the instruments provide only a thin layer, every one is just covering its own spot, its own frequency, while Waits' voice paints the songs in melancholy and wisdom. For me, Waits is like a father I never had, he feels like someone able to teach you about the miserable aspects of life, about pubs, prostitutes and alcohol. And music.&lt;/p&gt;
&lt;p&gt;I've never really heard much about &lt;a href="http://en.wikipedia.org/wiki/Scarlett+Johansson"&gt;Johansson&lt;/a&gt; before; I knew she was some kind of Hollywood celebrity, but I never really was into Hollywood nor celebrities. Only after investigating a bit I realized I had seen a movie starring her: &lt;i&gt;Lost in Translation&lt;/i&gt;. I didn't really like the flick though, it felt mediocre.&lt;/p&gt;
&lt;p&gt;So, a mediocre (by my standards) actress starts singing Waits songs? This could either be a complete catastrophy or really interesting. Anyways I had to give the album a try, so I went out to get it. But I was afraid to touch it for another two days.&lt;/p&gt;
&lt;p&gt;I had expected a bubblegum pop album. Or a really really good album. Or something entirely mediocre and trivial. It was neither.&lt;/p&gt;
&lt;p&gt;The album still feels entirely strange to me. I can't really open my mind. Do I like it? I don't know. I don't hate it. But I expected something different and hence I'm completely disoriented. I must say that I can see &lt;i&gt;Lost in Translation&lt;/i&gt; in this album. But, actually, the good parts of it. The waiting, the &lt;i&gt;to-no-avail&lt;/i&gt;-ity, a lot of its melancholy. It starts completey soundtrack-esque, with an instrumental intro. The first bits of her voice in &lt;i&gt;Town with No Cheer&lt;/i&gt;, are preceded by caribbean-sounding steel drums - and manage to surprise you. I expected her to sing better. After all, she had all the money of the world to let all sorts of machines sing instead of her. But, as someone posted in her shoutbox at last.fm - They didn't even try to pretend she can sing. They just let her go away with slight mistakes in pitch and a pretty monotonous voice. A voice not without charisma, but also with a lack of talent. She'll have to make up on it with character and innovations in future releases. I'll let it slip for this one, but I won't for the next.&lt;/p&gt;
&lt;p&gt;All songs are covers, except for #6, &lt;i&gt;Song for Jo&lt;/i&gt;, my favorite. This tune and &lt;i&gt;Green Grass&lt;/i&gt;, #7, are the greatest songs on this album.&lt;/p&gt;
&lt;p&gt;The atmosphere is very post-y, very melancholic. In contrast to Waits' instrumentation, the album feels a bit over-produced, too much reverb, to many stray notes wandering in a sound scape that feels very impressionistic overall - whereas Waits feels more like an expressionist. Instead of the contured, sharp tone of Waits, Johansson and Sitek deliver blurred and fuzzy sounds, sometimes even drone like. Her voice feels like Karaoke on some tracks, especially on &lt;i&gt;I don't wanna grow up&lt;/i&gt;, a ... &lt;b&gt;Disco tune&lt;/b&gt;! She appears to be a girl next door, taking huge sips from the 90's trash cocktail, while casually mentioning that she'll "drink you under the table" in &lt;i&gt;I Wish I was in New Orleans&lt;/i&gt;, the only of Waits' earlier tracks on here. Unfortunately, she (or someone else) decided to pick mostly Waits' later works, which I'm not that familiar with.&lt;/p&gt;
&lt;p&gt;Overall, this album feels strange and new. It's like soundtrack meets Waits meets that cute lost little girl in Japan, that's actually Danish, but an American actress. I tagged it &lt;a href="http://www.last.fm/tag/drone-pop"&gt;&lt;i&gt;drone-pop&lt;/i&gt;&lt;/a&gt; and &lt;a href="http://www.last.fm/tag/post-waits"&gt;&lt;i&gt;post-waits&lt;/i&gt;&lt;/a&gt; since that's what it feels like for me.&lt;/p&gt; 
&lt;p&gt;
I think I like it. &lt;br&gt;It would be hilarious if Johansson started a nice alternative/experimental music career frome here. But somehow I think she won't.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3460761117713509776-8480175848358240607?l=a-dimit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-dimit.blogspot.com/feeds/8480175848358240607/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3460761117713509776&amp;postID=8480175848358240607' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/8480175848358240607'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/8480175848358240607'/><link rel='alternate' type='text/html' href='http://a-dimit.blogspot.com/2008/07/uncanny-rattles-at-night-time-johansson.html' title='Uncanny Rattles at Night Time: Johansson Sings Waits'/><author><name>adimit</name><uri>http://www.blogger.com/profile/04917371723395784281</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_h4s_XF6s_5o/SIo9zlI9jjI/AAAAAAAAAAM/pP0yRe0g0SI/S220/dsc00206square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3460761117713509776.post-6459966881572188806</id><published>2008-05-24T05:51:00.000-07:00</published><updated>2008-07-12T07:30:47.410-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='depressions'/><category scheme='http://www.blogger.com/atom/ns#' term='Code'/><title type='text'>Use the Cluebat, Luke!</title><content type='html'>&lt;blockquote&gt;
Many are stubborn in pursuit of the path they have chosen, few in pursuit of the goal. &lt;br&gt;&lt;i&gt;F. Nietzsche&lt;/i&gt;&lt;/blockquote&gt;
&lt;p&gt;Sometimes us programmers are faced with what I would call the most ridiculous and humiliating aspect of our work: &lt;/p&gt;
&lt;p&gt;You come across a problem. You start thinking about it. You find it ever more complicated, but you go on and on. Actually, this is only &lt;i&gt;one&lt;/i&gt; of the obstactles in your way to achieving your original goal, it's probably not even got something to do with what you were trying to accomplish in the first place...&lt;/p&gt;
&lt;p&gt;Finally you come up with a solution. It took you 2000 lines of code, it reduced your app's performance by 40%, true, it still may have some bugs you don't know of - along with a couple of bugs you know but have no idea how to solve and hence try to sell as features; but, hey! the problem was complicated, after all! And &lt;b&gt;you&lt;/b&gt; &lt;i&gt;solved it&lt;/i&gt;. Yay!&lt;/p&gt;
&lt;p&gt;The glistening, glaring enlightenment strikes you once you're presented with a comment such as &lt;blockquote&gt;"Why didn't you just use random one-liner-solution X?"&lt;/blockquote&gt;
on your work.&lt;/p&gt;
&lt;p&gt;
Of course, your immidiate response goes "Huh?". Your brain feels like it's shrinking. No words available, they're all gone, along with your self-esteem, your thinking your're intelligent and all your coding skills. You've just spent a week's worth of coding time in vain. Everything you did was ugly and totally uncalled for. You take the blame.&lt;/p&gt;
&lt;p&gt;This happened to me yesterday, and the apathy and fear of code is still here, hampering my productivity and just about everything. If it wasn't for the &lt;a href="http://www.last.fm/music/65daysofstatic"&gt;great music&lt;/a&gt; pumping out of my speakers, I would even not feel competent enough to blog about it... Here's what I did.&lt;/p&gt;
&lt;p&gt;I'm currently working on porting a second-language-acqusition-aiding-system (&lt;i&gt;Think taaaanks! We need a nice buzz-word for this, &lt;b&gt;pronto!&lt;/b&gt;&lt;/i&gt;) from mod_python to Java &amp;amp; Servlets (in Tomcat), utilizing the &lt;a href="http://incubator.apache.org/uima"&gt;Apache/IBM UIMA-architecture&lt;/a&gt;. The program fetches remote web sites and performs (not-so-)random input enhancement on them. The problem was displaying remote websites properly on my own server, just like Google Translation does. Long story short, I went to considerable lengths to replace all relative paths in a given page with absolute ones to get the source adresses for extra content right. It worked. Sort of.&lt;/p&gt;
&lt;p&gt;Then I went to my advisor, and, whoops... Ever heard of the HTML &lt;i&gt;&amp;lt;base&amp;gt;&lt;/i&gt; tag? Me neither. It's not even ONE line, replacing all of my crafty and barely readable regular expressions. My conscience faded. Good thing I didn't drop dead right on spot, though I surely wanted to.&lt;/p&gt;
&lt;p&gt;Now I have to gather focus on performing the serious tasks at hand. Fortunately that's something I should know better - really, I think this sort of mistakes happens because you hit a spot in your app where you have to perform a task you don't know shit about. You don't know the libs people use there, you don't even know &lt;i&gt;how to approach the problem&lt;/i&gt;. I asked people on #tomcat and #java on freenode.net, but they couldn't help me either. They were all programmers, I should've asked some web designer. But I didn't... I went all finite state on it, bombarding the poor thing with hideous regexps, wasting my time on a problem that didn't really have to exist in the first place.&lt;/p&gt; 

&lt;p&gt;Oh well, 'tis one of the moments, where I just tend to pessimism, reminding myself about this great quote I came along in Nietzsche's "Menschliches, allzu Menschliches". Strangley, pessimism, like doom metal makes me go optimistic.&lt;/p&gt;
&lt;blockquote&gt;    Nothing lives which would be worthy&lt;br&gt;
    of your striving, and the earth deserves not a sigh.&lt;br&gt;
    Pain and boredom is our being and the world is excrement,&lt;br&gt;
    —nothing else.&lt;br&gt;
    Calm yourself.&lt;br&gt;
&lt;i&gt;G. Leopardi&lt;/i&gt; &lt;/blockquote&gt;
&lt;p&gt;There it goes. People screw up stuff all over the place. This time it had to be you. You're not even special in failing. Go on, dipshit.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3460761117713509776-6459966881572188806?l=a-dimit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-dimit.blogspot.com/feeds/6459966881572188806/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3460761117713509776&amp;postID=6459966881572188806' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/6459966881572188806'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/6459966881572188806'/><link rel='alternate' type='text/html' href='http://a-dimit.blogspot.com/2008/05/many-are-stubborn-in-pursuit-of-path.html' title='Use the Cluebat, Luke!'/><author><name>adimit</name><uri>http://www.blogger.com/profile/04917371723395784281</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_h4s_XF6s_5o/SIo9zlI9jjI/AAAAAAAAAAM/pP0yRe0g0SI/S220/dsc00206square.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3460761117713509776.post-5569523187437240181</id><published>2008-04-26T05:53:00.000-07:00</published><updated>2008-07-12T05:53:49.489-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='rants'/><category scheme='http://www.blogger.com/atom/ns#' term='Code'/><title type='text'>Where Sun Don't Shine</title><content type='html'>&lt;p&gt;Sun are a big company. Really big. They created some of the most reliable server workstations, some of the fastest processors, some of the most stable OSs in the world. And they created the as of now most-used programming language, Java.  Java is sort of nice. It's dumbed-down C++ with some enhancements, it's not feature rich, but nobody in their right minds wants a programming language to be feature rich. I'm a big advocate of &lt;em&gt;"the right tool for the right job"&lt;/em&gt; and feature rich languages seem to contradict to that credo. Java is the right tool for many jobs: GUI creation in Swing is easy and straight forward, networking closs platform is painless and portability is one of Java's main selling points - because it's really easy.  The only thing you have to keep track of is the JVM and source version and there you go. 
&lt;/p&gt;&lt;p&gt; I guess if we lived in milk-and-honey-land, that would make Java a perfect programming language. But it isn't, and milk-and-honey-land is far off. Java was supposed to bring interactive web pages to the clients more than ten years ago (note that JavaScript has nothing to do with Java). It failed. And miserably so, I must say. There's nothing that turns me off more than a page using a Java applet. They are ugly, they are slow to load, memory hogs, and they are buggy. 
&lt;/p&gt;
&lt;p&gt; But I don't care about applets. Servlets are a much better technology anyways, and I found Java to be really useful for Web programming. But this rant is really about Java on the Desktop and about Java for the programmer. Over the years, I've come about some rather annoying misfeatures, bugs and Sun's stubborn way of not wanting to address bugs that have been known - &lt;i&gt;literally&lt;/i&gt; - for years.&lt;/p&gt;
 &lt;p&gt;&lt;li&gt;Swing sucks, after all. It's ugly. It's slow. It's bloated. It lacks a set of really useful and easy-to-customize stuff in the library. Heck I remember hacking Delphi used to be more fun than Swing. At least you didn't have to call.thatMethod().somewhere().InAnInnerClass(WayDown.theCamelCase.objectHierarchy()); But see &lt;a href="#below"&gt;below&lt;/a&gt;&lt;/li&gt;&lt;/p&gt;
&lt;p&gt; &lt;li&gt;Swing sucks even more. Ever tried to run a Swing app on X using a window manager that is not one of {Compiz,Metacity,Kwin}? Well, good luck. &amp;lt;3 grey boxes. This &lt;a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6429775"&gt;has been a bug for a long time&lt;/a&gt;, Sun claim it's fixed. It ain't. It's fixed for Compiz, everything else still has problems. This is because some mind-bogglingly stupid intern at Sun had to &lt;strong&gt;hardcode the goddamn fucking names of Window Managers into .equals() checks of the kluges used for circumventing the original bug&lt;/strong&gt;. The result? My favorite window manager, XMonad, displays Protege &lt;a href="http://omploader.org/vaDB6"&gt;like this&lt;/a&gt;.&lt;/li&gt;&lt;/p&gt;
&lt;p&gt; &lt;li&gt;&lt;a name="below"&gt;&lt;/a&gt;Many people seem to argue against 8-space indentation on the basis of Java code exhausting horizontal screen space even on 1900xX resolutions. That shouldn't be the case. typedefs, operator overloading, sane object names (SomethingBadHappenedButIReallyDontKnowWhatExactlySoHeresAnException, anyone?) and more modern stuff like partial hiding/importing/exporting (like in Haskell) could greatly improve on the situation.&lt;/li&gt;&lt;/p&gt;
&lt;p&gt; &lt;li&gt;Inexplicable syntactic difference between dynamic and static arrays. Yeah, I know, it's just syntactic sugar. Go write your stuff in ASM, then, if you don't like that.&lt;/li&gt;&lt;/p&gt;
&lt;p&gt; &lt;li&gt;No way to generalize a static array. If T is a generic type, &lt;code&gt;T[] stuff = new T[x];&lt;/code&gt; is &lt;em&gt;illegal&lt;/em&gt;. But a function header like &lt;code&gt;void some_function(T[] stuff)&lt;/code&gt; &lt;em&gt;isn't&lt;/em&gt;. This means that you actually &lt;em&gt;can have&lt;/em&gt; static arrays of generalized types, but you have to work your way around like &lt;code&gt;T[] stuff = (T[])Object[x]();&lt;/code&gt; This is ugly, and, moreover, it's dangerous. It's also a restriction that hits the language quite hard. Don't believe me? Read on...&lt;/li&gt;&lt;/p&gt;
&lt;p&gt; &lt;li&gt;Not only that, but you are not allowed to create arrays of inner classes of parameterized classes. That's right. No, I know it's stupid, but it's the way it is. &lt;br&gt;
&lt;code&gt;public class General&amp;lt;T extends Something&amp;gt; {
InnerClass[] ic = new InnerClass[10];
private class InnerClass {
int data;
}
}&lt;/code&gt;
&lt;br&gt;
This will not compile. It fails with the oh-so-descriptive-and-helpful error message "generic array creation". There you go, the inner class doesn't even &lt;em&gt;use&lt;/em&gt; that freaking parameter type. It's enough for it to be a subclass of a paramaeterized type. This is especially annoying when you have to create, say a tree class that is to store all sorts of interesting different types. That would be what them Generics are good for in the first place, right? Well, if you want the tree to have, say, 4 children per node, you'd love to do that using a static array, right? And inner classes are usually the best approach for making a specialized Node class... But in Java, you have to suffer compiler warnings and unsafe typecasts to do that.&lt;/li&gt;&lt;/p&gt;
&lt;p&gt; &lt;li&gt;You can't pass functions as arguments. That's because there are no function pointers. Meh. That makes NLP systems and natural language processing (especially computational semantics) unreasonably complex, because you'll have wrap it all up into classes. But this may fall under the &lt;em&gt;right tool for the right job&lt;/em&gt; clause. I've long since wanted to switch to Prolog, C++ and, lately, Haskell for natural language processing. They're way batter at that than Java.&lt;/li&gt;&lt;/p&gt;
&lt;p&gt;
This isn't even as much as I expected it to be, but there's more that I've missed for now. Jamie Zawinskie has a &lt;a href="http://www.jwz.org/doc/java.html"&gt;lot more on this&lt;/a&gt;, but I do not share all his views. Maybe it's that I'm just no C programmer and therefore I have a whole different set of expectations. Maybe I just don't understand all of his points, but I couldn't agree more with most of the stuff he describes.  When you google for &lt;em&gt;"why java sucks"&lt;/em&gt;, you will find a whole bunch of pages. About 3000, for the phrase query. That's a lot for a phrase query. &lt;/p&gt;&lt;p&gt; I don't say Java sucks in general; it's an OK language for quite a number of tasks. And it's probably even the language I know best. But it has deficiencies, and quite some and then some more. I'll be moving on to greener pastures from now. Prolog sounds nice, it's well suited for what I'm currently doing. Haskell sounds even nicer, and I spend every free minute I can find with monads and similar stuff. I'll probably blog about it, too, when I'm good enough at it. ;-)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3460761117713509776-5569523187437240181?l=a-dimit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://a-dimit.blogspot.com/feeds/5569523187437240181/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3460761117713509776&amp;postID=5569523187437240181' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/5569523187437240181'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3460761117713509776/posts/default/5569523187437240181'/><link rel='alternate' type='text/html' href='http://a-dimit.blogspot.com/2008/04/where-sun-dont-shine.html' title='Where Sun Don&apos;t Shine'/><author><name>adimit</name><uri>http://www.blogger.com/profile/04917371723395784281</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://bp3.blogger.com/_h4s_XF6s_5o/SIo9zlI9jjI/AAAAAAAAAAM/pP0yRe0g0SI/S220/dsc00206square.jpg'/></author><thr:total>0</thr:total></entry></feed>
