<?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-806077456733837244</id><updated>2012-02-07T01:18:55.533+11:00</updated><category term='wikileaks'/><category term='logging'/><category term='scala'/><category term='java'/><category term='ceylon'/><category term='apple'/><category term='politics'/><category term='programming'/><category term='applicative functor'/><category term='monad'/><category term='ipad'/><category term='climate change'/><category term='evolution'/><category term='exceptions'/><category term='cocoa'/><category term='speculation'/><category term='objective-c'/><category term='scalaz'/><category term='euler'/><category term='software'/><category term='functional'/><category term='haskell'/><category term='mac'/><category term='religion'/><category term='closures'/><category term='rant'/><category term='flameage'/><title type='text'>Lachlan's Rambling</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://lachlanrambling.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://lachlanrambling.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Lachlan</name><uri>http://www.blogger.com/profile/13336649267304857235</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://static.flickr.com/42/83673461_67524e41a3_m.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>19</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-806077456733837244.post-1306220199606583342</id><published>2012-02-07T01:18:00.001+11:00</published><updated>2012-02-07T01:18:55.537+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='climate change'/><title type='text'>Why I'm a Climate Skeptic</title><content type='html'>&lt;div class='posterous_autopost'&gt;&lt;p&gt;I&amp;rsquo;m going to attempt to explain my position on climate change, mostly for my own benefit, perhaps. The controversial and divisive nature of the climate change debate means that a staggering amount is written about it on a daily basis. What can an amateur like me hope to contribute that hasn&amp;rsquo;t been better covered elsewhere? I shall attempt to offer a useful perspective. But doing this right means doing it long, so sorry about that.&lt;/p&gt;  &lt;h2&gt;My Road to &amp;ldquo;Denial&amp;rdquo;&lt;/h2&gt;  &lt;p&gt;For most of my adult life, I have believed that human pollution of the atmosphere was causing destructive changes to the climate, and that this would lead to catastrophe if we didn&amp;rsquo;t mend our ways. I know I learnt about the greenhouse effect, and that anthropogenic CO₂ was making it stronger, in high school; no later than 1989, when I was 16. I recall playing the original &lt;em&gt;Civilization&lt;/em&gt; PC game in circa 1991. In the late stages of the game, when industrialisation was in full swing, the planet would start heating up, resulting in some areas becoming deserts and others jungles. By adopting “low pollution” technologies, the climate change impacts could be reduced, but not entirely avoided.&lt;/p&gt;  &lt;p&gt;I read Ben Elton&amp;rsquo;s books. I listened to what Greenpeace was saying. For a time I was a member of the Australian Democrats, who were the Greens before there were Greens. When I saw &lt;em&gt;An Inconvenient Truth&lt;/em&gt; in 2005, I was thoroughly impressed, and – this is very embarrassing – considered buying a Prius.   In the 2007 Australian federal election I voted Green and looked forward to the new Labor government finally doing something about climate change.&lt;/p&gt;  &lt;p&gt;In other words, I was a Believer, someone who supported the environmentalist agenda. But not any more. I have actually surprised myself at how rapidly my views changed. I have seriously wondered: am I a total flake, lacking in any real conviction? I report, you decide.&lt;/p&gt;  &lt;p&gt;My first break with environmental orthodoxy was when, in my capacity as an amateur science geek, I started reading about how nuclear power plants actually worked, in detail. It didn&amp;rsquo;t take very long to figure out that almost everything environmentalists said about nuclear power and radiation was complete garbage. Most nuclear advocates also push the consensus line on climate change, as they see it as an opportunity to resuscitate the industry in the west. But I found there were some people advocating nuclear power while also expressing skepticism of climate change claims. That seemed weird.&lt;/p&gt;  &lt;p&gt;I was perplexed that the reality of Anthropogenic Global Warming (AGW) was not universally accepted. I started wondering what the skeptics were actually skeptical of. Did they doubt the planet was warming, or merely the influence of humans? I decided I needed to fully understand the skeptical arguments to better counter them. What I discovered was that the skeptical &amp;ldquo;side&amp;rdquo; actually consists of a somewhat maddening diversity of opinions regarding exactly which aspects of the consensus are wrong. The consensus side, by comparison, was remarkably uniform in its position.&lt;/p&gt;  &lt;p&gt;For a layperson, getting into the contentious scientific issues of climate change is not at all easy. You&amp;rsquo;ll find arguments and counter-arguments over virtually everything, and it&amp;rsquo;s not easy to tell what is important and what can be ignored. The IPCC reports themselves are almost completely useless for gaining any understanding of the issues. I had expected that the reports were designed to inform the policy debate. But no, they&amp;rsquo;re purely technocratic &amp;ndash; written by experts, for experts. The best approach I&amp;rsquo;ve found is to listen to what experts say the IPCC report says, then confirm that myself as well as I can.&lt;/p&gt;  &lt;p&gt;Eventually, I was able to figure out what the skeptical case is mainly all about. The first thing to understand is that there is relatively little skepticism of AGW itself. Most skeptics accept that the evidence for AGW is strong, and that its very likely real. The skepticism is about the magnitude of the anthropogenic influence, and whether we are facing a catastrophe. A more accurate label for &amp;ldquo;Climate change skeptics&amp;rdquo; would &amp;ldquo;climate catastrophe skeptics&amp;rdquo;. No one (fringe religious nuts excluded) is denying that the climate is changing. One of the central planks of the skeptical argument is that the climate is always changing, and we should not necessarily be concerned when we observe this.&lt;/p&gt;  &lt;p&gt;The basic argument for AGW goes like this:&lt;/p&gt;  &lt;ol&gt; &lt;li&gt;The average temperature of the planet has increased since circa 1940&lt;/li&gt; &lt;li&gt;Anthropogenic CO₂ emissions have risen steadily since circa 1940&lt;/li&gt; &lt;li&gt;Adding atmospheric CO₂ makes the greenhouse effect stronger, which makes the planet warmer&lt;/li&gt; &lt;li&gt;Ergo, anthropogenic CO₂ emissions are warming the planet&lt;/li&gt; &lt;/ol&gt;   &lt;p&gt;When a consensus person is impressing you with the strength of their evidence, they are usually supporting the above points. And when they ridicule the &amp;ldquo;denial&amp;rdquo; of science by skeptics, they are usually saying that skeptics deny the above. The thing is that most skeptics &lt;em&gt;accept&lt;/em&gt; the above points. Now, there are valid scientific debates about each of these items, believe it or not. It&amp;rsquo;s not all completely settled. But overall, there seems to be agreement across both skeptics and warmists that the above points have pretty solid evidence to support them. Skeptics &lt;em&gt;have&lt;/em&gt; spent much effort trying to show that point 1 is not as strong as we&amp;rsquo;ve been led to believe; but while there is undoubtedly problems with the instrumental temperature record, the bottom line conclusion seems to have held up.&lt;/p&gt;  &lt;p&gt;So, it&amp;rsquo;s case-closed? Shut down &lt;a href="http://en.wikipedia.org/wiki/Hazelwood_Power_Station"&gt;Hazelwood&lt;/a&gt; and cover the land in wind farms, right? No, it&amp;rsquo;s no where near that simple. We have a huge, genuinely incontrovertible, mass of evidence that the earth&amp;rsquo;s climate changes all the time, all by itself, without any human influence. Of course, whatever natural climate effects were present in the past didn&amp;rsquo;t just disappear when humans started burning coal, oil and gas. So &lt;em&gt;all&lt;/em&gt; the climate observations we make involve some combination of natural and anthropogenic influence (&amp;ldquo;forcings&amp;rdquo; in the lingo). In order to know what we&amp;rsquo;re actually dealing with, we need to understand the strength of the natural vs the anthropogenic forcings. This is called &lt;em&gt;attribution&lt;/em&gt;, and this is where it gets really messy.&lt;/p&gt;  &lt;p&gt;It&amp;rsquo;s when I started looking into attribution that started doubting the consensus position. There&amp;rsquo;s a bunch of details involved that seemed very important and relevant to me, but that I&amp;rsquo;d never heard any environmentalist, greenie or consensus scientist even hint at. First thing: the greenhouse warming from CO₂ is logarithmic. This means that as CO₂ is added to the atmosphere, the impact of adding more CO₂ becomes less and less. The standard analogy is to think about painting over a window: the first coat blocks a lot of light, the second coat blocks less light, and so on. Now, I don&amp;rsquo;t want to over-emphasise the importance of this – the IPCC fully takes it into account – but it was a shock to me because I realised I didn&amp;rsquo;t really understand the fundamentals of AGW. My diet of environmentalist propaganda had led me to believe that all those megatons of CO₂ were going to cause Venus-like runaway warming. Nope.&lt;/p&gt;  &lt;p&gt;Next surprise: the &lt;a href="http://en.wikipedia.org/wiki/Ice_core"&gt;ice cores&lt;/a&gt;. I can only recall one slide in Al Gore&amp;rsquo;s entire presentation that dealt with attribution: the slide showing the temperature and CO₂ graphs from ice core data. He then said:&lt;/p&gt;  &lt;blockquote class="posterous_medium_quote"&gt;&lt;p&gt;The relationship is actually very complicated but there is one relationship that is far more powerful than all the others and it is this. When there is more carbon dioxide, the temperature gets warmer, because it traps more heat from the sun inside.&lt;/p&gt;&lt;/blockquote&gt;  &lt;p&gt;And indeed the graphs on the slide show a very close correlation between CO₂ and temperature. But I learned that Mr Gore was deliberately misleading his audience with this slide. What did he mean when he said the relationship is &amp;ldquo;very complicated&amp;rdquo;? Well, what the ice cores actually show is temperature increases happen roughly 800 years &lt;em&gt;before&lt;/em&gt; increases in the CO₂ level. This is not mysterious, it&amp;rsquo;s basic physics that as the oceans warm up they will release more of their dissolved CO₂ into the atmosphere. So it&amp;rsquo;s actually not that &amp;ldquo;complicated&amp;rdquo;, Mr Gore just didn&amp;rsquo;t feel like explaining it.&lt;/p&gt;  &lt;p&gt;The ice cores were once one of the best pieces of evidence that CO₂ had a strong influence on temperature. Initially the resolution of samples was not so high, and it did indeed appear that CO₂ and temperature increased together. Then scientists were able to improve the resolution and see that temperature changed before CO₂. The consensus now tries to act like this was totally expected. The claim now is that the planet starts warming (due to a cause we can only speculate about), this causes more CO₂ to enter the atmosphere, which then amplifies the warming (this is somehow not speculation). I find the best way to evaluate claims like this is to imagine if the result had come out the other way; if the cores had shown temperature increasing after CO₂, do you think they would say &amp;ldquo;oh, we didn&amp;rsquo;t predict that!&amp;rdquo; Of course not, it would be (with some justification) trumpeted as evidence of CO₂ being a major driver of climate change. The ice core data presents other problems for theories of CO₂-driven climate catastrophe: despite the &amp;ldquo;amplification&amp;rdquo; going on, the warming somehow stops long before anything catastrophic happens. And when the temperature falls, CO₂ levels stay high for over a thousand years. A far simpler explanation for the ice core data is that CO₂ levels respond slowly to temperature changes, but do not significantly drive temperature changes.&lt;/p&gt;  &lt;h2&gt;Sensitivity and Feedbacks&lt;/h2&gt;  &lt;p&gt;Next shock: when it comes to the total greenhouse effect of the earth, CO₂ is only a minor contributor. The most significant player is water vapour, by quite a margin. So how exactly does CO₂ act as the climate bogey-man? (Someone familiar with climate science might say &amp;ldquo;&lt;em&gt;duh&lt;/em&gt;, climate scientists have always acknowledged the importance of water&amp;rdquo;. That is so, but I had listened to a lot of alarmists and never heard it mentioned.)&lt;/p&gt;  &lt;p&gt;At this point, I have to introduce the notion of &lt;em&gt;climate sensitivity&lt;/em&gt;. This is not a thing that is part of the physics of the climate, it&amp;rsquo;s basically a rough measure of how much warming we get from increasing CO₂ levels. For laypeople who are mainly interested in policy implications, the sensitivity is usually expressed as the temperature increase caused by doubling CO₂, both relative to pre-industrial levels (the doubling will occur circa 2070 assuming current trends). The last IPCC report says the climate sensitivity is probably 3.3℃, but the range of possible values is 2.0℃ to 4.5℃. The skeptics think it is significantly lower. If you want the science of the climate change debate boiled down to its essence, it is the determination of this value.&lt;/p&gt;  &lt;p&gt;Now, it turns out we can use laboratory experiments to work out a reasonably accurate (for climate science) value for how much warming we get from adding CO₂. A climate sensitivity of around 1.2℃ from CO₂ warming alone is widely accepted by both warmists and skeptics. Huh? That&amp;rsquo;s a lot less than 3.3℃.&lt;/p&gt;  &lt;p&gt;The discrepancy is because the lab experiments measure the CO₂ effect in isolation, but in the real climate all forcings like this are subject to feedbacks. We know of the existence of many feedbacks, both positive and negative, in the climate system. The problem is we have very little idea of how strong any of them are compared to the others. One of the major feedback components is water vapour in the atmosphere. The IPCC says that when increased CO₂ levels make the planet slightly warmer, this causes the atmosphere to hold more water vapour. Water vapour is the strongest greenhouse gas, so the earth gets even warmer. Of course, I&amp;rsquo;m leaving out a huge amount of detail in all this, much of which I don&amp;rsquo;t completely understand. But I think it&amp;rsquo;s correct to say that water vapour feedback constitutes the bulk of the warming the IPCC says we&amp;rsquo;ll get beyond the 1.2℃ direct forcing.&lt;/p&gt;  &lt;p&gt;I just want to take a quick aside to emphasise how completely, utterly, totally bogus it is to refer to CO₂ (or even worse, &amp;ldquo;carbon&amp;rdquo;) as &amp;ldquo;pollution&amp;rdquo;. If you accept the argument that the mere fact it&amp;rsquo;s possible to accumulate too much of something means it should be called a pollutant, then you have to be consistent. Most of the warming the IPCC predicts comes not from CO₂, but H₂O. Therefore, &lt;em&gt;water&lt;/em&gt; is a pollutant, and a more significant one than &amp;ldquo;carbon&amp;rdquo;. &lt;em&gt;Reductio ad absurdum&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;The big issue with water vapour in the atmosphere is that it will sometimes form clouds. Clouds can both warm and cool the earth&amp;rsquo;s surface. This means that adding water vapour to the atmosphere produces both positive and negative feedbacks. I think it&amp;rsquo;s fair to say that there&amp;rsquo;s few aspects of the climate that we understand less well than clouds. The bottom line is we can only speculate about what the net water vapour feedback is. We can&amp;rsquo;t even say with any certainty whether the feedback is negative or positive overall.&lt;/p&gt;  &lt;p&gt;So in order to know what the climate sensitivity is, we need to know how the feedbacks work. But we don&amp;rsquo;t know that, so we use various means to try to estimate the likely range. I think you can pick any value for the climate sensitivity between 0℃ and 6℃ and you&amp;rsquo;ll be able to find one or more peer-reviewed scientific papers that say that could be the value. The IPCC&amp;rsquo;s estimate of 2.0℃ to 4.5℃ seems to have been arrived at almost entirely via modelling. This range requires net feedbacks to be positive.&lt;/p&gt;  &lt;p&gt;The sign and magnitude of the feedbacks is the difference between major catastrophe and an effect so small it cannot be noticed against natural variation. But the direct empirical evidence for a net strong positive feedback is virtually non-existent. Models, combined with the argument &amp;ldquo;we know of no other cause of 20th century warming&amp;rdquo; (I&amp;rsquo;m not making that up, &lt;a href="http://news.bbc.co.uk/2/hi/science/nature/8511670.stm"&gt;they actually say that&lt;/a&gt;) are all that supports it.&lt;/p&gt;  &lt;p&gt;On the other hand, there are increasingly good reasons to think the net feedback is slightly negative. For one, almost all natural systems that have reached a stable or meta-stable state are governed by negative feedback. The fact that the earth&amp;rsquo;s climate doesn&amp;rsquo;t constantly careen from one extreme state to the next indicates that negative feedback probably dominates (it&amp;rsquo;s also worth noting another factoid never spoken of by the consensus – over the entire history of the earth, today&amp;rsquo;s CO₂ levels are relatively low). And there&amp;rsquo;s the fact that the warming predicted is just not eventuating. For over ten years now, the various temperature records, surface, satellite, ocean, have all been &lt;em&gt;flat&lt;/em&gt;. All while CO₂ levels have continued to rise.&lt;/p&gt;  &lt;p&gt;The way the consensus is sold is by focusing entirely on the strong part of their theory – that human CO₂ emissions make the planet slightly warmer. But the chain of reasoning should be judged by the weakest link, which is that the warming will be catastrophic due to positive feedback.&lt;/p&gt;  &lt;h2&gt;Climate Models&lt;/h2&gt;  &lt;p&gt;Climate models are just computer programs. I don&amp;rsquo;t pretend to understand all the details of how they work, but I will attempt to give a fair summary. They are written to simulate what we know and what we think we know about the physics of the earth&amp;rsquo;s climate. They take into account all known climate forcings (solar activity for example) and all known feedback mechanisms. You end up with a big pile of parameters in the model, the values of which cannot be determined by observation with any great certainty. These parameters are set by a combination of simple assumption, combined with tuning the output of the model to match certain historical records. The IPCC (ok, not them directly, the scientists whose papers they rely on) then re-run the models with anthropogenic CO₂ left out, find that the results don&amp;rsquo;t match history, and from this conclude that their assumptions of positive feedback are correct and that CO₂ is the main driver of global warming. And this is how the value for climate sensitivity is arrived at &amp;ndash; the models say that earth with CO₂ doubled is 3.3℃ warmer than earth with CO₂ unchanged.&lt;/p&gt;  &lt;p&gt;You may be thinking that I&amp;rsquo;m either lying or mistaken here, because that sounds &lt;em&gt;completely bloody crazy&lt;/em&gt;. It&amp;rsquo;s simply begging the question. Well I&amp;rsquo;m not lying, but I could be mistaken. Take a look at the critical IPCC chapter on attribution, especially &lt;a href="http://www.ipcc.ch/publications_and_data/ar4/wg1/en/faq-9-2.html"&gt;pp 702-703&lt;/a&gt; and decide for yourself if I&amp;rsquo;m being fair.&lt;/p&gt;  &lt;p&gt;I haven&amp;rsquo;t yet heard a convincing argument as to why using models like this is evidence of anything. A telling sentence on page 702 referenced above is &amp;ldquo;Numerous experiments have been conducted using climate models to determine the likely causes of the 20th-century climate change&amp;rdquo;. The word &amp;ldquo;experiments&amp;rdquo; here is quite misleading, as in the scientific context it implies you&amp;rsquo;re doing something empirical. But all climate models do is answer the question &amp;ldquo;if I assume the climate works like this, what are the implications?&amp;rdquo; This is undoubtedly useful, but it can&amp;rsquo;t tell you if the assumptions you start with are correct. Model outputs are not observations.&lt;/p&gt;  &lt;p&gt;But if the climate model produces results that match real-world historical data, doesn&amp;rsquo;t that prove the model&amp;rsquo;s assumptions are basically valid? No. A quote from John von Neumann sums it up: &amp;ldquo;With four parameters I can fit an elephant, and with five I can make him wiggle his trunk.&amp;rdquo; Climate models have many parameters. Like the relative strengths of various feedbacks. But the models also need to account for periods where CO₂ rose and temperatures fell (the 1970s for example). That&amp;rsquo;s where some of the negative temperature forcings come into play, the principle one being &amp;ldquo;aerosols&amp;rdquo;, which are mainly genuine pollutants like sulphates. We know that aerosols make the earth cooler overall (sometimes called &amp;ldquo;global dimming&amp;rdquo;) but, again, there&amp;rsquo;s huge uncertainty as to the strength of the effect. Because various positive and negative parameters are so poorly constrained by observation, it&amp;rsquo;s just a matter of tuning them until your model roughly matches the real-world data. The IPCC uses many climate models, each with different assumptions and producing slightly different future &amp;ldquo;scenarios&amp;rdquo;. Obviously they can&amp;rsquo;t all be correct, but they all match historical data to roughly the same degree.&lt;/p&gt;  &lt;h2&gt;The Bottom Line&lt;/h2&gt;  &lt;p&gt;The heart of the scientific debate about climate change is the issue of attribution. It is a real debate, concerned with real evidence. It is simply not true that the only people not going along with the consensus are few science-denying fools or paid shills for the fossil fuel industry. I didn&amp;rsquo;t learn about these issues on my own, there&amp;rsquo;s a great many knowledgable people who have come to doubt what climate change activists and the IPCC are telling us. There are very good reasons to doubt the consensus claim that almost all 20th century warming can be attributed to anthropogenic influence.&lt;/p&gt;  &lt;p&gt;What should we do? Well, we can&amp;rsquo;t decide on a policy based on climate science alone, we have to examine the available options and their costs. That&amp;rsquo;s a whole new rabbit hole, so I won&amp;rsquo;t get into it now.&lt;/p&gt;  &lt;p&gt;I would, however, like to address some of the common comebacks to the type of argument I&amp;rsquo;ve laid out above. When doubts about the consensus scientific position are raised, usually only professional scientists understand the details will go into bat and defend it. But most people who are advocating &amp;ldquo;action&amp;rdquo; on climate change aren&amp;rsquo;t really able to do this. Instead, it&amp;rsquo;s amazing how quickly they will declare the truth of climate science claims as basically irrelevant because of some other overriding reason.&lt;/p&gt;  &lt;h2&gt;1. We Should Look After the Environment&lt;/h2&gt;  &lt;p&gt;&amp;ldquo;It doesn&amp;rsquo;t matter if climate change science is wrong, because we have to look after the environment anyway&amp;rdquo;. This argument is actually at the heart of the climate change hysteria. Whenever the catastrophic climate change barrow is pushed, it is invariably linked to pollution and environmental problems generally. But our very real environmental challenges are not causing climate change, nor are they caused by it. Emissions from cars and coal power stations certainly are dirty and can cause environmental problems, but it&amp;rsquo;s not the dirty or toxic stuff that makes the greenhouse effect stronger. Neither do oil spills or the myriad of other ways we manage to screw things up. Whatever the merits are of the clean-up-the-planet argument are, it is a separate issue to what&amp;rsquo;s going on with the greenhouse effect. Alarming people with tales of climatic disaster is not an honest way to pursue a clean air agenda.&lt;/p&gt;  &lt;p&gt;Australia&amp;rsquo;s &amp;ldquo;Carbon Price&amp;rdquo; is sold as the means to a &amp;ldquo;clean energy future&amp;rdquo;. So with all the nasty things emitted by fossil fuel combustion (there are many), we put a price on an emission that is not dirty or toxic, and was abundant throughout the biosphere before the first human drew breath. Yeah, that totally makes sense as a clean air policy.&lt;/p&gt;  &lt;p&gt;Just a quick note on something you&amp;rsquo;ve probably heard about: that increasing CO₂ levels are making the oceans &amp;ldquo;more acidic&amp;rdquo;. The scare mongering about ocean acidification is stopped in its tracks by the elementary observation that the average pH of the oceans is about 8.14. That&amp;rsquo;s right, the world&amp;rsquo;s oceans are &lt;em&gt;alkaline&lt;/em&gt;. So while it&amp;rsquo;s technically correct that increased CO₂ has made the oceans more acidic, it&amp;rsquo;s quite misleading. It&amp;rsquo;s more honest to say that the oceans are becoming more neutral, that is, &lt;em&gt;less&lt;/em&gt; corrosive. Claims about the dangers of ocean acidification are just another desperate attempt to make CO₂ into a dangerous pollutant.&lt;/p&gt;  &lt;h2&gt;2. Fossil Fuels are Bad&lt;/h2&gt;  &lt;p&gt;Related to the previous argument, there is the &amp;ldquo;it doesn&amp;rsquo;t matter if climate change science is wrong, because fossil fuels are bad and we should stop using them&amp;rdquo;. There are indeed plenty of downsides to fossil fuels (and some major upsides too). However, this is again a separate debate from climate change. The various carbon pricing and emission reduction schemes were not sold on the basis that fossil fuels have downsides, they were sold based on predictions of drowned coastlines, dead coral reefs and endless droughts. If you want to make the argument for the negatives of fossil fuels, then make the argument on its own merits, don&amp;rsquo;t try to force your agenda with scare tactics about the climate. Oh and having a remotely practical alternative might help, too.&lt;/p&gt;  &lt;h2&gt;3. Idiots whom I hate are climate change skeptics&lt;/h2&gt;  &lt;p&gt;I&amp;rsquo;ve been really surprised how often I&amp;rsquo;ve heard some variation of this: &amp;ldquo;I can&amp;rsquo;t be a climate skeptic, because that would mean agreeing with: Tony Abbott, Andrew Bolt, Glenn Beck, assorted conservative religious nuts, et alia&amp;rdquo;. I have to admit that I have fallen victim to this line of &amp;ldquo;reasoning&amp;rdquo; myself in the past, and now do my best to guard against it. Forming your opinion on a matter based on the opinions of people you don&amp;rsquo;t respect is manifestly stupid. Need I say more?&lt;/p&gt;  &lt;h2&gt;4. We should act as a precaution&lt;/h2&gt;  &lt;p&gt;The argument goes: &amp;ldquo;because we can&amp;rsquo;t definitively prove that anthropogenic emissions are not going to destroy the world, we should play it safe and cut emissions&amp;rdquo;. This will often be backed up with some demagogic nonsense such as &amp;ldquo;we should not gamble with our children&amp;rsquo;s future&amp;rdquo;. The flaw in this argument becomes obvious when it is applied to an issue other than climate change: &amp;ldquo;because we can&amp;rsquo;t definitively prove that an asteroid is not going to destroy the world, we should play it safe and spend trillions of dollars on an asteroid defence system&amp;rdquo;.&lt;/p&gt;  &lt;p&gt;A another deliciously silly argument I&amp;rsquo;ve often seen attached to this is that the &amp;ldquo;only&amp;rdquo; cost of such precautionary action is money. Right. Money. The thing we use to represent our available resources. The resources we use to sustain, grow and advance our civilisation. Oh, if that&amp;rsquo;s the only cost, I don&amp;rsquo;t know what all the fuss is about. The best part is that if you ask the person making this argument &amp;ldquo;should we spend more on education/health care/social justice/foreign aid/anything except defence&amp;rdquo;, they&amp;rsquo;ll say &amp;ldquo;yes&amp;rdquo; to every one without a hint of irony.&lt;/p&gt;  &lt;p&gt;What&amp;rsquo;s lacking here is any assessment of risk and cost. Most environmentalists seem to avoid getting into any hard numbers concerning risk and cost, likely because their ideas do not come out well. That&amp;rsquo;s a topic for another post, however.&lt;/p&gt;      &lt;p style="font-size: 10px;"&gt;      &lt;a href="http://posterous.com"&gt;Posted via email&lt;/a&gt;       from &lt;a href="http://lockster.posterous.com/why-im-a-climate-skeptic"&gt;lockster's posterous&lt;/a&gt;      &lt;/p&gt;      &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/806077456733837244-1306220199606583342?l=lachlanrambling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lachlanrambling.blogspot.com/feeds/1306220199606583342/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=806077456733837244&amp;postID=1306220199606583342' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/1306220199606583342'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/1306220199606583342'/><link rel='alternate' type='text/html' href='http://lachlanrambling.blogspot.com/2012/02/why-i-climate-skeptic.html' title='Why I&amp;#39;m a Climate Skeptic'/><author><name>Lachlan</name><uri>http://www.blogger.com/profile/13336649267304857235</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://static.flickr.com/42/83673461_67524e41a3_m.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-806077456733837244.post-920214421990174547</id><published>2011-09-02T12:32:00.001+10:00</published><updated>2011-09-02T12:32:08.658+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='monad'/><category scheme='http://www.blogger.com/atom/ns#' term='scalaz'/><category scheme='http://www.blogger.com/atom/ns#' term='applicative functor'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Applying Applicative Functors in Scala</title><content type='html'>&lt;div class='posterous_autopost'&gt;&lt;p&gt;A chap named ittayd has written a nice &lt;a href="http://www.tikalk.com/incubator/blog/functional-programming-scala-rest-us"&gt;gentle tutorial on functional programming in Scala&lt;/a&gt;. My only minor complaint is that he calls the applicative functor &amp;ldquo;sequential application&amp;rdquo; function &lt;code&gt;apply&lt;/code&gt;. While this is a logical choice, in Scala &lt;code&gt;apply&lt;/code&gt; is used everywhere to implement plain old function application, so it could lead to confusion. I think it&amp;rsquo;s better to call it &lt;code&gt;&amp;lt;*&amp;gt;&lt;/code&gt;, as in Haskell. Read on.&lt;/p&gt;  &lt;p&gt;I found the tutorial interesting because it talks a bit about applicative functors, and how to give them a nice syntax in Scala. The one thing that has bugged me about applicatives is that using them in Scala always felt clunkier than Haskell. Ittayd comes up with a scheme I like, but says &amp;ldquo;we have one difficulty: we can no longer define apply inside Future&amp;rdquo;. He uses a standard object-pimping implicit conversion to get around this, and that works fine. However, it &lt;em&gt;is&lt;/em&gt; possible to define &lt;code&gt;&amp;lt;*&amp;gt;&lt;/code&gt; inside your thing-with-an-applicative-functor, using one of my favourite Scala features: &lt;a href="http://stackoverflow.com/questions/3427345/what-do-and-mean-in-scala-2-8-and-where-are-they-documented/3427759#3427759"&gt;generalized type constraints&lt;/a&gt;. To continue with ittayd&amp;rsquo;s example using &lt;code&gt;Future&lt;/code&gt;:&lt;/p&gt;  &lt;div class="CodeRay"&gt; &lt;div class="code"&gt;&lt;pre&gt;trait Future[A] { … def &amp;lt;*&amp;gt;[X, Y](x: Future[X])(implicit ev: A &amp;lt;:&amp;lt; (X =&amp;gt; Y)) = new Future[Y] { def get = Future.this.get(x.get) def isDone = Future.this.isDone &amp;amp;&amp;amp; x.isDone } }&lt;/pre&gt;&lt;/div&gt; &lt;/div&gt;   &lt;p&gt;The compiler will only allow &lt;code&gt;&amp;lt;*&amp;gt;&lt;/code&gt; to be called on a &lt;code&gt;Future&lt;/code&gt; that provides an appropriate function as its value.&lt;/p&gt;  &lt;p&gt;Ittayd bootstraps things simply by lifting the function to be applied into &lt;code&gt;Future&lt;/code&gt;, but personally I prefer the Haskell style of using &lt;code&gt;&amp;lt;$&amp;gt;&lt;/code&gt;, aka &amp;ldquo;map&amp;rdquo;. In Scala, &lt;code&gt;&amp;lt;$&amp;gt;&lt;/code&gt; is unsuitable for a few reasons, so I picked &lt;code&gt;**:&lt;/code&gt;:&lt;/p&gt;  &lt;div class="CodeRay"&gt; &lt;div class="code"&gt;&lt;pre&gt;trait Future[A] { … def **:[B](f: A =&amp;gt; B): Future[B] = map(f) }&lt;/pre&gt;&lt;/div&gt; &lt;/div&gt;   &lt;p&gt;Obviously, this is just the standard &lt;code&gt;map&lt;/code&gt; method with a different name, what&amp;rsquo;s the point? Well, because the operator ends with a :, it&amp;rsquo;s right associative; and because it starts with an *, it has higher precedence than &lt;code&gt;&amp;lt;*&amp;gt;&lt;/code&gt;; so you end up with:&lt;/p&gt;  &lt;div class="CodeRay"&gt; &lt;div class="code"&gt;&lt;pre&gt;(marry _).curried **: joe &amp;lt;*&amp;gt; jane&lt;/pre&gt;&lt;/div&gt; &lt;/div&gt;   &lt;p&gt;Or, if you subscribe to the slippery slope theory of gay marriage:&lt;/p&gt;  &lt;div class="CodeRay"&gt; &lt;div class="code"&gt;&lt;pre&gt;(gayMarry _).curried **: joe &amp;lt;*&amp;gt; bob &amp;lt;*&amp;gt; george &amp;lt;*&amp;gt; fido &amp;lt;*&amp;gt; aDonkey&lt;/pre&gt;&lt;/div&gt; &lt;/div&gt;   &lt;p&gt;This is reasonably close to the Haskell idiom:&lt;/p&gt;  &lt;div class="CodeRay"&gt; &lt;div class="code"&gt;&lt;pre&gt;gayMarry &amp;lt;$&amp;gt; joe &amp;lt;*&amp;gt; bob &amp;lt;*&amp;gt; george &amp;lt;*&amp;gt; fido &amp;lt;*&amp;gt; aDonkey&lt;/pre&gt;&lt;/div&gt; &lt;/div&gt;   &lt;p&gt;You may wonder why obsess over the best way of dealing with applicative functors? After all, most of the applicative functors you see have an associated monad, so we can use Scala&amp;rsquo;s nice &lt;code&gt;for&lt;/code&gt; syntax. Yes this is true for many useful applicative functors, but not all of them.&lt;/p&gt;  &lt;p&gt;Just a quick asside on termonology. In casual conversation, you may hear it said that &amp;ldquo;Option is a monad&amp;rdquo;. But it&amp;rsquo;s more accurate to say &amp;ldquo;Option &lt;em&gt;has&lt;/em&gt; a monad&amp;rdquo;. Because many types only have one useful monad associated with them, we tend to think that the type itself is the monad, but that&amp;rsquo;s not quite right. This doesn&amp;rsquo;t just apply to monads, of course, the same goes for monoids, applicative functors, etc. For example, numeric types have two useful monoids: one for addition and one for multiplication.&lt;/p&gt;  &lt;p&gt;Now consider a Validation type from &lt;a href="http://dl.dropbox.com/u/7810909/docs/applicative-errors-scala/chunk-html/index.html"&gt;this Tony Morris tutorial&lt;/a&gt;. You can write a useful monad for this type, which implies an applicative functor as well. However, the tutorial is concerned with a &lt;em&gt;second&lt;/em&gt; useful applicative functor for Validation. This second applicative is only relevant for the case where the Validation is using a semigroup as its error type (the tutorial explains what a semigroup is), and it allows using the semigroup to accumulate a list of all the validation failures. The classic example of this is validating data entered by a user on a form with several fields. The &amp;ldquo;plain&amp;rdquo; applicative/monad will only record the first validation failure it finds, whereas the semigroup applicative will record all the failures.&lt;/p&gt;  &lt;p&gt;Now, finally, to my point (I think). This applicative functor that uses semigroup does not have a corresponding monad. Which means that we can&amp;rsquo;t use it with Scala&amp;rsquo;s &lt;code&gt;for&lt;/code&gt; syntax. Hence the desire for a nice syntax for applicative functors. It is most definitely useful.&lt;/p&gt;  &lt;p&gt;Obligatory &lt;a href="http://code.google.com/p/scalaz/"&gt;Scalaz&lt;/a&gt; reference: those guys have pretty much worked out the best way to do all this stuff in Scala. But I find I learn a lot by experimenting myself.&lt;/p&gt;      &lt;p style="font-size: 10px;"&gt;      &lt;a href="http://posterous.com"&gt;Posted via email&lt;/a&gt;       from &lt;a href="http://lockster.posterous.com/applying-applicative-functors-in-scala"&gt;lockster's posterous&lt;/a&gt;      &lt;/p&gt;      &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/806077456733837244-920214421990174547?l=lachlanrambling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lachlanrambling.blogspot.com/feeds/920214421990174547/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=806077456733837244&amp;postID=920214421990174547' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/920214421990174547'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/920214421990174547'/><link rel='alternate' type='text/html' href='http://lachlanrambling.blogspot.com/2011/09/applying-applicative-functors-in-scala.html' title='Applying Applicative Functors in Scala'/><author><name>Lachlan</name><uri>http://www.blogger.com/profile/13336649267304857235</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://static.flickr.com/42/83673461_67524e41a3_m.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-806077456733837244.post-735016230524907551</id><published>2011-05-03T23:23:00.001+10:00</published><updated>2011-05-03T23:23:37.366+10:00</updated><title type='text'>A variation on Scala's Either type</title><content type='html'>&lt;div class='posterous_autopost'&gt;&lt;p&gt;I&amp;rsquo;ve been using Scala&amp;rsquo;s &lt;code&gt;Either&lt;/code&gt; type a bit recently, and found a couple of minor annoyances with it. So as a learning exercise I tried to make a variation of &lt;code&gt;Either&lt;/code&gt;, and this is what I came up with. I also wanted to experiment with syntax a little. See what you think.&lt;/p&gt;  &lt;p&gt;&lt;code&gt;Either&lt;/code&gt; is a disjunctive type with two possible values: a &lt;em&gt;left&lt;/em&gt; and a &lt;em&gt;right&lt;/em&gt;. It places no meaning at all on left or right, but 99% of its uses in practice involve putting normal, expected values in right, and errors or other &amp;ldquo;exceptional&amp;rdquo; values in left. This means that almost all the time you end up getting the &lt;code&gt;RightProjection&lt;/code&gt;, e.g.:&lt;/p&gt;  &lt;div class="CodeRay"&gt; &lt;div class="code"&gt;&lt;pre&gt;for { v1 &amp;lt;- foo(…).right v2 &amp;lt;- bar(…).right v3 &amp;lt;- baz(…).right } yield …&lt;/pre&gt;&lt;/div&gt; &lt;/div&gt;   &lt;p&gt;Whereas I&amp;rsquo;ve never used &lt;code&gt;.left&lt;/code&gt; even once.&lt;/p&gt;  &lt;p&gt;The second minor issue is that Either has some limitations with patterns in &lt;code&gt;for&lt;/code&gt; expressions, because of how it is forced to implement the &lt;code&gt;filter&lt;/code&gt; method. See &lt;a href="http://stackoverflow.com/questions/5831453/why-does-this-scala-for-expression-using-tuples-fail-to-compile"&gt;this Stack Overflow question&lt;/a&gt; for the details.&lt;/p&gt;  &lt;p&gt;So I created a type that is explicitly designed to handle the possibility of &amp;ldquo;exception&amp;rdquo; conditions. Because the word &amp;ldquo;exception&amp;rdquo; already has a well known meaning on the JVM, I called this type &lt;em&gt;Anomaly&lt;/em&gt; instead. Actually, I ended up calling the type &lt;code&gt;|:&lt;/code&gt; because I thought it worked nicely syntactically. Here&amp;rsquo;s a comparison with &lt;code&gt;Either&lt;/code&gt;:&lt;/p&gt;  &lt;div class="CodeRay"&gt; &lt;div class="code"&gt;&lt;pre&gt;val e1: Either[String, Int] = Right(30) val e2: Either[String, (Int, Int)] = Right((10, 2)) val e3 = for { i &amp;lt;- e1.right j &amp;lt;- e2.right } yield i + j._1 + j._2 val e4: Either[String, Int] = Left(&amp;quot;error&amp;quot;)&lt;/pre&gt;&lt;/div&gt; &lt;/div&gt;   &lt;p&gt;vs &amp;ldquo;Anomaly&amp;rdquo;:&lt;/p&gt;  &lt;div class="CodeRay"&gt; &lt;div class="code"&gt;&lt;pre&gt;val a1: String |: Int = Expected(30) val a2: String |: (Int, Int) = Expected((10, 2)) val a3 = for { i &amp;lt;- a1 (j, k) &amp;lt;- a2 } yield i + j + k val a4: String |: Int = Anomaly(&amp;quot;error&amp;quot;)&lt;/pre&gt;&lt;/div&gt; &lt;/div&gt;   &lt;p&gt;The &lt;code&gt;|:&lt;/code&gt; operator is right-associative, which helps for the occasional cases where you have an Anomaly within an Anomaly, eg. &lt;code&gt;String |: String |: Int&lt;/code&gt; is equivalent to &lt;code&gt;Either[String, Either[String, Int]]&lt;/code&gt;. Of course, depending on your taste you could reverse the order of type arguments, using an operator like &lt;code&gt;:|&lt;/code&gt;, or use a name instead of an operator.&lt;/p&gt;  &lt;p&gt;There&amp;rsquo;s a cost to making the &lt;code&gt;for&lt;/code&gt; expression pattern matching work like this, however. In addition to the &lt;code&gt;Anomaly&lt;/code&gt; and &lt;code&gt;Expected&lt;/code&gt; cases, I had to introduce a &lt;code&gt;NoValue&lt;/code&gt; case object, which is what is returned when a filter does not match. This is annoying, because now folding or pattern matching must account for three cases instead of two. And unless you have explicit filters or patterns matching particular values, the &lt;code&gt;NoValue&lt;/code&gt; outcome won&amp;rsquo;t come up, so it&amp;rsquo;s a pain to have to check for it. What I ended up doing was providing an alternate two-parameter fold method that calls &lt;code&gt;error&lt;/code&gt; in case of a &lt;code&gt;NoValue&lt;/code&gt;. You just have to be careful about only calling it when you know it&amp;rsquo;s safe.&lt;/p&gt;  &lt;p&gt;All-in-all I&amp;rsquo;m still wondering whether this experiment is worthwhile, but here&amp;rsquo;s the code in case anyone is interested. There are other utility methods that could be added:&lt;/p&gt;  &lt;div class="CodeRay"&gt; &lt;div class="code"&gt;&lt;pre&gt;sealed abstract class |:[+A, +E] { def anomaly: A def expected: E def isExpected: Boolean = false def isAnomaly: Boolean = false def isNoValue: Boolean = false  def map[X](f: E =&amp;gt; X): A |: X  def flatMap[X, AA &amp;gt;: A](f: E =&amp;gt; AA |: X): AA |: X  def withFilter(f: E =&amp;gt; Boolean): A |: E = this final def filter(f: E =&amp;gt; Boolean): A |: E = withFilter(f)  def foreach(f: E =&amp;gt; Unit): Unit = {}  final def fold[X](fExpected: E =&amp;gt; X, fAnomaly: A =&amp;gt; X, fNoValue: =&amp;gt; X): X = this match { case Anomaly(a) =&amp;gt; fAnomaly(a) case Expected(e) =&amp;gt; fExpected(e) case NoValue =&amp;gt; fNoValue }  final def fold[X](fExpected: E =&amp;gt; X, fAnomaly: A =&amp;gt; X): X = this match { case Anomaly(a) =&amp;gt; fAnomaly(a) case Expected(e) =&amp;gt; fExpected(e) case NoValue =&amp;gt; error(&amp;quot;Attempt to fold NoValue case&amp;quot;) }  final def join[X, AA &amp;gt;: A](implicit ev: E &amp;lt;:&amp;lt; (AA |: X)): AA |: X = this match { case Anomaly(a) =&amp;gt; Anomaly(a) case Expected(e) =&amp;gt; e case NoValue =&amp;gt; NoValue } }  final case class Expected[+A, +E](expected: E) extends (A |: E) { override def isExpected = true def anomaly: A = Predef.error(&amp;quot;Not an anomaly&amp;quot;)  override def withFilter(f: E =&amp;gt; Boolean) = if (f(expected)) this else NoValue  def flatMap[X, AA &amp;gt;: A](f: E =&amp;gt; AA |: X) = f(expected)  def map[X](f: E =&amp;gt; X) = Expected[A, X](f(expected))  override def foreach(f: E =&amp;gt; Unit) { f(expected) } }  object Expected { def cond[A, E](test: Boolean, expected: =&amp;gt; E, anomaly: =&amp;gt; A): A |: E = if (test) Expected(expected) else Anomaly(anomaly) }  final case class Anomaly[+A, +E](anomaly: A) extends (A |: E) { override def isAnomaly = true def expected: E = Predef.error(&amp;quot;Not an expected value&amp;quot;)  def flatMap[X, AA &amp;gt;: A](f: E =&amp;gt; AA |: X) = Anomaly[AA, X](anomaly)  def map[X](f: E =&amp;gt; X) = Anomaly[A, X](anomaly) }  object Anomaly { def cond[A, E](test: Boolean, anomaly: =&amp;gt; A, expected: =&amp;gt; E): A |: E = if (test) Anomaly(anomaly) else Expected(expected) }  case object NoValue extends (Nothing |: Nothing) { override def isNoValue = true def anomaly = Predef.error(&amp;quot;Not an anomaly&amp;quot;) def expected = Predef.error(&amp;quot;No value&amp;quot;)  def flatMap[X, AA &amp;gt;: Nothing](f: Nothing =&amp;gt; AA |: X) = this  def map[X](f: Nothing =&amp;gt; X) = this }&lt;/pre&gt;&lt;/div&gt; &lt;/div&gt;      &lt;p style="font-size: 10px;"&gt;      &lt;a href="http://posterous.com"&gt;Posted via email&lt;/a&gt;       from &lt;a href="http://lockster.posterous.com/a-variation-on-scalas-either-type"&gt;lockster's posterous&lt;/a&gt;      &lt;/p&gt;      &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/806077456733837244-735016230524907551?l=lachlanrambling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lachlanrambling.blogspot.com/feeds/735016230524907551/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=806077456733837244&amp;postID=735016230524907551' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/735016230524907551'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/735016230524907551'/><link rel='alternate' type='text/html' href='http://lachlanrambling.blogspot.com/2011/05/variation-on-scala-either-type.html' title='A variation on Scala&amp;#39;s Either type'/><author><name>Lachlan</name><uri>http://www.blogger.com/profile/13336649267304857235</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://static.flickr.com/42/83673461_67524e41a3_m.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-806077456733837244.post-5739607290548687548</id><published>2011-04-15T12:27:00.001+10:00</published><updated>2011-04-15T12:27:21.757+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='ceylon'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><category scheme='http://www.blogger.com/atom/ns#' term='flameage'/><title type='text'>Ceylon: Interesting for the Wrong Reasons</title><content type='html'>&lt;div class='posterous_autopost'&gt;&lt;p&gt;A couple of days ago, Gavin King announced that he is leading a team at RedHat that&amp;rsquo;s creating a new JVM language called Ceylon. See &lt;a href="http://in.relation.to/19161.lace"&gt;here&lt;/a&gt; for most of what is known so far. The stated motivation, in a nutshell is that they like Java very much, but it has deficiencies that are preventing progress in key areas, and they are generally feeling &amp;ldquo;frustrated&amp;rdquo;. They don&amp;rsquo;t have a complete compiler yet, but they&amp;rsquo;re working on it, and I get the impression RedHat is pretty serious about it.&lt;/p&gt;  &lt;p&gt;Gavin King&amp;rsquo;s slides provide a fascinating insight into the kind of thinking that remains so dominant in the Java community. Gavin King is well known in the Java world as the inventor/leader of &lt;a href="http://www.hibernate.org/"&gt;Hibernate&lt;/a&gt; and various other JBoss projects. He certainly knows Java inside out, and his list of &amp;ldquo;frustrations&amp;rdquo; is astute, if incomplete. While I haven&amp;rsquo;t dug into all the details so far revealed about Ceylon, but it seems likely that they&amp;rsquo;ll succeed in their goal of creating &amp;ldquo;a better Java&amp;rdquo;. If given the choice between using Java and Ceylon, I could certainly see myself choosing Ceylon. But Ceylon is a terrible idea. The problem is that they are treating the symptoms, not the disease; and they&amp;rsquo;re repeating exactly the same mistakes that resulted in them finally hitting a dead-end with Java.&lt;/p&gt;  &lt;p&gt;Possibly the best outcome of Ceylon is that it emphatically refutes the argument that &amp;ldquo;Java is all we need&amp;rdquo;. Few have put more hard labour into trying to make Java feasible than Gavin King and the JBoss folks. They and a &lt;a href="http://apache.org"&gt;few&lt;/a&gt; &lt;a href="http://www.springsource.org/"&gt;others&lt;/a&gt; have spent the last decade or so producing a staggering number of bloated tools, libraries and frameworks in order to keep Java going. Don&amp;rsquo;t get me wrong, there&amp;rsquo;s a lot of extremely useful Java libraries out there, but there&amp;rsquo;s also a huge amount of guff that exists solely to compensate for the impracticality of the Java language. Ceylon is the &amp;ldquo;main-stream&amp;rdquo; admitting, finally, that not all problems can be solved &lt;em&gt;the Java way&lt;/em&gt;: more frameworks, more libraries, more tools, more code.&lt;/p&gt;  &lt;p&gt;So Mr King and friends have finally hit the wall with Java. They&amp;rsquo;re a bit late to the party, but we should welcome them none the less. So why do I say Ceylon is a terrible idea? The short answer is: &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt;. The long answer is, well, longer. My biased summary of the situation is this: after years of having to build more and more layers of increasingly baroque frameworks in order to make progress, they realise that they can no longer keep up with their competitors (&lt;em&gt;cough_C#&lt;/em&gt;cough_) because Java the language is an unavoidable &amp;ldquo;bottleneck&amp;rdquo;. They identify certain essential abstractions that are needed to solve their immediate problems, and proceed to design a new language that provides those essential abstractions, while remaining as &amp;ldquo;familiar&amp;rdquo; as possible.&lt;/p&gt;  &lt;p&gt;In other words, Ceylon is all about making &amp;ldquo;a better Java&amp;rdquo;. There is certainly support for a evolutionary approach like this. Some argue that Java itself was (in language terms) &amp;ldquo;a better C++&amp;rdquo;, so why not follow that successful approach now? Well, if that worked so well for Java, why are even its greatest fans now trying to replace it? I&amp;rsquo;m reminded of Linus Torvalds' reaction to &amp;ldquo;Subversion is a better CVS&amp;rdquo;. The problem with Subversion isn&amp;rsquo;t that is poorly designed or built; it isn&amp;rsquo;t. The problem with Subversion is that the goal itself just isn&amp;rsquo;t very useful.&lt;/p&gt;  &lt;p&gt;This is how it&amp;rsquo;s going to go: Ceylon will be built, they&amp;rsquo;ll make a SDK library, then there will be Hibernate-Ceylon, Spring-Ceylon, WebFrameworks-Ceylon 1 through 63,854, Logging4Ceylon, Ceylon.util.logging, commons-logging-ceylon and Simple Logging Facade 4 Ceylon. All these will be an improvement over their Java equivalents. Then, in another five or so years they&amp;rsquo;ll hit some new pain points and realise that some of those other &amp;ldquo;academic&amp;rdquo; abstractions are actually useful in the real world after all. For example, Ceylon supports higher-order functions (but, inexplicably, not lambda expressions). If we could go back in time 5 years and ask Gavin King &amp;ldquo;how important do you think higher-order functions are?&amp;rdquo;, what would he say? My guess is &amp;ldquo;they&amp;rsquo;re not essential for Real Work™&amp;rdquo;.&lt;/p&gt;  &lt;p&gt;But it&amp;rsquo;s still an improvement, so why not embrace it? Because we have an already have a much better option that&amp;rsquo;s already doing the job in the real world: Scala. Or look at the interesting stuff going on in .NET land. Ceylon&amp;rsquo;s goals look positively narrow and uninspiring by comparison. Of course, Gavin King was immediately asked &amp;ldquo;why not Scala?&amp;rdquo;. It is my sincere hope that this question will continue to be asked of him. His answer consists of the same misconceptions that Scala advocates have been trying to dispel since forever. Take this statement from Mr King, from an &lt;a href="http://www.infoq.com/news/2011/04/ceylon"&gt;interview in InfoQ&lt;/a&gt;:&lt;/p&gt;  &lt;p&gt;&lt;em&gt;One important force that helped make Java so successful was the things Java left out. But you need to be very smart here: Java&amp;rsquo;s decision to leave out higher-order function support was enormously harmful. Now, obviously the Scala team have gone down a very different path here and have created a very feature-rich type system. As a general rule I would prefer to solve my problems with fewer, more general constructs, than with more, less powerful constructs.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;This is the exact inverse of the truth. No one who has made a serious effort to understand Scala could make such a statement. &amp;ldquo;Fewer, more general constructs&amp;rdquo; is &lt;em&gt;exactly&lt;/em&gt; what Scala is all about! My summary of Scala&amp;rsquo;s mission statement would be as follows:&lt;/p&gt;  &lt;ul&gt; &lt;li&gt;Scala aims to maximise the potential for useful abstractions, whilst:  &lt;ul&gt; &lt;li&gt;giving assurance that your abstractions are correct (static typing)&lt;/li&gt; &lt;li&gt;allowing you to do what is necessary to get the performance you need&lt;/li&gt; &lt;li&gt;maintaining seamless interoperability with Java&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt;   &lt;p&gt;Scala aims to be compatible with Java, but it&amp;rsquo;s about much more than just &amp;ldquo;a better Java&amp;rdquo;. Ironically, it seems as though Ceylon will not interoperate with Java as seamlessly as Scala does (e.g. Scala keeps null and type erasure). It&amp;rsquo;ll be interesting to see how that works out. To get an idea of how serious the Scala team is about powerful but &lt;em&gt;practical&lt;/em&gt; abstractions, look at how they handle the tensions that crop up between abstraction and performance. Great examples of this are how Scala handles the unpleasantness of arrays on the JVM, and also the @specialized annotation.&lt;/p&gt;  &lt;p&gt;Scala is by no means perfect. The trade-offs it makes will not suit everyone fully. But I cannot help but scratch my head over statements like this (Gavin King, again):&lt;/p&gt;  &lt;p&gt;&lt;em&gt;But I guess I should mention that the number one technical problem that we simply can&amp;rsquo;t solve to our satisfaction in Java &amp;ndash; or in any other existing JVM language &amp;ndash; is the problem of defining user interfaces and structured data using a typesafe, hierarchical syntax.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;I could very well be missing something, but this would seem like a problem that is right in Scala&amp;rsquo;s wheelhouse. Perhaps it may not be solved satisfactorily today, but it could done with far less effort than creating a whole new language (and new standard library, and new tool chain…). It is depressing to think of what these guys could achieve working with Scala instead of pouring resources into Ceylon.&lt;/p&gt;  &lt;p&gt;You may wonder, &amp;ldquo;if you think Scala is so good, then use it and be happy, why worry about Ceylon?&amp;rdquo; Well, I worry because I think Ceylon is worse than Scala, but it could win anyway. That actually seems to be the more common outcome in these situations. I would much prefer a world with Scala jobs in demand than one with Ceylon jobs in demand. So, yes, it&amp;rsquo;s all about me being selfish. I would say to all Scala fans: don&amp;rsquo;t be afraid to be a little selfish and evangelise for the better outcome.&lt;/p&gt;      &lt;p style="font-size: 10px;"&gt;      &lt;a href="http://posterous.com"&gt;Posted via email&lt;/a&gt;       from &lt;a href="http://lockster.posterous.com/ceylon-interesting-for-the-wrong-reasons"&gt;lockster's posterous&lt;/a&gt;      &lt;/p&gt;      &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/806077456733837244-5739607290548687548?l=lachlanrambling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lachlanrambling.blogspot.com/feeds/5739607290548687548/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=806077456733837244&amp;postID=5739607290548687548' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/5739607290548687548'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/5739607290548687548'/><link rel='alternate' type='text/html' href='http://lachlanrambling.blogspot.com/2011/04/ceylon-interesting-for-wrong-reasons.html' title='Ceylon: Interesting for the Wrong Reasons'/><author><name>Lachlan</name><uri>http://www.blogger.com/profile/13336649267304857235</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://static.flickr.com/42/83673461_67524e41a3_m.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-806077456733837244.post-1990301467509159126</id><published>2010-12-21T17:26:00.001+11:00</published><updated>2010-12-21T17:26:19.500+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='climate change'/><category scheme='http://www.blogger.com/atom/ns#' term='religion'/><category scheme='http://www.blogger.com/atom/ns#' term='evolution'/><category scheme='http://www.blogger.com/atom/ns#' term='politics'/><title type='text'>Creationism and climate change denial</title><content type='html'>&lt;div class='posterous_autopost'&gt;&lt;p&gt;I&amp;rsquo;ve noticed this more and more: people lumping &amp;ldquo;climate change denial&amp;rdquo; and &amp;ldquo;evolution denial&amp;rdquo; (creationism) into the same category. The argument is that both of these are the result of the same religious conservative &amp;ldquo;anti-science&amp;rdquo; movement. In a very narrow sense, this is true; creationists generally do not seem to believe in anthropogenic global warming (AGW), for the same bogus reasons they don&amp;rsquo;t believe in evolution. But the reverse is not true: many (most I would say) AGW skeptics are not creationists. Lumping these two things together allows the environmentalists to dismiss any criticism of the established climate change narrative as the ravings of anti-scientific religious nuts. But there are some very significant scientific and economic arguments around climate change that are most definitely not in the same class as creationist arguments. Time for some de-lumping.&lt;/p&gt;  &lt;p&gt;One major difference between climate change and evolution is how the evidence is understood and presented. It is now a familiar experience to see someone on TV telling us we need to immediately reduce emissions to avoid climatic catastrophe. In the rare event that such a person is asked to provide evidence of a human cause, the most common answer I&amp;rsquo;ve observed is along the lines of &amp;ldquo;ice caps and glaciers are melting, and the scientific consensus is that human CO₂ emissions are to blame.&amp;rdquo; Now, when was the last time you heard someone asked for evidence supporting evolution to respond with &amp;ldquo;life forms adapt to their environment and the scientific consensus is that Darwinian evolution is the cause.&amp;rdquo; This is not a small point. The fact that &amp;ldquo;consensus&amp;rdquo; is so regularly rolled out to support AGW, but is &lt;em&gt;never&lt;/em&gt; used to support evolution shows that the levels of scientific understanding and debate are completely different.&lt;/p&gt;  &lt;p&gt;No one talks about the &amp;ldquo;scientific consensus&amp;rdquo; for evolution because there&amp;rsquo;s no need to: evolution has a mountain of cold hard facts on its side, all confirmed by independent observation countless times. Climate research is very tough by comparison: our observational capabilities generally aren&amp;rsquo;t good enough to falsify competing theories. Instead, we have the IPCC saying that since we can&amp;rsquo;t establish the facts by direct observation, we&amp;rsquo;ll establish them by consensus. You can&amp;rsquo;t take the IPCC publications, repeat the experiments and confirm their results, because at the end of the day it&amp;rsquo;s just opinion.&lt;/p&gt;  &lt;p&gt;My point here is not to show that the IPCC is wrong, but simply to show that the scientific process that it follows is fundamentally and necessarily different to that of evolutionary biology, or any other hard science for that matter. Questioning the consensus-derived &amp;ldquo;facts&amp;rdquo; of climate research is not the same thing as questioning the empirically verified facts of evolution.&lt;/p&gt;  &lt;p&gt;Another difference I think is worth pointing out is how politics is so commonly mixed with climate science, in contrast to evolution science. Tell me if this scenario sounds familiar: well credentialed scientist goes on TV and says &amp;ldquo;my research shows that climate change is likely to significantly damage coral reefs&amp;hellip;&amp;rdquo; and barely pausing for breath continues &amp;ldquo;so it&amp;rsquo;s clear we must act to cut CO₂ emissions.&amp;rdquo; This casual connection of minor scientific research to sweeping reorganization of the world&amp;rsquo;s energy production is now so common place that people don&amp;rsquo;t find it remarkable. And if you accept the climate change problem but doubt the solution you&amp;rsquo;ll likely still receive the &amp;ldquo;denier&amp;rdquo; pejorative. Evolutionary biology simply isn&amp;rsquo;t political in this way.&lt;/p&gt;  &lt;p&gt;Skepticism regarding climate change is not comparable to the denial of the established facts of evolution. Climate research has a long, long way to go before it achieves the level of confidence we have in evolution. It is very wrong to think that all opposition to the climate change narrative is driven by Biblical literalism.&lt;/p&gt;      &lt;p style="font-size: 10px;"&gt;      &lt;a href="http://posterous.com"&gt;Posted via email&lt;/a&gt;       from &lt;a href="http://lockster.posterous.com/creationism-and-climate-change-denial"&gt;lockster's posterous&lt;/a&gt;      &lt;/p&gt;      &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/806077456733837244-1990301467509159126?l=lachlanrambling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lachlanrambling.blogspot.com/feeds/1990301467509159126/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=806077456733837244&amp;postID=1990301467509159126' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/1990301467509159126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/1990301467509159126'/><link rel='alternate' type='text/html' href='http://lachlanrambling.blogspot.com/2010/12/creationism-and-climate-change-denial.html' title='Creationism and climate change denial'/><author><name>Lachlan</name><uri>http://www.blogger.com/profile/13336649267304857235</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://static.flickr.com/42/83673461_67524e41a3_m.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-806077456733837244.post-2877068310027870816</id><published>2010-12-09T13:55:00.001+11:00</published><updated>2010-12-09T13:55:13.863+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='politics'/><category scheme='http://www.blogger.com/atom/ns#' term='wikileaks'/><title type='text'>WikiLeaks</title><content type='html'>&lt;div class='posterous_autopost'&gt;&lt;h1&gt;Attack and Counter-Attack&lt;/h1&gt;  &lt;p&gt;I must confess, no story in recent months has captured my attention like the still-developing WikiLeaks saga. The ongoing dump of diplomatic cables combined with Julian Assange being charged with some sort of sex crime in Sweden means this is going to be in our face for a while yet.&lt;/p&gt;  &lt;p&gt;The response to WikiLeaks has been loud, angry, hyperbolic attacks from &amp;ldquo;tough on terror&amp;rdquo; types in the U.S., and a corresponding thoughtless, reflexive defence from many &amp;ldquo;progressive&amp;rdquo; types. Amongst the noise are a few precious thoughtful critiques.&lt;/p&gt;  &lt;p&gt;Clearly, WikiLeaks is not engaged in terrorism, and Julian Assange is not remotely comparable to the most junior jihadist. Sarah Palin&amp;rsquo;s pronouncements on the subject are pure demagoguery (by now I think we can fairly declare that an axiom with regard to any statement she makes). And Senator Lieberman needs to seriously deflate his sense of his own importance, and recognise that maintaining the government&amp;rsquo;s operational security isn&amp;rsquo;t actually in his job description.&lt;/p&gt;  &lt;p&gt;I believe all these clumsy attacks against WikiLeaks will fail in the end, and they deserve to fail. In fact, I think they are completely counter-productive: sympathy for WikiLeaks is growing as people become concerned about the government trying to restrict speech.&lt;/p&gt;  &lt;p&gt;The defenders of WikiLeaks are themselves hugely overreacting, however. The &amp;ldquo;attacks&amp;rdquo; against WikiLeaks and Mr Assange so far consist of: a few random nuts-with-a-mike threatening violence, some companies cutting off service, and a number of people expressing the &lt;em&gt;opinion&lt;/em&gt; that U.S. law has been broken. Taken together, all this doesn&amp;rsquo;t come close to being a serious attempt to censor WikiLeaks. In the event that Mr Assange is charged by the DOJ, which is unlikely in my opinion, he&amp;rsquo;ll have his day in court. In the even more unlikely event that he&amp;rsquo;s actually convicted of espionage, then it should be the law you&amp;rsquo;re complaining about rather than the enforcement of it. And as Christopher Hitchens &lt;a href="http://www.slate.com/id/2276857/"&gt;points out&lt;/a&gt;, those who choose to engage in civil disobedience must be prepared to face the consequences.&lt;/p&gt;  &lt;p&gt;(The reason I say charges are unlikely is that I can&amp;rsquo;t see how the DOJ could credibly prosecute Mr Assange without also prosecuting the editor of the &lt;em&gt;New York Times&lt;/em&gt;, which would be sure to end in disaster. But, who knows?)&lt;/p&gt;  &lt;p&gt;At a time when publishing a cartoon depicting the Prophet Mohammed means you run the very real risk of &lt;em&gt;being murdered&lt;/em&gt;, I can read people earnestly telling me that Amazon and Paypal cutting off WikiLeaks represents the greatest free-speech fight of our generation. Perspective is sorely lacking here.&lt;/p&gt;  &lt;h1&gt;Transparency&lt;/h1&gt;  &lt;p&gt;Overall, I&amp;rsquo;m far more concerned about the way WikiLeaks is being lauded and defended than the way it&amp;rsquo;s being attacked. I&amp;rsquo;ve seen a call for Julian Assange to be awarded the Nobel Peace Prize and another for him to be named Australian of the Year. This is madness.&lt;/p&gt;  &lt;p&gt;The word most often used by WikiLeaks fans is &lt;em&gt;transparency&lt;/em&gt;. More transparency is good, and WikiLeaks provides more transparency, therefore WikiLeaks is good. Mr Assange certainly understands his fan base very well, as this is the line he takes in his &lt;a href="http://www.theaustralian.com.au/in-depth/wikileaks/dont-shoot-messenger-for-revealing-uncomfortable-truths/story-fn775xjq-1225967241332"&gt;deceitful, self-serving piece&lt;/a&gt; in &lt;em&gt;The Australian&lt;/em&gt;. Well, I need to make a few points about transparency.&lt;/p&gt;  &lt;p&gt;First, transparency is a means, not an end in itself. The ends are, essentially, ensuring that government office holders are acting within the law and in accordance with the will of the people. Of course, this is both a good and necessary thing. In principle, I&amp;rsquo;m all in favour of leaking government secrets when there&amp;rsquo;s a clear public interest in doing so. This has served us well in the past, and will do so again in the future.&lt;/p&gt;  &lt;p&gt;But it must be recognised that transparency may also lead to negative ends. This is why responsible journalists weigh, as best they can, the public interest against the potential downsides before publishing leaked information. &lt;a href="http://www.pbs.org/wnet/need-to-know/security/wikileaks-hurts-the-cause-of-transparency/5503/"&gt;This article&lt;/a&gt; provides a good description of the negative ends that may result from the &amp;ldquo;transparency&amp;rdquo; that WikiLeaks has forced on us.&lt;/p&gt;  &lt;p&gt;Now we must delve into the theories and ideology of Julian Assange. He has explained these &lt;a href="http://www.abc.net.au/news/stories/2010/12/09/3088573.htm?site=thedrum"&gt;in detail&lt;/a&gt;, but I shall do my best to summarise them fairly here. What the defenders of WikiLeaks don&amp;rsquo;t seem to have realised is that Mr Assange actually has no interest in improving transparency, or holding governments to account. His goal is essentially to conduct information warfare against what he views as &amp;ldquo;conspiratorial authoritarian regimes&amp;rdquo;. This is why, in sharp contrast to all the talk of transparency, WikiLeaks does everything it can to conceal its own activities. It&amp;rsquo;s an organisation built for conducting information warfare.&lt;/p&gt;  &lt;p&gt;So, the objective of indiscriminately releasing all the diplomatic cables was not to inform the public, the objective was to impede the ability of the &amp;ldquo;regimes&amp;rdquo; to conduct diplomacy in the future. This is a goal that may very well have been achieved. Julian Assange is not trying to improve the system, he&amp;rsquo;s trying to smash it. In a nutshell, he&amp;rsquo;s an anarchist using information as his weapon. And after he has smashed every institution of liberal democracy, what then? Like any good anarchist, he has nothing more to say.&lt;/p&gt;  &lt;p&gt;The fact that so many of the leaks have been &amp;ldquo;against&amp;rdquo; the U.S. government leads to the unavoidable conclusion that Mr Assange considers that government to be a &amp;ldquo;conspiratorial authoritarian regime&amp;rdquo;. Judging by his rhetoric, I strongly suspect he views all governments that way. Now we come to the really critical point: if Julian Assange is right about this, then &lt;em&gt;his actions make perfect sense and should be supported&lt;/em&gt;. It should be no surprise by now that I think he is completely wrong.&lt;/p&gt;  &lt;p&gt;It is necessary to follow the implications of accepting Mr Assange&amp;rsquo;s thesis. He is claiming that our governments that are ostensibly democratic systems working for the people, are in fact authoritarian regimes that are actively conspiring against the people. Your nation&amp;rsquo;s constitution is a lie. Our traditions of liberal democracy are actually myths. Debate is pointless. Your vote, irrelevant. Breaking the machine with information warfare is the only way to truly affect change.&lt;/p&gt;  &lt;p&gt;Now if I try to muster every last reserve of cynicism and despair at my disposal, I cannot bring myself close to believing such a thing. Am I a naive, dewy-eyed, babe in the woods?&lt;/p&gt;  &lt;p&gt;Returning the subject of transparency, I would argue that in historical terms we&amp;rsquo;re actually doing reasonably well on the transparency front these days. Let us consider some of the government activities that the WikiLeaks cheerleaders are generally most concerned about: detention without trial, &amp;ldquo;enhanced interrogation&amp;rdquo;, handing prisoners over to foreign authorities known to practice torture, extraordinary rendition, support for the Karzai regime/racket, I could go on. Many of these issues concern me too. But we knew about these policies before the valiant Mr Assange rode onto the scene. The leaks have, at most, underscored a few things. These policies are no more likely to be changed after the leaks than they were before.&lt;/p&gt;  &lt;p&gt;Opponents of these harsh policies need to face up to a conclusion that appears most unwelcome to them: conspiracy and lack of transparency are not what keeps the policies alive. The real reason they persist is much more prosaic: the electorate, broadly speaking, is ok with them. What&amp;rsquo;s called for is less vandalism and more old-fashioned criticism. Make your arguments and try to convince your fellow citizens. Don&amp;rsquo;t be afraid to be boring about it (I certainly have no such fear &amp;ndash; ha!). Or forget all that and go with cynical ranting about a public stupefied by mass media and consumerism. Either way.&lt;/p&gt;  &lt;p&gt;In conclusion, I do not want to see WikiLeaks silenced or Julian Assange in jail for espionage (I&amp;rsquo;m not going to comment on the Swedish charges, thus far they seem completely tangential). However, those of us who believe that liberal democracy has some life in it yet need to criticise the undemocratic and destructive ideology that drives WikiLeaks. This is a secretive, unelected, unaccountable group that releases whatever information it can get its hands on. It indiscriminately and purposefully harms the ability of our government office holders to do the work we elected them to do. Our oft-derided citizenry at least have the pragmatic sense to recognise that those to whom we have delegated power can better achieve our common good when some secrecy is maintained. Julian Assange should respect that democratically determined outcome, and give up this reckless test of his pet conspiracy theories.&lt;/p&gt;      &lt;p style="font-size: 10px;"&gt;      &lt;a href="http://posterous.com"&gt;Posted via email&lt;/a&gt;       from &lt;a href="http://lockster.posterous.com/wikileaks"&gt;lockster's posterous&lt;/a&gt;      &lt;/p&gt;      &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/806077456733837244-2877068310027870816?l=lachlanrambling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lachlanrambling.blogspot.com/feeds/2877068310027870816/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=806077456733837244&amp;postID=2877068310027870816' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/2877068310027870816'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/2877068310027870816'/><link rel='alternate' type='text/html' href='http://lachlanrambling.blogspot.com/2010/12/wikileaks.html' title='WikiLeaks'/><author><name>Lachlan</name><uri>http://www.blogger.com/profile/13336649267304857235</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://static.flickr.com/42/83673461_67524e41a3_m.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-806077456733837244.post-3268924035930414780</id><published>2010-10-27T10:24:00.007+11:00</published><updated>2010-10-27T10:32:33.254+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='speculation'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>Some more thoughts on Apple</title><content type='html'>A few more points that occurred to me, following up on my last post.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Whither the mouse?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;/b&gt;Since its inception in 1984, the Mac user interface has obviously been designed for desktop computers with a mouse and a keyboard. When notebook computers came along and we wanted to be able to use them without carrying a mouse everywhere, or without even a flat, stable surface to put the mouse on, they had to emulate the mouse as best they could. This may now be reversing.&lt;br /&gt;
&lt;br /&gt;
In the announcement of Mac OS X Lion, there was great emphasis placed on the use of multitouch gestures as a means of control. I think Lion will be the first OS designed for notebooks with multitouch trackpads, with the desktop Macs left to emulate the MacBooks as best they can. If you consider that a sizeable majority of the hardware Apple sells today is mobile and primarily operated via some form of multitouch instead of a mouse, this move seems sensible. And all new desktop Macs ship with the multitouch-capable &lt;a href="http://www.apple.com/magicmouse/"&gt;Magic Mouse&lt;/a&gt; as standard now.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;b&gt;The Costs of Supporting Java&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
With regard to Java, there's been a few comments along the lines of "all the hardware Apple sells to Java developers must more than cover the cost of the handful of engineers needed to keep maintaining Java". I think this underestimates the costs involved. Supporting Java means, in addition to the engineers, that:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Java must be accounted for in development plans&lt;/li&gt;
&lt;li&gt;Java must be accounted for in QA plans&lt;/li&gt;
&lt;li&gt;Customer support needs to deal with it&lt;/li&gt;
&lt;li&gt;Security vulnerabilities need to be investigated and fixed&lt;/li&gt;
&lt;/ul&gt;
The true cost isn't so much the money, it's that it unavoidably diverts some of the company's attention from things it would rather focus on. While continuing with Java support wouldn't be hugely onerous for Apple, eliminating distractions that aren't bringing much benefit can really help competitiveness.&lt;br /&gt;
&lt;br /&gt;
Also, as the vast majority of Java work (since the switch to Intel) has been on the GUI, I'd expect the Java team knows the guts of the Mac GUI pretty well by now. Engineering talent isn't exactly a fungible resource. There's probably a development manager somewhere in Apple salivating at the thought of having the Java people on her team.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;b&gt;Apple and the Server Side&lt;/b&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
Folks have pointed out that Apple is a heavy user of server-side Java in their web services. I can think of many ways they can deal with that, and have no idea which option they'll take. But I think we can be sure they've got a plan and aren't leaving it to chance. And despite everyone (including me) getting very animated over "Apple dropping Java", it's worth remembering that their Java team isn't going to be shutting down tomorrow.&lt;br /&gt;
&lt;br /&gt;
More generally, Apple's plans for the cloud are completely opaque to me right now. We're all assuming they have big plans for cloud services: they built that &lt;a href="http://www.tuaw.com/2010/10/05/apples-north-carolina-data-center-nears-completion/"&gt;huge new data centre&lt;/a&gt;, and their hardware strategy seems to imply more reliance on cloud services in the future. The iPad's greatest weakness is that so much of its functionality, including just initialising it, requires USB synchronisation with a PC or Mac. MobileMe syncing is great, but it only works for a few things.&lt;br /&gt;
&lt;br /&gt;
The new MacBook Air models were just announced, including one with an 11" screen, which I think is a first for Apple notebooks. When making the announcement, Steve Jobs said something like "we think this is the future of MacBooks". With their emphasis on mobile, wireless use and limited storage, these too are crying out for more cloud services.&lt;br /&gt;
&lt;br /&gt;
And I think this could be Apple's greatest weakness. If I were Steve Jobs, the thing that would worry me most about Android isn't its "openness" (however you care to define it), or the temporary situation of shelf-space in U.S. phone outlets, but the fact it is backed up by the world's best cloud services. And they're only going to get better. Obstacles remain, but the movement towards doing more and more in the cloud is inexorable. Where Google has no rival, Apple's track record is not that great. The iTunes store is a huge success, obviously, but it's not really all that "cloudy", as you need a Mac with enough hard drive to hold all your content. MobileMe is expensive, and often unreliable and slow; it&amp;nbsp;really&amp;nbsp;only survives due to the first class client support on Mac and iOS. The iWork service is not bad, but lacks Google's killer feature of collaborative editing. Apple has its work cut out for it when it comes to the cloud.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;b&gt;Flash, Core Animation and Multitouch&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
In my last post I claimed Flash didn't support Core Animation or Multitouch. Well, &lt;a href="http://twitter.com/#!/johnyanarella/status/28742755151"&gt;@johnyanarella set me right on that&lt;/a&gt;. Flash does support both of these. I haven't used that many Flash apps, so now I'm wondering to what extent the multitouch support is actually used in apps.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/806077456733837244-3268924035930414780?l=lachlanrambling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lachlanrambling.blogspot.com/feeds/3268924035930414780/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=806077456733837244&amp;postID=3268924035930414780' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/3268924035930414780'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/3268924035930414780'/><link rel='alternate' type='text/html' href='http://lachlanrambling.blogspot.com/2010/10/some-more-thoughts-on-apple.html' title='Some more thoughts on Apple'/><author><name>Lachlan</name><uri>http://www.blogger.com/profile/13336649267304857235</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://static.flickr.com/42/83673461_67524e41a3_m.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-806077456733837244.post-8743547404747596723</id><published>2010-10-22T22:52:00.003+11:00</published><updated>2010-10-22T23:03:25.071+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='speculation'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='mac'/><category scheme='http://www.blogger.com/atom/ns#' term='ipad'/><title type='text'>Java and the Mac</title><content type='html'>So Apple has quietly announced that it is &lt;a href="http://developer.apple.com/library/mac/#releasenotes/Java/JavaSnowLeopardUpdate3LeopardUpdate8RN/NewandNoteworthy/NewandNoteworthy.html%23//apple_ref/doc/uid/TP40010380-CH4-SW1"&gt;deprecating its support for Java on the Mac&lt;/a&gt;. The wording was (not uncharacteristically for situations like this) a bit vague on the details of what this means. I think two things are definite: 1) Apple will continue to support Java 6 on Snow Leopard until it reaches end of life; which I think happens when the OS &lt;i&gt;after&lt;/i&gt; Lion is publicly released. 2) Apple will not port Java 7+ to the Mac. The main unresolved question is whether Java 6 will be supported on Lion. My guess is that it will be offered as an optional download, similar to Rosetta in Snow Leopard. Apple won't make any promises though, as they will want to have the option to drop it if it's too much effort.&lt;br /&gt;
&lt;br /&gt;
As a Mac user who has been working on the Java platform for many years, this is a fairly big deal for me. I think it's an interesting event that provides a chance to examine both Java's position and Apple's plans for the Mac. People in the Mac Java community are speculating about the deeper meaning behind this move, especially when combined with Apple effectively banning Java platform applications from the new Mac App Store. So time for me to add my speculation to the noise.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Is Apple trying to force the use of their platform and tools?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
No. True, Apple has made it crystal clear on numerous occasions (the Mac App store requirements are just the latest case) that they want developers targeting their OS platforms to use their development platform (Objective-C, Cocoa, Xcode). But I don't think they are deprecating Java in an attempt to force the issue. After all, Lion will come with Perl, Python and Ruby all pre-installed.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Does Apple want to kill cross-platform desktop apps?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
No. I think it's true that, strategically speaking, Apple has no interest at all in cross-platform apps (outside of the browser). But along with announcing the deprecation,&amp;nbsp;the latest Apple Java release&amp;nbsp;also includes brand-new support for installing multiple versions of the Java platform, explicitly mentioning support for third-party versions. It's clear that Apple has no problem at all with Java running on Macs. I think they want Oracle to take it over, but I doubt they bothered to make any sort of deal with Oracle before making this move. &lt;b&gt;Update:&lt;/b&gt; as I was drafting this, news came through that Steve Jobs has &lt;a href="http://www.macrumors.com/2010/10/22/steve-jobs-comments-on-apples-java-discontinuation/"&gt;replied to a question about this&lt;/a&gt;, which basically confirms that he thinks Oracle should be responsible for Java on the Mac.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Then why did Apple do this?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The reason isn't that complicated: Apple no longer needs Java. If you make a list of what Steve Jobs sees as the critical objectives for Apple, it becomes immediately obvious that maintaining a Mac port of Java is not helping to advance any of them. Of course, neither does maintaining, say, Apple's port of Python. But Python takes very little effort to port and maintain. The Java port requires a team of engineers permanently dedicated to it. Also, the huge success of iOS has given Apple the confidence that their approach to working with third-party developers is working out great for everyone. The prospect of Java developers and applications abandoning the Mac is no longer remotely scary for them. Apple have decided they'd rather pay the costs of dropping Java than keep maintaining it.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;But what are Apple's critical objectives?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The main theme of the "Back to the Mac" event on October 20 was the idea of moving iPad software and hardware features into the Mac, in a way that made sense for the Mac. My theory is that Apple has now oriented its entire strategy around the iPad. I think Steve Jobs probably regards the iPad has the best thing Apple has ever made. This is because the iPad provides the "purest" user experience: you hold it in your hands, rotate it, move it, directly manipulate the information you're working with via touch, and it dedicates itself to the task at hand. Of course, the iPhone has these characteristics too, but if will forever be limited by the (obviously worthwhile) trade-off of fitting in your pocket. The larger screen size of the iPad allows the touch interface to reach its full potential.&lt;br /&gt;
&lt;br /&gt;
Slight diversion: in the recent financial call, Jobs said that 7" was a lousy form-factor for a tablet. You had better believe that he meant it. I will bet that Apple will never release an iPad with a different form factor. Going smaller puts to many constraints on the options for touch UI, so you end up with a bulky iPhone. Going larger would be nice, but it rapidly becomes unwieldy (the fact the iPad can be easily held and moved around is a critical part of the "experience"). The dimensions were chosen to balance the needs of video with those of e-books. Believe me, Apple chose the form-factor it did &lt;i&gt;very&lt;/i&gt; carefully.&lt;br /&gt;
&lt;br /&gt;
And yes, something else Jobs likes about the iPad is that Apple has more control over it. While many ascribe this to cynical motives, I believe Jobs honestly sees this as being good for the customer, and part of the reason for the success of iOS devices. Whether this view is correct will, in the end, be decided in the marketplace.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;What is the future for the Mac?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
So Apple sees the iPad as the future. But while it might be a "pure" experience, there's obviously a large number of important things that the iPad simply cannot do&lt;sup&gt;1&lt;/sup&gt;. So Macs aren't going anywhere, but Jobs wants to make them more iPad-like. In the Mac event, Jobs called out what this meant: curated App Store, full screen apps, app "Launchpad", autosave/resume. What is equally interesting is what this implies they are leaving behind. During&amp;nbsp;Craig Federighi's demo of Lion on the 20th, he showed the use of swipe to switch between a) full screen apps b) dashboard c) "the desktop". Perhaps I'm reading too much into this, but what today constitutes "the Mac Desktop experience" seems, in Lion, to be just another full-screen app you can switch to. A Rosetta-like box to run "the legacy stuff". I think Lion could be Apple's first step in really redesigning the Mac from first principles.&lt;br /&gt;
&lt;br /&gt;
This iPad-like approach also reinforces other trends already underway. The traditional document-centric Mac app is basically dead. Most apps will be one-window, "content-centric", and abstract the filesystem completely. And they'll be made with Apple's tools. In other words, iPhoto '11 is the model. It's going to be fascinating to see how far Apple can take this. There have been people saying, literally for decades, that the fundamental desktop concept of movable, resizable, overlapping windows was the worst idea in the history of user interfaces. Will they be proven right? I have no idea. The best part is, as others have pointed out, Windows cannot easily copy what Mac OS X is doing. Greater distinction between the keyboard/pointer OS platforms will be a great thing, in my opinion.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Where does Java fit in all this?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
It doesn't. Regardless of whether you think Apple's plans for the Mac are great or terrible, it's clear that heavy-weight "cross-platform platforms" like Java and Flash, which are controlled by others, could hardly be more useless to Apple. They don't interfere with Apple's plans, but they don't help them either. Java and Flash apps don't use compelling OS X technologies like Core Animation. They're completely clueless when it comes to multitouch. Apple only cares about one "cross-platform platform": the light-weight and mobile-friendly HTML5, which they can also influence.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Will Oracle Provide Java on Mac?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
I'm not sure, but I think yes. The answer to this question will also answer many questions about what Oracle really has planned for Java and JavaFX. In my opinion, JavaFX has already lost the cross-platform war to HTML5 (I like JavaFX a lot, and would love Oracle to prove me wrong here). Oracle claims to be committed to developing and promoting JavaFX, so it apparently believes it can turn things around. But there's one thing I'm certain about: JavaFX cannot succeed as a credible platform without first-class support on the Mac. If Oracle is actually serious about JavaFX (which &lt;i&gt;is&lt;/i&gt; client-side Java now) then it needs to very soon announce that it will be adding Mac as a fully supported platform, by Java 8 at the latest. Bringing Mac support online in a Java 7 update would be better. If Oracle lets Java on the Mac rot, then the death of client-side Java will be certain and final.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Where did it all go wrong for Java?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
A few people have pointed out that just 10 short years ago Steve Jobs was proudly proclaiming that the Mac would be the premier platform for Java, and now after years of disinterest Apple is finally giving up on Java altogether. How times have changed. In 2000, Apple desperately needed apps on the Mac - any apps, and of course developers. Now, it's Sun/Oracle that really needs Java on the Mac, and Apple can afford to be indifferent.&lt;br /&gt;
&lt;br /&gt;
Even if Oracle produces a brilliant implementation of JavaFX for the Mac, things do not look great for Java on the client. I won't make this post even longer by discussing the reasons for client Java's failure, but it's not because Apple didn't give Java a fair chance. Speaking as someone who really believed in and supported the "write once, run anywhere" ideal of Java, the fact has to be faced: the dream is well and truly finished. Where Java has failed, HTML5 has succeeded, primarily by keeping its goals modest and being ruthlessly pragmatic.&lt;br /&gt;
&lt;br /&gt;
&lt;sup&gt;1&lt;/sup&gt; &lt;span class="Apple-style-span" style="font-size: x-small;"&gt;But I think that we haven't even scratched the surface of what the iPad is capable of. Many of its limitations are "a simple matter of software". I think iOS 4.2 is going to give a big boost to the iPad's utility, as will iOS 5 and beyond. Having said that, there'll always be some jobs that just need a mouse pointer and a keyboard.&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/806077456733837244-8743547404747596723?l=lachlanrambling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lachlanrambling.blogspot.com/feeds/8743547404747596723/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=806077456733837244&amp;postID=8743547404747596723' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/8743547404747596723'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/8743547404747596723'/><link rel='alternate' type='text/html' href='http://lachlanrambling.blogspot.com/2010/10/java-and-mac.html' title='Java and the Mac'/><author><name>Lachlan</name><uri>http://www.blogger.com/profile/13336649267304857235</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://static.flickr.com/42/83673461_67524e41a3_m.jpg'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-806077456733837244.post-7835534215273377612</id><published>2010-09-30T20:04:00.000+10:00</published><updated>2010-09-30T20:04:47.470+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='functional'/><category scheme='http://www.blogger.com/atom/ns#' term='scalaz'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Scala's Missing Monad</title><content type='html'>&lt;p&gt;I've been writing more and more pure functional code in both Scala and Java recently. An issue I found myself running into quite often is this: say you have a function that sometimes returns no results (e.g. looking up a key in a map). A common way to deal with that in Scala is to return an &lt;code&gt;Option&lt;/code&gt;:&lt;/p&gt;

&lt;script class="brush: scala" type="syntaxhighlighter"&gt;
&lt;![CDATA[
def foo(i: Int): Option[String]
]]&gt;
&lt;/script&gt;

&lt;p&gt;Simple enough. But then a typical use of such a function is to map it over all members of a collection:&lt;/p&gt;

&lt;script class="brush: scala" type="syntaxhighlighter"&gt;
&lt;![CDATA[
val strings: List[Option[String]] =
  List(1, 2, 3).map(foo _)
]]&gt;
&lt;/script&gt;

&lt;p&gt;What I find I often want to do in a situation like this is to only bother with the results if all the applications of &lt;code&gt;foo&lt;/code&gt; returned a result. In other words, I want to turn the &lt;code&gt;strings&lt;/code&gt; list above into an &lt;code&gt;Option[List[String]]&lt;/code&gt;, which is &lt;code&gt;Some(List(foo(1).get, foo(2).get, foo(3).get))&lt;/code&gt; if all those applications of &lt;code&gt;foo&lt;/code&gt; give values, and &lt;code&gt;None&lt;/code&gt; otherwise. I couldn't see any method in the Scala standard library that does what I want.&lt;/p&gt;

&lt;p&gt;As a bit of a functional programming n00b, one approach I've found to be useful is to work out the Haskell type signature of the function I want, feed that into &lt;a http="http://haskell.org/hoogle/"&gt;Hoogle&lt;/a&gt; and see what I get, if anything. In this case, the Haskell type is:&lt;/p&gt;

&lt;script class="brush: haskell" type="syntaxhighlighter"&gt;
&lt;![CDATA[
[Maybe a] -&gt; Maybe [a]
]]&gt;
&lt;/script&gt;

&lt;p&gt;The top Hoogle result for that is the sequence function:&lt;/p&gt;

&lt;script class="brush: haskell" type="syntaxhighlighter"&gt;
&lt;![CDATA[
sequence :: Monad m =&gt; [m a] -&gt; m [a]
]]&gt;
&lt;/script&gt;

&lt;p&gt;And look, the &lt;code&gt;sequence&lt;/code&gt; function works on any monad, not just &lt;code&gt;Maybe&lt;/code&gt;/&lt;code&gt;Option&lt;/code&gt;. For example, if my &lt;code&gt;foo&lt;/code&gt; function had been returning &lt;code&gt;Either[SomeErrorType, String]&lt;/code&gt;, then the sequence function would give the first error in the list if there was an error, or the list of results if there was no error. So this is a useful function, but as I said, I can't find it in the standard Scala library.&lt;/p&gt;

&lt;p&gt;When I thought about how to implement sequence in Scala, I immediately ran into trouble. It is often said that "Scala has monads", and we know that the &lt;code&gt;flatMap&lt;/code&gt; method is doing a monadic bind. But this support isn't much more than a convention for method names and type signatures, combined with nice syntax in the form of &lt;code&gt;for&lt;/code&gt; expressions. There is no monad type declared anywhere in the standard library. Without a monad type, the sequence function would have to be re-implemented over and over: &lt;code&gt;Option.sequence&lt;/code&gt;, &lt;code&gt;Either.sequence&lt;/code&gt;, &lt;code&gt;List.sequence&lt;/code&gt;, etc.&lt;/p&gt;

&lt;p&gt;The good news is that Scala's type system &lt;em&gt;can&lt;/em&gt; express the monad type. And the better news is that some really smart people have already done all the work for us in a library called &lt;a href="http://code.google.com/p/scalaz/"&gt;Scalaz&lt;/a&gt;. So I had a look, and lo and behold there is the &lt;a href="http://scalaz.googlecode.com/svn/continuous/latest/browse.sxr/scalaz/MA.scala.html#27505"&gt;sequence function&lt;/a&gt;:&lt;/p&gt;

&lt;script class="brush: scala" type="syntaxhighlighter"&gt;
&lt;![CDATA[
def sequence[N[_], B](implicit a: A &lt;:&lt; N[B],
  t: Traverse[M], n: Applicative[N]): N[M[B]] =
    traverse((z: A) =&gt; (z: N[B]))
]]&gt;
&lt;/script&gt;

&lt;p&gt;That may look nothing like the Haskell function, but that is mostly a result of how typeclasses are expressed in Scala. Trust me, this is the same function. Also, this Scalaz function is more general than the Haskell function above. It turns out that sequence works for any "traversable" thing (not just lists) containing anything that is an applicative functor (not just monads). Haskell also has the equivalent fully generalised sequence function in the &lt;code&gt;Data.Traversable&lt;/code&gt; library.&lt;/p&gt;

&lt;p&gt;So what did I learn from this exercise? First that the lack of explicit types for monad, functor and friends in Scala's standard library is a greater problem than I'd expected. Second, if you're writing pure functional Scala code, you should be using Scalaz. Since all Scala programmers should be writing pure functional code, it follows that all Scala programmers should be using Scalaz!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/806077456733837244-7835534215273377612?l=lachlanrambling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lachlanrambling.blogspot.com/feeds/7835534215273377612/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=806077456733837244&amp;postID=7835534215273377612' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/7835534215273377612'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/7835534215273377612'/><link rel='alternate' type='text/html' href='http://lachlanrambling.blogspot.com/2010/09/scalas-missing-monad.html' title='Scala&apos;s Missing Monad'/><author><name>Lachlan</name><uri>http://www.blogger.com/profile/13336649267304857235</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://static.flickr.com/42/83673461_67524e41a3_m.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-806077456733837244.post-4508198760608261842</id><published>2010-01-08T10:57:00.005+11:00</published><updated>2010-01-08T11:02:08.449+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='cocoa'/><category scheme='http://www.blogger.com/atom/ns#' term='mac'/><category scheme='http://www.blogger.com/atom/ns#' term='objective-c'/><title type='text'>Cocoa vs Haskell</title><content type='html'>So here's the deal - if you want to write a Mac GUI app, you want to use the Cocoa framework. As a practical system for writing desktop GUI apps, the Cocoa stack simply has no equal anywhere. Part of what makes Cocoa so great is the Objective-C language, which adds a very flexible and dynamic OOP system on top of standard C.&lt;br /&gt;
&lt;br /&gt;
Objective-C turned out to be a great match for creating desktop GUIs. It's obviously a general-purpose language, but for general programming it would be no where near my first choice. My first choice right now would be Haskell, even though I'm still a beginner and I pretty much suck at it. But I get why Haskell is so good (and so much fun).&lt;br /&gt;
&lt;br /&gt;
So if I want to write a Mac GUI app, can I use Haskell? I've had a play with&amp;nbsp;&lt;a href="http://hoc.sourceforge.net/"&gt;HOC&lt;/a&gt;&amp;nbsp;which is a very neat bit of software that bridges Objective-C to Haskell. You can call Haskell from Objective-C and implement Objective-C classes in Haskell. There are some challenges trying to use HOC—it's not exactly straightforward to get it up and running and integrated into your XCode project; and it's under active, but slow, development and doesn't have a stable release. But at a more fundamental level I've come to the conclusion that, while it's very cool, HOC probably isn't worth it.&lt;br /&gt;
&lt;br /&gt;
If you can get HOC working, you'll have a full-blown bridge that lets you use Cocoa APIs from Haskell. But is that actually worthwhile? The things that Haskell excels at are basically useless when using Cocoa, which is completely based around stateful objects being mutated by events and messages. While you could have all your code—including the Cocoa GUI stuff—in Haskell, the GUI code will all be imperative using the IO monad. All the effort just gets you&amp;nbsp;Objective-C with nicer syntax.&lt;br /&gt;
&lt;br /&gt;
So for Mac apps, I think sticking with Objective-C for the GUI code is the best choice. As a language, it sucks compared to Haskell, but it just works very well with the Cocoa APIs. But what about using Haskell to implement the Model and do other computational heavy-lifting under the hood? This turns out to be much simpler than a full Objective-C bridge. &lt;a href="http://www.haskell.org/ghc/"&gt;GHC&lt;/a&gt;&amp;nbsp;of course offers a standardised foreign function interface to C out of the box, and Objective-C is a superset of C. So you can call Haskell from Objective-C code just as you would from plain C, and it works quite naturally.&lt;br /&gt;
&lt;br /&gt;
But it's a bit trickier to build a complete Cocoa application that does this. There is a&amp;nbsp;&lt;a href="http://www.haskell.org/haskellwiki/Using_Haskell_in_an_Xcode_Cocoa_project"&gt;HaskellWiki page&lt;/a&gt;&amp;nbsp;that describes one approach to getting a complete XCode project set up. I tried it out and it works, although things don't integrate very well. You have to compile the Haskell code using ghc outside of the XCode build process, and you have to manually track down all the libWhatever.a files that your Haskell code needs to link against. I've made a simple demonstration project for XCode 3.2 that works for me on OS 10.6:&amp;nbsp;&lt;a href="http://github.com/quelgar/HaskellCocoaDemo"&gt;http://github.com/quelgar/HaskellCocoaDemo&lt;/a&gt;. This is basically the classic Currency Converter app from Apple's Cocoa tutorial, but it does the currency calculation in Haskell. Here's the rough list of steps I performed, starting from the standard XCode template for a Cocoa Application:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;In the project build settings:&lt;/li&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Set the architecture to just "i386". GHC is today only built for 32-bit Intel on Mac&lt;/li&gt;
&lt;li&gt;Add "-liconv" to "Other Linker Flags". GHC libs need it.&lt;/li&gt;
&lt;li&gt;Add your GHC include directory to "Header Search Paths". For GHC 6.12.1 on my system, this was "/Library/Frameworks/GHC.framework/Versions/Current/usr/lib/ghc-6.12.1/include/".&lt;/li&gt;
&lt;li&gt;Add "/Library/Frameworks/GHC.framework/Versions/Current/" to the "Library Search Paths" and mark it recursive. Not sure if this is actually necessary since we end up adding all the libraries to the project manually anyway.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;li&gt;The Haskell function that will be called from C is in HaskellConvert.hs, which uses the typical FFI stuff. You compile this with GHC like so: "ghc -c HaskellConvert.hs". This outputs various files, of which the following have to be added to your XCode project:&lt;/li&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;HaskellConvert.o&lt;/li&gt;
&lt;li&gt;HaskellConvert_stub.o&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;li&gt;You now have to add all the lib*.a files from GHC that your Haskell code needs to link successfully. The wiki page I linked to above describes one way of doing this. It's not pretty, but it works. Once you know you need a particular .a file, just drag it from the finder to the project, and accept all the defaults in the add file dialog. It will be added to the link stage automatically.&lt;/li&gt;
&lt;li&gt;Modify main.m to perform the Haskell runtime setup and teardown.&lt;/li&gt;
&lt;li&gt;In this demo, Haskell is called from Converter.m, so this file needs &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;#import "HaskellConvert_stub"&lt;/span&gt;, and then just make the call to Haskell.&lt;/li&gt;
&lt;/ul&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
Probably the biggest downside of this plain C approach vs HOC is that you can't pass Objective-C objects to Haskell (well, you can, but they are not easy to use from Haskell, to say the least). So you have to convert whatever Objective-C data structures you're using in the GUI to plain C types for interfacing with your Haskell APIs. Haskell wrappers for the OS X C APIs for CoreFoundation and the Objective-C runtime might make using Objective-C objects from Haskell feasible without a full language bridge, but I'm not sure about this.&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
The GHC installer for Mac installs the bulk of GHC under /Library/Frameworks/GHC.framework, but I don't think it actually works as a Mac framework. I could be doing something wrong, but adding it to XCode as a framework didn't work (XCode just said it wasn't found when I tried to build, from memory). It would be great if GHC could be made a fully-functional Mac framework, as we would no longer need to manually set include and lib search paths, or explicitly add every Haskell .a file to the project. But to make this useful, I think we'd need some automated way of building any Cabal package as a framework. I'm not sure if that's feasible.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/806077456733837244-4508198760608261842?l=lachlanrambling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lachlanrambling.blogspot.com/feeds/4508198760608261842/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=806077456733837244&amp;postID=4508198760608261842' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/4508198760608261842'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/4508198760608261842'/><link rel='alternate' type='text/html' href='http://lachlanrambling.blogspot.com/2010/01/cocoa-vs-haskell.html' title='Cocoa vs Haskell'/><author><name>Lachlan</name><uri>http://www.blogger.com/profile/13336649267304857235</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://static.flickr.com/42/83673461_67524e41a3_m.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-806077456733837244.post-3577169688449660087</id><published>2009-12-15T23:12:00.006+11:00</published><updated>2009-12-15T23:31:09.728+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Some simple Scala null tricks</title><content type='html'>&lt;p&gt;Scala code often needs to deal with null references, unfortunately. Such is the price of Java interoperability. One of my favourite utility methods is:&lt;/p&gt;

&lt;script type="syntaxhighlighter" class="brush: scala"&gt;&lt;![CDATA[
def ?[A &lt;: AnyRef](ref: A): Option[A] =
    if (ref eq null) None else Some(ref)

// e.g.
val value =
  ?(javaCallThatMayReturnNull()).getOrElse(defaultValue)
]]&gt;&lt;/script&gt;

&lt;p&gt;Scala 2.8 offers this using &lt;code&gt;Option(ref)&lt;/code&gt; instead of &lt;code&gt;?(ref)&lt;/code&gt;. However, I can't figure out why the Scala 2.8 method accepts non-reference values as well.&lt;/p&gt;

&lt;p&gt;Another simple thing that may come in handy is an extractor for non-null values:&lt;/p&gt;

&lt;script type="syntaxhighlighter" class="brush: scala"&gt;&lt;![CDATA[
object NotNull {
  def unapply[A &lt;: AnyRef](ref: A): Option[A] =
      if (ref eq null) None else Some(ref)
}
]]&gt;&lt;/script&gt;

&lt;p&gt;What's the advantage of using an extractor? Say you have a collection of references, some of which may be null, and you want to ignore the null references:&lt;/p&gt;

&lt;script type="syntaxhighlighter" class="brush: scala"&gt;&lt;![CDATA[
val xs = List("a", null, "b", null, null, "c", null)
// prints "List(a, b, c)"
println(for (NotNull(x) &lt;- xs) yield x)
]]&gt;&lt;/script&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/806077456733837244-3577169688449660087?l=lachlanrambling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lachlanrambling.blogspot.com/feeds/3577169688449660087/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=806077456733837244&amp;postID=3577169688449660087' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/3577169688449660087'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/3577169688449660087'/><link rel='alternate' type='text/html' href='http://lachlanrambling.blogspot.com/2009/12/some-simple-scala-null-tricks.html' title='Some simple Scala null tricks'/><author><name>Lachlan</name><uri>http://www.blogger.com/profile/13336649267304857235</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://static.flickr.com/42/83673461_67524e41a3_m.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-806077456733837244.post-1225984358737964913</id><published>2009-07-06T12:45:00.004+10:00</published><updated>2009-07-06T15:35:06.867+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>The FSF doesn't care if they're lonely</title><content type='html'>Daniel Jalkut, a leading light of the Mac developer community recently &lt;a href="http://www.red-sweater.com/blog/825/getting-pretty-lonely"&gt;blogged about&lt;/a&gt; the &lt;a href="http://www.gnu.org/licenses/licenses.html#GPL"&gt;GPL&lt;/a&gt; and some of consequences of it for collaborative software development. I agree with what he says, and I dislike how the GPL limits collaboration in a number of ways. But I thought it might be useful to go over the background and objectives of the GPL.&lt;div&gt;
&lt;/div&gt;&lt;div&gt;There's an important thing to remember when talking about the GPL: the impact, good or bad, on the practicalities of software development have nothing to do with its objectives. The authors of the GPL, the &lt;a href="http://www.fsf.org/"&gt;Free Software Foundation&lt;/a&gt; just aren't concerned by the kinds of issues that Daniel raises. The fundamental principle of the FSF is that anyone should have complete freedom to study, modify and share all computer software. The end-game of the FSF is that all restrictions that apply to software, such as copyrights and patents, be abolished altogether (in so far as they currently apply to software). In other words, they want any software written by anyone to have no legal protection from examination, modification and redistribution by anyone else. The FSF really wants all software to be in the public domain, without the option of copyright protection.&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;The GPL is their attempt to bring this about given the reality that copyright of software exists today and shows no signs of going away. The GPL is designed to use the copyright system against itself; the FSF calls this "copyleft". In typical commercial software, the copyright is used to prevent the licensee (user) of the software from doing things with it that the author doesn't like (such as modification or redistribution). The GPL instead prevents the licensee from adding any new restrictions. The end result of putting software under the GPL is basically the same as if copyright protection for that software didn't exist at all.&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;Now, you can make many arguments pointing out the practical downsides of removing copyright restrictions on software (whether by abolishing software copyright, or via the GPL). Daniel's post is a good example of this. But to the FSF, these considerations are secondary to the principle that &lt;i&gt;any&lt;/i&gt; restrictions to what users can do with their software is morally Wrong. You can see an example of this in the &lt;a href="http://www.gnu.org/gnu/manifesto.html"&gt;GNU Manifesto&lt;/a&gt; where they acknowledge that adopting their policies could result in programmers earning less. Their view seems to be that doing the "right thing" can have effects that aren't necessarily desirable, but we just have to live with as best we can. Perhaps a good analogy is free speech, which necessarily increases the risk of children accessing pornographic or violent material.&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;I try to take a pragmatic "what best serves the common good?" approach to matters, which leads me to agree with the FSF with regard to software patents, but disagree with them on copyright. I think patents, when applied to software, are all harm and no benefits. For copyright, I can see greater upside than downside to the current system. It's true that without software copyrights we would all have greater freedom regarding how we can use our computers, but it's also likely that our computers would be of much less practical use to us. Do professional photographers and artists prefer GIMP or Photoshop?&lt;/div&gt;&lt;div&gt;
&lt;/div&gt;&lt;div&gt;Just to be clear, arguing over the implications of the GPL on software development practice is a very useful thing to do. Many people who don't care about the political position of the FSF still chose to use the GPL simply because it happens to suit their needs, and there's nothing wrong with that. But having a clear understanding of the costs and benefits is essential.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/806077456733837244-1225984358737964913?l=lachlanrambling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lachlanrambling.blogspot.com/feeds/1225984358737964913/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=806077456733837244&amp;postID=1225984358737964913' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/1225984358737964913'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/1225984358737964913'/><link rel='alternate' type='text/html' href='http://lachlanrambling.blogspot.com/2009/07/fsf-doesnt-care-if-theyre-lonely.html' title='The FSF doesn&apos;t care if they&apos;re lonely'/><author><name>Lachlan</name><uri>http://www.blogger.com/profile/13336649267304857235</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://static.flickr.com/42/83673461_67524e41a3_m.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-806077456733837244.post-1032667179666787596</id><published>2009-06-01T23:11:00.006+10:00</published><updated>2009-06-01T23:32:40.640+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='functional'/><category scheme='http://www.blogger.com/atom/ns#' term='euler'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Project Euler Problem 8</title><content type='html'>&lt;p&gt;I guess I should warn that these Project Euler posts have &lt;strong style="color: red"&gt;spoilers&lt;/strong&gt;, in case you want to try the problems yourself ☺. My Scala solution to &lt;a href="http://projecteuler.net/index.php?section=problems&amp;id=8"&gt;problem 8&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;val input = "73167176531330624919225119674426574742355349194934" +
"96983520312774506326239578318016984801869478851843" +
"85861560789112949495459501737958331952853208805511" +
"12540698747158523863050715693290963295227443043557" +
"66896648950445244523161731856403098711121722383113" +
"62229893423380308135336276614282806444486645238749" +
"30358907296290491560440772390713810515859307960866" +
"70172427121883998797908792274921901699720888093776" +
"65727333001053367881220235421809751254540594752243" +
"52584907711670556013604839586446706324415722155397" +
"53697817977846174064955149290862569321978468622482" +
"83972241375657056057490261407972968652414535100474" +
"82166370484403199890008895243450658541227588666881" +
"16427171479924442928230863465674813919123162824586" +
"17866458359124566529476545682848912883142607690042" +
"24219022671055626321111109370544217506941658960408" +
"07198403850962455444362981230987879927244284909188" +
"84580156166097919133875499200524063689912560717606" +
"05886116467109405077541002256983155200055935729725" +
"71636269561882670428252483600823257530420752963450"

val digits = input.map(_.asDigit).toArray

def multiply(index: Int) = digits.slice(index, index + 5)
    .foldLeft(1)(_*_)

val multiples: Stream[Int] = {
    def rec(n: Int): Stream[Int] = Stream.cons(multiply(n),
        if (n &gt; digits.length - 5) Stream.empty else rec(n+1))
    Stream.cons(mult(0), rec(1))
}
println(Iterable.max(multiples))
&lt;/pre&gt;

&lt;p&gt;For convenience, this specifies the input as a string, then uses &lt;code&gt;RichChar.asDigit&lt;/code&gt; to create a corresponding array of integers. The &lt;code&gt;multiply&lt;/code&gt; function uses left fold to multiply together sequences of five digits. The &lt;code&gt;multiples&lt;/code&gt; value is a stream (lazy list) of the multiples of all groups of five consecutive digits from the input. And finally, the &lt;code&gt;Iterable&lt;/code&gt; object provides a convenient method to find the maximum value in any Iterable containing Orderable things.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/806077456733837244-1032667179666787596?l=lachlanrambling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lachlanrambling.blogspot.com/feeds/1032667179666787596/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=806077456733837244&amp;postID=1032667179666787596' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/1032667179666787596'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/1032667179666787596'/><link rel='alternate' type='text/html' href='http://lachlanrambling.blogspot.com/2009/06/project-euler-problem-8.html' title='Project Euler Problem 8'/><author><name>Lachlan</name><uri>http://www.blogger.com/profile/13336649267304857235</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://static.flickr.com/42/83673461_67524e41a3_m.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-806077456733837244.post-7519464978653576959</id><published>2009-06-01T17:19:00.008+10:00</published><updated>2009-06-01T22:40:42.297+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='functional'/><category scheme='http://www.blogger.com/atom/ns#' term='euler'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Project Euler in Scala</title><content type='html'>&lt;p&gt;&lt;a href="http://projecteuler.net/"&gt;Project Euler&lt;/a&gt; is a bunch of mathematical/programming problems. I've been trying to improve my &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt; skills by using it on some of the Euler problems. I'm trying to use functional programming styles as much as possible. My solutions definitely haven't been very optimized, but I am learning, which is the aim.&lt;/p&gt;

&lt;h3&gt;&lt;a href="http://projecteuler.net/index.php?section=problems&amp;id=1"&gt;Euler Problem 1&lt;/a&gt;&lt;/h3&gt;

&lt;p class="myQuote"&gt;
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.

Find the sum of all the multiples of 3 or 5 below 1000.
&lt;/p&gt;

&lt;p&gt;My solution:&lt;/p&gt;

&lt;pre&gt;def sum(nums: Iterable[Int]): Int = (0 /: nums)(_ + _)

println(sum((3 until 1000).filter(i =&gt; i%3 == 0 || i%5 == 0)))&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;3 until 1000&lt;/code&gt; creates a "range", which is a lazy sequence of numbers from 3 to 999 inclusive. Because it's lazy, you don't get 997 integers sitting around in memory, you only get those integers which pass the filter. The filter itself shows the Scala syntax for a "lambda expression" (anonymous function). The full syntax is &lt;code&gt;(arg1, arg2, ..) =&gt; function body&lt;/code&gt;, but when you only have one argument (a single Int, in this case) you can leave out the brackets.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;sum&lt;/code&gt; function is the operator syntax for a left fold over &lt;code&gt;nums&lt;/code&gt;. The &lt;code&gt;_+_&lt;/code&gt; is an even more terse form of a lambda expression that you can use for really simple expressions. The first underscore is replaced by the first argument to the function, and the second is replaced by the second argument.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/806077456733837244-7519464978653576959?l=lachlanrambling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lachlanrambling.blogspot.com/feeds/7519464978653576959/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=806077456733837244&amp;postID=7519464978653576959' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/7519464978653576959'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/7519464978653576959'/><link rel='alternate' type='text/html' href='http://lachlanrambling.blogspot.com/2009/06/project-euler-in-scala.html' title='Project Euler in Scala'/><author><name>Lachlan</name><uri>http://www.blogger.com/profile/13336649267304857235</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://static.flickr.com/42/83673461_67524e41a3_m.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-806077456733837244.post-716187787558248904</id><published>2006-10-17T14:30:00.001+10:00</published><updated>2009-06-01T21:49:58.610+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='closures'/><category scheme='http://www.blogger.com/atom/ns#' term='logging'/><title type='text'>Logging vs String Construction</title><content type='html'>&lt;p&gt;A classic logging problem in Java is this:&lt;/p&gt;
&lt;pre&gt;
logger.finest(expensiveStringConstruction());
&lt;/pre&gt;
&lt;p&gt;The problem with this is that even when the logger's level is above FINEST and the message is not logged, the message string must still be constructed. In cases where constructing the string involves a lot of work, your code can be slowed down significantly even when logging is off. The standard solution is like so:&lt;/p&gt;
&lt;pre&gt;
if (logger.isLoggable(Level.FINEST))
{
  logger.finest(expensiveStringConstruction());
}
&lt;/pre&gt;
&lt;p&gt;By adding the &lt;code&gt;if&lt;/code&gt; statement around the logging, the expensive string construction is only done if the message is actually going to be used. The problem with this is that if you have a lot of logging statements, your code soon ends up littered with these &lt;code&gt;if&lt;/code&gt;s that just obscure what is really happening. Not to mention that you have to type it all in.&lt;/p&gt;

&lt;p&gt;This problem could have been tackled in a different way. It was a mistake for the logging methods to take &lt;code&gt;String&lt;/code&gt; objects as parameters. This mandates that the messages &lt;em&gt;must&lt;/em&gt; be constructed before passing them to the logger. A better approach is to delay creating the message string until the last possible moment, when we know it will be needed. One option would be to have an interface called, say, &lt;code&gt;LogMessageFactory&lt;/code&gt; with a method &lt;code&gt;String createLogMessage()&lt;/code&gt; and have the log methods accept the interface instead of &lt;code&gt;String&lt;/code&gt;. But a new interface isn't necessarily needed, as good old &lt;code&gt;Object&lt;/code&gt; already has a &lt;code&gt;toString&lt;/code&gt; method. If loggers took &lt;code&gt;Object&lt;/code&gt;'s instead of &lt;code&gt;String&lt;/code&gt;'s, then they could just call &lt;code&gt;toString&lt;/code&gt; when logging actually takes place.&lt;/p&gt;

&lt;p&gt;Well, the logging API actually does let you do this. &lt;code&gt;LogRecord&lt;/code&gt; objects can store a message string and an arbitrary set of parameter objects. The standard formatters will use &lt;code&gt;MessageFormat&lt;/code&gt; to construct the string that is finally logged. Here's an example:&lt;/p&gt;
&lt;pre&gt;
public final class TestLog
{

    public static final Logger logger =
        Logger.getLogger("test");

    public static void main(final String[] args)
    {
        final TestLog testLog = new TestLog();
        logger.finest(testLog.toString());     // 1
        logger.log(Level.FINEST, "{0}", testLog);   // 2
    }

    public String toString()
    {
        try
        {
            // expensive string construction here
            Thread.sleep(5000L);
        }
        catch (InterruptedException e)
        {
            assert false;
        }
        return "Hello, world";
    }

}
&lt;/pre&gt;
&lt;p&gt;If the logger is configured to log at FINEST or below, the lines marked 1 and 2 behave identically and the message is logged. However, if the logger's level is above FINEST, then line 1 will take 5 seconds to do nothing and line 2 will just check the level and exit, without calling &lt;code&gt;toString&lt;/code&gt; at all.&lt;/p&gt;

&lt;p&gt;The advantage of logging this way is that you don't have to put all those &lt;code&gt;if&lt;/code&gt;s statements in. But there are disadvantages. You can't use the convenience logging methods like &lt;code&gt;severe&lt;/code&gt; and &lt;code&gt;info&lt;/code&gt;, etc. You have to use one of the &lt;code&gt;log&lt;/code&gt; methods that accept &lt;code&gt;Object&lt;/code&gt; parameters. Unfortunate, but not too egregious.&lt;/p&gt;

&lt;p&gt;The bigger disadvantage is that the string generation has to be inside a &lt;code&gt;toString&lt;/code&gt; method. While this can be done inside an anonymous inner class, the syntax for that isn't exactly convenient. If you have a bunch of log messages that are generated completely differently, then using anonymous inner classes everywhere will be far worse than just using the &lt;code&gt;if&lt;/code&gt; statements. Where it would make sense is if you have a bunch of log statements where the expensive portion of the message creation is the same.&lt;/p&gt;

&lt;p&gt;For example, you could replace this:&lt;/p&gt;
&lt;pre&gt;
if (logger.isLoggable(Level.FINEST))
{
   logger.finest("Stuff happened " + expensiveStringCreation());
}
if (logger.isLoggable(Level.FINEST))
{
   logger.finest("Foo happened " + expensiveStringCreation());
}
if (logger.isLoggable(Level.FINEST))
{
   logger.finest("Bar happened " + expensiveStringCreation());
}
&lt;/pre&gt;
&lt;p&gt;with:&lt;/p&gt;
&lt;pre&gt;
final Object msgFactory = new Object()
{
    public String toString()
    {
        return expensiveStringCreation();
    }
};
logger.log(Level.FINEST, "Stuff happened {0}", msgFactory);
logger.log(Level.FINEST, "Foo happened {0}", msgFactory);
logger.log(Level.FINEST, "Bar happened {0}", msgFactory);
&lt;/pre&gt;
&lt;p&gt;I'm assuming here that there's code in between these log calls that changes the state and hence the string returned by &lt;code&gt;expensiveStringCreation&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There's a lot of talk at the moment about adding closures to Java. Whatever ends up being adopted, this is definitely one of the scenarios it should assist with (although what I'm describing only requires the most basic capabilities of closures). I'm a fan of the &lt;a href="http://crazybob.org/2006/10/java-closure-spectrum.html"&gt;CICE&lt;/a&gt; proposal, although some of the objections raised seem valid. The CICE proposal requires an interface with a single method, so if we did have the &lt;code&gt;LogMessageFactory&lt;/code&gt; interface I proposed above, we could just do:&lt;/p&gt;
&lt;pre&gt;
logger.finest(LogMessageFactory()
    { return "Stuff happened " + expensiveStringCreation(); });
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/806077456733837244-716187787558248904?l=lachlanrambling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lachlanrambling.blogspot.com/feeds/716187787558248904/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=806077456733837244&amp;postID=716187787558248904' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/716187787558248904'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/716187787558248904'/><link rel='alternate' type='text/html' href='http://lachlanrambling.blogspot.com/2006/10/logging-vs-string-construction.html' title='Logging vs String Construction'/><author><name>Lachlan</name><uri>http://www.blogger.com/profile/13336649267304857235</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://static.flickr.com/42/83673461_67524e41a3_m.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-806077456733837244.post-5296866552136045466</id><published>2006-09-25T22:21:00.000+10:00</published><updated>2007-05-16T22:29:07.043+10:00</updated><title type='text'>XML vs Streams</title><content type='html'>&lt;p&gt;Ever get the feeling that XML sometimes makes things harder than they need to be? One of the problems that I and others have run into is that when parsing XML using SAX (or, in my case, using JAXB to unmarshall XML, which uses SAX under the hood) from an InputStream, the stream is always closed after the parsing is complete. This is surprising behaviour in Java, because you're not supposed to close streams you don't own. This can be a problem when &lt;a href="http://weblogs.java.net/blog/kohsuke/archive/2005/07/socket_xml_pitf.html"&gt;using network sockets&lt;/a&gt; or when you want to write two or more unrelated XML documents to the same stream.&lt;/p&gt;

&lt;p&gt;The root cause of this isn't anything in Java or SAX, it's the XML specification itself. There's simply no way to tell when an XML document ends. Every well-formed XML document will have an end tag, so you'd think the parser could simply stop when it reached the end tag. However, the XML specification allows for an arbitrary amount of comments and processing instructions to follow the main element. So when reading from a stream, the parser has no choice but to keep reading until it gets to the end of the stream. After reading to the end of the stream, SAX calls close on it. I believe the reason for this is that the stream has been completely read anyway, so there's no point keeping it open.&lt;/p&gt;

&lt;p&gt;I've had a couple of cases where I've wanted to write two or more independent XML documents to the same stream. In one case, I had a thread producing XML documents and writing them to a PipedOutputStream. Another thread would read from the corresponding PipedInputStream. The second case was a save file for an application that happened to include two unrelated XML documents. Because of the "uncertain ending" feature of the XML spec, neither of these things are possible.&lt;/p&gt;

&lt;p&gt;Not unless you use customised input and output streams, that is. After some searching, I found some classes from Xerces called &lt;a href="http://svn.apache.org/viewvc/xerces/java/trunk/samples/socket/io/WrappedOutputStream.java?revision=447688&amp;view=markup"&gt;WrappedOutputStream&lt;/a&gt; and &lt;a href="http://svn.apache.org/viewvc/xerces/java/trunk/samples/socket/io/WrappedInputStream.java?revision=447688&amp;amp;view=markup"&gt;WrappedInputStream&lt;/a&gt; that allowed me to do what I wanted. They actually solve the more general problem of reading data of unknown length without reading too much. I ended up writing my own implementations, but I used the same "protocol" as these classes. I can now read and write XML over streams without having to use a new stream for each document.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/806077456733837244-5296866552136045466?l=lachlanrambling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lachlanrambling.blogspot.com/feeds/5296866552136045466/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=806077456733837244&amp;postID=5296866552136045466' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/5296866552136045466'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/5296866552136045466'/><link rel='alternate' type='text/html' href='http://lachlanrambling.blogspot.com/2006/09/xml-vs-streams.html' title='XML vs Streams'/><author><name>Lachlan</name><uri>http://www.blogger.com/profile/13336649267304857235</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://static.flickr.com/42/83673461_67524e41a3_m.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-806077456733837244.post-1371099610857369630</id><published>2006-03-26T22:06:00.000+11:00</published><updated>2007-05-16T22:20:58.766+10:00</updated><title type='text'>Java's clone mechanism is teh suq</title><content type='html'>&lt;p&gt;Doing cloning properly in Java is way harder than it should be. I thought I knew all the traps, but recently found yet another. In a nutshell, making inner classes cloneable is almost always a bad idea. The reason is that inner classes have an internal reference to an instance of their enclosing class, which is implicitly final and can't be changed as part of a clone. For example:&lt;/p&gt;

&lt;pre&gt;
class Outer implements Cloneable
{
    int i = 0;
    Inner inner = new Inner();

    public Object clone()
    {
        try
        {
            Outer clone = (Outer)super.clone();
            clone.inner = (Inner)inner.clone(); // A.
                 Cloned inner still refers to this Outer instance
            return clone;
        }
        catch (CloneNotSupportedException e)
        {
        }
    }

    class Inner implements Cloneable
    {
        int j = 0;
        
        public Object clone()
        {
            try
            {
                return super.clone();  // B. WARNING!
                      - this does the Wrong Thing
            }
            catch (CloneNotSupportedException e)
            {
            }
        }

        void inc()
        {
            i++;
            j++;
        }
    }
}
&lt;/pre&gt;

&lt;p&gt;This code is attempting to do a deep clone of an &lt;code&gt;Outer&lt;/code&gt; instance, which requires a deep clone of the &lt;code&gt;Inner&lt;/code&gt; it references. The problem occurs at B, because the object returned by &lt;code&gt;super.clone&lt;/code&gt; refers to the same &lt;code&gt;Outer&lt;/code&gt; instance as the original. So if you do this:&lt;/p&gt;

&lt;pre&gt;
Outer outer1 = new Outer();
Outer outer2 = (Outer)outer1.clone();
outer2.inner.inc();  // will change i in outer1 instead of outer2
System.out.println(outer1.i);
System.out.println(outer2.i);
&lt;/pre&gt;

&lt;p&gt;You get:&lt;/p&gt;
&lt;pre&gt;
1
0
&lt;/pre&gt;

&lt;p&gt;Because the cloned &lt;code&gt;outer2.inner&lt;/code&gt; has an internal reference to the original &lt;code&gt;outer1&lt;/code&gt; instance. There may be cases where you want it to work that way, but it seems very unlikely. So what to do? Calling &lt;code&gt;super.clone()&lt;/code&gt; from an inner class is basically broken, and there's no way to fix it. If you're able to make the inner class final, this can be avoided relatively easily by using a copy constructor to clone the inner class instead of &lt;code&gt;Object.clone&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;
class Outer implements Cloneable
{
    int i = 0;
    Inner inner = new Inner();

    public Object clone()
    {
        try
        {
            Outer clone = (Outer)super.clone();
            clone.inner = clone.new Inner(inner);  // C.
                  Use "qualified" copy constructor
            return clone;
        }
        catch (CloneNotSupportedException e)
        {
        }
    }

    final class Inner  // no longer Cloneable
    {
        int j = 0;
        
        Inner(Inner inner)
        {
            j = inner.j;
        }

        void inc()
        {
            i++;
            j++;
        }
    }
}
&lt;/pre&gt;

&lt;p&gt;This gives the desired output of:&lt;/p&gt;

&lt;pre&gt;
0
1
&lt;/pre&gt;

&lt;p&gt;Check out the change at line C, it's actually valid syntax. It's called a "qualified" new, where you explicitly specify the enclosing instance of the new inner class instance.&lt;/p&gt;

&lt;p&gt;Using copy constructors for cloning is only OK for final classes, because they aren't polymorphic. If we had sublcasses of Inner involved here, then it gets harder - &lt;code&gt;Object.clone&lt;/code&gt; is the only easy way to get the right class instantiated. &lt;a href="http://www.jetbrains.com/idea/"&gt;Idea&lt;/a&gt; will actually give a warning on line C for this reason.&lt;/p&gt;

&lt;p&gt;Another, possibly better, solution is to make &lt;code&gt;Inner&lt;/code&gt; a standard (non-inner) class with an explicit, non-final reference to its &lt;code&gt;Outer&lt;/code&gt; instance. Basically, do the inner class stuff by hand. Because the reference to the outer class isn't final, it can be fixed up before returning from &lt;code&gt;clone()&lt;/code&gt;. Of course, this lacks to convenience that was the motivation for inner classes in the first place.&lt;/p&gt;

&lt;p&gt;More info on Java's cloning woes: &lt;a href="http://www.adtmag.com/java/articleold.asp?id=364"&gt;http://www.adtmag.com/java/articleold.asp?id=364&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/806077456733837244-1371099610857369630?l=lachlanrambling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lachlanrambling.blogspot.com/feeds/1371099610857369630/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=806077456733837244&amp;postID=1371099610857369630' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/1371099610857369630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/1371099610857369630'/><link rel='alternate' type='text/html' href='http://lachlanrambling.blogspot.com/2006/03/javas-clone-mechanism-is-teh-suq.html' title='Java&apos;s clone mechanism is teh suq'/><author><name>Lachlan</name><uri>http://www.blogger.com/profile/13336649267304857235</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://static.flickr.com/42/83673461_67524e41a3_m.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-806077456733837244.post-3982627755367047765</id><published>2005-12-23T00:07:00.001+11:00</published><updated>2009-06-01T21:50:13.913+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='exceptions'/><title type='text'>Handling InvocationTargetException</title><content type='html'>&lt;p&gt;A quick hint on handling &lt;code&gt;java.lang.reflect.InvocationTargetException&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This sucker is thrown whenever you invoke a method via reflection (typically via &lt;code&gt;Method.invoke&lt;/code&gt;), and that method throws any sort of exception. So it doesn't indicate a problem with the reflection mechanism, it is simply how the reflection mechanism notifies you of exceptions thrown by the method you called.&lt;/p&gt;

&lt;p&gt;Whenever you catch this exception (and you will have to catch it at some level), the first thing you should do is call &lt;code&gt;getCause()&lt;/code&gt;. This returns the exception thrown from the method that was invoked via reflection, and that's what you care about. So whenever you need to log or report an occurrence of &lt;code&gt;InvocationTargetException&lt;/code&gt;, always use the cause object rather than the &lt;code&gt;InvocationTargetException&lt;/code&gt; itself.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/806077456733837244-3982627755367047765?l=lachlanrambling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lachlanrambling.blogspot.com/feeds/3982627755367047765/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=806077456733837244&amp;postID=3982627755367047765' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/3982627755367047765'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/3982627755367047765'/><link rel='alternate' type='text/html' href='http://lachlanrambling.blogspot.com/2005/12/handling-invocationtargetexception.html' title='Handling InvocationTargetException'/><author><name>Lachlan</name><uri>http://www.blogger.com/profile/13336649267304857235</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://static.flickr.com/42/83673461_67524e41a3_m.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-806077456733837244.post-2435598487905811516</id><published>2005-12-22T23:37:00.001+11:00</published><updated>2009-06-01T21:50:34.174+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='exceptions'/><title type='text'>How not to catch Exceptions</title><content type='html'>&lt;p&gt;When it comes to bad Java practices, top of my list would have to be catching exceptions like this:&lt;/p&gt;
&lt;pre&gt;
try
{
   // stuff - anything really
}
catch (Exception e)
{
   // maybe log it if you're lucky
}
&lt;/pre&gt;

&lt;p&gt;This is usually done because the "stuff" throws more than one kind of checked exception, and the code to handle each case is the same. So what's wrong with it? The biggest problem is that this not only catches the checked exceptions you're interested in, but also all &lt;code&gt;RuntimeException&lt;/code&gt;s. The vast majority of &lt;code&gt;RuntimeException&lt;/code&gt;s are only thrown from buggy code, and catching them is rarely a good idea. The above catch handles all kinds of exceptions the same way, regardless of whether it was caused by a bug or an ordinary failure that can happen from time to time when a program is running (e.g. a network failure). This only obscures bugs.&lt;/p&gt;

&lt;p&gt;Consider the case where a bug causes a &lt;code&gt;NullPointerException&lt;/code&gt; to be thrown - perhaps the most common type of bug in Java. If the catch clause simply logs the exception message (not uncommon), then you have to check the log to have any idea why your app is misbehaving. And if you don't log the stack trace (again, not uncommon), you still won't have a clue what caused it. A much better option is to simply let &lt;code&gt;RuntimeException&lt;/code&gt;s go, which produces a screeching halt in your app and, in most cases, an immediate stack trace dump telling you exactly what happened. The details of what happens when you don't catch a &lt;code&gt;RuntimeException&lt;/code&gt; at all will vary depending on the environment you're running in, but it's always safe to do so. For example, servlet containers usually output the stack trace in the HTTP response when a servlet throws a &lt;code&gt;RuntimeException&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A good principle of catching exceptions is to only catch the those specific exceptions that you can actually deal with. E.g.&lt;/p&gt;

&lt;pre&gt;
try
{
   // stuff that throws AException
   // stuff that throws BException
}
catch (AException e)
{
    // deal
}
catch (BException e)
{
    // deal
}
&lt;/pre&gt;

&lt;p&gt;This way just deals with the exceptions that you can sensibly recover from and lets any &lt;code&gt;RuntimeException&lt;/code&gt;s that indicate bugs to be thrown to the caller. If the code to handle both &lt;code&gt;AException&lt;/code&gt; and &lt;code&gt;BException&lt;/code&gt; is the same, you could always move it to a method.&lt;/p&gt;

&lt;p&gt;"But what if the code throws, like, 10 different kinds of checked exceptions?". I've found it's actually pretty rare to have a block of code that throws more than about 4 unrelated checked exceptions. Some of the reflection APIs are pretty bad with this, however. It can be a pain to enter basically identical catch clauses for every one. A good alternative is:&lt;/p&gt;

&lt;pre&gt;
try
{
   // stuff that throws AException
   // stuff that throws BException
   // stuff that throws CException
   // stuff that throws DException
}
catch (RuntimeException e)
{
   throw e;
}
catch (Exception e)
{
   // deal with all checked exceptions in the same way
}
&lt;/pre&gt;

&lt;p&gt;This is actually not a bad way to get the best of both worlds (although I usually find it clearer to just handle each checked exception individually).&lt;/p&gt;

&lt;p&gt;I think in hindsight, the inheritance hierarchy of exceptions is backwards. Instead of the &lt;code&gt;RuntimeException&lt;/code&gt; extends &lt;code&gt;Exception&lt;/code&gt; extends &lt;code&gt;Throwable&lt;/code&gt; hierarchy, it should have been &lt;code&gt;CheckedException&lt;/code&gt; extends &lt;code&gt;UncheckedException&lt;/code&gt; extends &lt;code&gt;Throwable&lt;/code&gt;. That would allow catching all checked exceptions in a single catch clause, while not obscuring unchecked exceptions thrown by buggy code.&lt;/p&gt;

&lt;p&gt;In a similar vein, you almost never want to declare a method with &lt;code&gt;throws Exception&lt;/code&gt;. This is basically throwing away the whole checked exception system and saying "this method can throw any kind of exception". This tends to make exception handling in the caller painful, and may give the caller no good option but to declare &lt;code&gt;throws Exception&lt;/code&gt; itself. Before long, you end up with all your methods declared as throwing &lt;code&gt;Exception&lt;/code&gt; and you have little indication of what exceptions you might actually have to deal with at runtime. (There is an argument to made that checked exceptions are a bad idea altogether, but that subject will have to wait for another day.)&lt;/p&gt;

&lt;p&gt;There are a few cases where you might have a legitimate reason to catch &lt;code&gt;Exception&lt;/code&gt;, or &lt;code&gt;Error&lt;/code&gt;, or &lt;code&gt;Throwable&lt;/code&gt;. Here are some of them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When implementing &lt;code&gt;Runnable&lt;/code&gt;. Reporting &lt;code&gt;RuntimeException&lt;/code&gt;s thrown from &lt;code&gt;Runnable.run&lt;/code&gt; is a bit of a pain in Java versions 1.4 and earlier. It's often easier just to catch them yourself and log the entire stack trace somewhere it can't be missed. Java 5 has a nicer mechanism for doing this, however.&lt;/li&gt;
&lt;li&gt;When calling some sort of plug-in module. In this case, a bug in the plug-in doesn't mean the whole application needs to abort. You can catch the exception, notify the user, unload the plug-in and move on.&lt;/li&gt;
&lt;li&gt;When dealing with poorly designed APIs that throw &lt;code&gt;Exception&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/806077456733837244-2435598487905811516?l=lachlanrambling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://lachlanrambling.blogspot.com/feeds/2435598487905811516/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=806077456733837244&amp;postID=2435598487905811516' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/2435598487905811516'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/806077456733837244/posts/default/2435598487905811516'/><link rel='alternate' type='text/html' href='http://lachlanrambling.blogspot.com/2005/12/how-not-to-catch-exceptions.html' title='How not to catch Exceptions'/><author><name>Lachlan</name><uri>http://www.blogger.com/profile/13336649267304857235</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='25' height='32' src='http://static.flickr.com/42/83673461_67524e41a3_m.jpg'/></author><thr:total>0</thr:total></entry></feed>
