Note: This is an experimental site, if you have a feed you would like to add or you would like your feed to be removed please contact me.

Planet 5

May 17, 2012

codegrunt.co.uk

What's the Appeal of Programming?

A Quick Aside

Before I get stuck into this post, I want to quickly mention my last. It got to the front page of Hacker News and stayed there for around a day. I submitted it on a whim and did not expect it to get even the slightest bit of attention. Thank you everybody who upvoted it, I am amazed and humbled that people found it (at least somewhat) interesting.

I fully intend to investigate the issue further and to write a follow up. There were some great comments on the Hacker News thread and on the article itself - leads for further research.

I also want to make it clear that the items listed on my upcoming post are coming, however the posts on that list require a fair bit of work and I want to make sure they’re as good as I want them to be. In order to stick to my promised post/week I need to ‘buffer’ a number of meatier posts, meanwhile I am going to throw out ideas I’ve wanted to express for some time.

The subject of today’s post is one of these things I’ve wanted to write about for a while and by coincidence there was a recent HN furore regarding Jeff Atwood’s latest blog post - Please Don’t Learn to Code - which addresses related issues, so I was motivated to write this now. I will try to pull the threads together.

Why Do I Code?

Growing up I spent a lot of time playing around with BASIC on my ZX Spectrum, and more than anything got a massive kick out of seeing this stuff actually do something, actually working on my computer. It was so satisfying.

Ever since, it has been that kick of seeing something actually come together, actually doing something which has driven my interest in computing. It might sound petty, but this thrill has never quite left me, and I really do think it lies at the heart of the pleasure of the thing. To quote edw519:-

The best part is getting something working for the first time where nothing was there before. For me, this is so exciting that I still I do a “happy dance” every time.

One utterly delightful aspect of programming is how low the barriers are to building things. If you wanted to design and build a car, say, you’d need lots of money and lots of people and a funnelling process from idea to physical reality to achieve your dreams, with plenty of difficult compromises in between. You’d certainly find it incredibly challenging not to mention expensive to try this on your own, to the extent it would be rather mad to try it at all.

Compare this to programming - all you need is a computer - even an ultra-cheap laptop is sufficient, and that combined with the web and all the free material out there is enough to get you from any level to really rather proficient limited only by your attitude and hard work. I can think of nothing else quite like it.

Fred Brooks put it far more eloquently than I ever could:-

The programmer, like the poet, works only slightly removed from pure thought-stuff. He builds castles in the air, from air, creating by exertion of the imagination. Yet the program construct, unlike the poet’s words, is real in the sense that it moves and works, producing visible outputs separate from the construct itself. The magic of myth and legend has come true in our time. One types the correct incantation on a keyboard, and a display screen comes to life, showing things that never were nor could be.

Solving abstract problems with few constraints while still actually having an impact on the real world is a large part of the appeal of programming. It’s important not to forget what a miracle this stuff is - we build things which ‘exist’ in what amounts to an imaginary world of electrons travelling around lumps of transmuted sand which somehow do things which people find useful, so useful in fact, that these ghosts in the machine have utterly revolutionised the world and continue to do so at an ever increasing rate.

Programming and Talent

It is my strong conviction that talent and intelligence are the smallest components of the make up of a good programmer. I do believe they make a difference, but are important to a lesser degree than many think.

You need to be able to think logically and be capable of keeping a certain degree of state in your mind, that’s the talent of it, and you need to be bright enough to explore a problem sufficiently to find a solution, which is where the intelligence lies. But these are only pre-requisites. If you have enough of both, then you are going to be able to program (it turns out that a surprising number of people cannot, though to what degree that is talent vs. attitude I dont know.)

Attitude is the really crucial component. The vast size of the subject matter and the vast complexity of the machine in front of you means hubris is the biggest error you can possibly make. You will make mistakes, do stupid things, and misunderstand what the computer is actually doing much of the time. The vital attitude to have in facing this reality is to remain humble. As Dijkstra put it:-

The competent programmer is fully aware of the strictly limited size of his own skull; therefore he approaches the programming task in full humility, and among other things he avoids clever tricks like the plague.

A programmer who lacks this humility can be absolutely nightmarish to deal with. Mistakes get brushed under the carpet, code remains an awful unmaintainable mess because ‘it works’ and that’s sufficient (that whole subject is likely to be an entire other ranty post), and things never improve because the first step in improving something is to admit that there’s something which needs improving. You can’t suck less every year without admitted you suck in the first place.

The other, slightly less important, but still critical component of being a good programmer is hard work. Things are always harder than they seem. Any non-trivial problem you’re dealing with will screw you over repeatedly before you solve it, and not until you’ve felt like giving up 3 times will it finally decide to behave. Oh, and the final 10% of the project will take 90% of the time. You just have to keep on going.

This latter point is in fact a lesson I’ve had to learn the hard way with personal projects. I have started several highly ambitious projects, only to hit problems early and give up (‘hey this is meant to be a hobby, this is no fun!’, etc.) - my chess engine project, weak, may be progressing slowly, but it is progressing and I refuse to give up on it.

Another skill which matters rather a lot is the ability to communicate. If you can’t communicate your great idea or the fatal technical flaw in a proposed plan, then no matter how able you are as a developer your voice just won’t be heard. Also, if you can’t communicate well it’s a lot easier to end up in realms of unpleasantness with others, which gets in the way of everything.

Storm in a Teacup

Back to the furore. I strongly believe that programming should be open for all, and new programmers welcomed with open arms. This thing is amazing and nobody has the right to tell anybody that they can’t choose to learn this craft and get that wonderful kick out of making computers actually do stuff. The fact that there has been a big movement to spread coding knowledge is great, the more the merrier I say.

Having said that, I think Jeff has hit on an inconvenient and slightly unpalatable truth which strongly links back to the two crucial characteristics of a good programmer. What we emphatically don’t need are new programmers who believe programming is incredibly easy yet wonder why their spaghetti monster runs so slowly, or managers who learn to write a very simple rails app and therefore get to treat you with less respect because it’s ‘all so easy’. Most of all, we don’t need people thinking developers are fungible commodities, because that simply ain’t so.

What’s needed is humility, commitment, and an understanding that it takes many years to become truly proficient at this craft.

Another uncomfortable truth is that we professional programmers often feel threatened by the idea that all these young whippersnappers might come in and make us look incredibly stupid and redundant. The nightmare scenario of an inexperienced guy coming in and doing in 1 week what took you 4 months is not a pleasant thought.

The solution is to not attach your identity1 too closely to your code. You are not your job. Personally I’ve found this a very hard lesson and it’s something I still struggle with2, but forming this separation is so clearly the answer that it’s worth the struggle.

Try to be the best programmer you can be. Focus on creating solutions to people’s problems because that’s ultimately what matters, but don’t forget that maintainability matters too and code quality informs a lot of the externally observable quality of your solution.

Have fun. Build stuff you’re proud of. And above all else, be nice to other people who are also trying to improve themselves. I know I fail at that often enough myself, and it can sometimes be incredibly difficult, but ultimately we are all idiots, so the best we can do is to try and help each other be a little less stupid.

Notes

1

I reference this post in order to give credit where it’s due. I want to make it clear that I actually strongly dislike the tone of Zed Shaw’s blog post, not to mention many other occasions where he’s, in my opinion, acted in rather a bullying fashion (e.g. this and of course this). He is a great programmer, and his books are equally brilliant, but his behaviour towards others is not.

As I commented on hacker news, my perception of that kind of bullying nastiness put me off working on anything public for a long while. I take responsibility for my lack of productivity, but that kind of attitude certainly didn’t help anything. I don’t think it helps anybody.

2

I don’t want to be too much of a pop psychologist, but I do wonder whether the stereotypical experience of feeling somewhat inadequate at school while finding a means of gaining a sense of value via programming/working with computers binds self worth to your work early on. Of course, this is by no means the experience of all programmers out there, but I do think it is the experience of a fair few, including myself.

May 17, 2012 11:00 PM

May 12, 2012

Going Along

走过这个城市


走在丝雨中,完全没有赶路的意思。一种安心,让我醉了。是陶醉在满足里。

走在从美术馆回来的路上,再次驻足在那家咖啡店的外面。已经要打烊了。女主人还在忙着。临街的座位,就是我带走满意的地方。

结帐时,我轻轻的问:“请问到底Forty Cafe里加了什么果实“?她答:”就只是这种高级的Espresso独特的香味。“。她朗朗的笑了一下。笑走了刚才满脸的倦意。是的,再用心做同一件事,久了也是无奈的疲态。但只需客人能略微的感动,就值回全心的付出了。

是一种什么样的感觉?那味道是直达舌底的,很熟悉又不能想起。一次次的抚起杯子,让那香气帮我回忆。慢慢一口一口的咽下,舌跟挥之不去的思绪。淡淡的甜,但带着浓郁。是了是了,是小时候留口水的烤地瓜的味道。

问好了去国美的路,目的是寻找这间咖啡店。刚好赶在饭口前,也因为没有预约,只能沿窗一排坐下。选好了生菜沙拉,清口。然后是一碗玉米粥配烤面包,适口。再下来主菜沙朗鹅肝。这时天已经完全黑了,店里也是满满的。但丝毫没有喧哗。大家都静静的交谈着,夹杂着轻碰玻璃杯的悦耳。忽然觉得腿有些麻了。原来是保持一个姿势太久了,太专注于沙朗的嫩和鹅肝的滑了。

”台中有些慢,还有些人情味在。“昨天回来时,计程车司机说。他以为我从台北过来,一路和我慢慢的聊着。讲着小时候还能搭公车,可现在捷运还不知何时建好,公车也越来越少。每台车都等在场里,等着附近的电话招呼。满街都是小摩托。那我那天从逢甲夜市出来,能在交通灯口拦下一辆空车,是幸运的了。

更幸运的是我能系上安全带。今天的计程车突然刹停。我的电脑包重重地甩到座位下。我也猛地从沉迷的书中抬起头来大喝怎么啦。司机大叔连声对不起,走下车,从路上拾起一个铁笼子,帮前面比卡的司机搬上去,却完全没有责怪的意思。这是个包容的城市,狭窄的路上忙乱的车流大家彼此迁就着。我也就不能再发作什么了。

但也不尽然,前天的路险可是让我Oh My God。同事开车送我,就惊见一辆红色小面包突然从拐角冲出来,闪过一个要横穿马路的摩托,擦着我们就跑远了。Oh My God。几乎就撞到那个万幸的骑士,几乎我就亲眼目击一桩惨祸。

今天的电视新闻,一辆花莲的旅游车,爬山路时换档不慎失去动力,载着13名南韩游客下滑翻覆到28米深的溪谷。万幸有树木拖住在8米处,又有一个管理员碰巧经过及时报警救援,得以保全每个人的生命。管理员的车载镜头录像了整个过程,使我们得以亲眼看到别人的不幸万幸,再庆幸。

又是一场不幸,雪山隧道猛烈燃烧一户人家化为碳与青烟,小孩无从辨认需DNA验证。为什么这两天台湾事故连连?其实这世界每时每刻都在重复着幸与不幸的故事,只是没有人强迫我们做我们旁观者。来了台湾才发现媒体上充斥的都是这些负面,或者是一些喧哗燥浮。不。这肯定不是全部。至少我亲眼亲身的是一个和善安逸的社会。

刚到台湾的第二天就去了日月潭。潭不大也不惊艳只是静静的绿水既不像日圆也没有月弯。和本岛游玩的人一样我租了一辆单车,就在和风煦日中远离了大团的游客。沿湖边一路骑行,轻松自在。偶尔停下看看,照个照片。偶尔猛骑一通,感受一下风的力度。不觉得3km的单车道到头要回头了,就不加思索的把车推上了山,准备来个33公里的环湖一圈。之前在游客中心问过要4个小时,也没注意到自己还穿着上班的牛仔T-shirt。等满身大汗气喘连连的爬到山顶,才后悔没换上短装。只好卷起裤腿坚持下去。还好下去的一路飞驰的痛快让我忘了刚刚的辛苦无奈。这样一路滑到12Km处,又是一段长长的上坡山路。37速的捷安特山地车也骑不动了,只能慢慢推行。沿路对面有些飞行而过的快乐骑士,还有个老太太冲我喊加油。感觉这到10Km处的两千米最为吃力。还好又是一路下坡直到玄奘寺渡口。当然想都没想做船横渡回去,还剩10公里已经想着老太太给的鼓励又上路了。这段上坡好辛苦,又要躲着大小汽车,又要担心峭壁的落石。还好带够了水一路不停地喝,又吃着飞机上留下来的杂果,熬过了午餐时段的饥饿,一路上上下下地到了尹达邵渡口。吃了山猪肉串和皮串,买了猫头鹰纪念,看看表已经骑了3个小时了,这剩下6公里的山路就坚持吧就坚持到了终点。车店的老板娘夸我厉害我只能苦笑着说很好玩然后等着晚上精疲力竭地和老婆Skype时再被夸赞损我go nuts。

-- fango

by Fango (noreply@blogger.com) at May 12, 2012 11:53 AM

浪费半天在台北

6:40起床吃已经吃了七天腻到不行的饭店早餐。想到中午吃好点儿吧就几乎饿着check out搭计程车240元到高铁,用机器买8点的票到台北700元。一路翻译'银河搭车手册'转眼到站好像是9点。出站就直奔地图搞清楚捷运出口却发现搭669号公车也到101还能看街景就花了好长时间才找到Y8出口又等了更长时间才发现这号车40分钟才一趟直站到两腿发麻找个石凳坐下就这时来车了。已是10点了不过车票超级便宜15块就一路摇晃着看到了101就急忙下车了。正碰到new ipad开卖十几个模特摆pose就跟着媒体疯照了一通。信步走入101直奔5楼的观景售票点450元,但回身看到长长喧哗的观光队伍就立马没来兴致。发现旁边有寄存箱自设密码不要钱也没人用,就把沉重的电脑包扔进去一身轻松的window shopping lv channel等等国辱太太的最爱。没啥看的就下楼吃鼎泰封小笼包和最贵的450块5个的松露包饱餐之后就搭免费公车到捷运站。心想着抓紧时间到高铁的诚品买本书就按机器35块到板桥站。车过台北火车站时我不安了一下可是因为正忙着打这些字就一路出来捷运直奔高铁售票机器,看表是12点半就买1:44的票130元才突然发现我没去台北站却到了下一站新北。罢了罢了走到哪算哪开始绝望的到处转希望也能找个书店。这里可是啥都没有双肩开始发沉就走到检票口的长椅子上坐下把这段在手机上写完。写到1:15为打发时间就谈谈今天联合报发表的韩寒的博客讲他喜欢台湾人感谢港台保存了中华文化欲言又止。我可能可以说得更好但我不学鲁迅了投匕首被人捧痛苦到自己抽到烟死。1:30到起身等车10分钟就到了桃园。 顺便到华行柜台办理登机。要有行李在此托运快过到机场办理。坐公车30元到机场我还在坐着记录下这些文字。2:25到3:35才登机就在一家餐厅门口坐下享用他们的无线网络。下次来台北怎么也要住宿一晚,这是个越夜越美的城市好像每个人都要街上逛逛买些小吃走走看看打发时间。这次只是过路就在手机是草草记录也是打发时间吧。胡言乱语就此EOF。

by Fango (noreply@blogger.com) at May 12, 2012 09:13 AM

May 07, 2012

codegrunt.co.uk

The Brittleness of Type Hierarchies

In this post I explore what I perceive to be a fundamental issue with object orientation via a type hierarchy.

Apologetic Preamble

I want to make it clear that this post is emphatically not an attack on C# (a language I admire1), nor is C# the only language to implement type hierarchies (java is a better-known language which takes this approach), rather it’s a criticism of a general trait of the kind of object orientation implemented2 by languages like C#, which due to my familiarity with it is the language I use in this post to explore my point.

The Problem

When you write a program using a C#-like language you typically start by modelling your problem as a hierarchical set of classes which represent your domain. You then procede to ‘flesh out’ and expand upon these types with code which actually implements your program.

After a while you inevitably find an exception to the rules of the system you have created - your types turn out not to match the problem in some way. Typically this occurs later after a lot of work has already been done which is now strongly tied to the structure of your type hierarchy, so you are left with a problem - do you hack around the incongruity, usually the quickest solution, or restructure your types to adapt to the new requirement?

If you choose the former your hierarchy not only fails represent the problem anymore, it actively misleads you about it. If you choose the latter, you end up spending a long time yak shaving - working on something which has absolutely nothing to do with the problem itself and is purely a product of the system in which you are writing your program - the very definition of accidental complexity.

A Concrete Example

To explore this problem more concretely, let’s take a look at an actual example.

Note that, whatever example I choose, it’s inevitable that it will not fully capture this problem the way architecting a big project under deadline pressure will. However, exploring actual code is of such value that I think it worth doing regardless.

That said, let’s consider a type hierarchy which represents trades made on financial exchanges:-

class Exchange {
    public string Bic { get; set; }
    public string Name { get; set; }
}

abstract class Security {
    public string Description { get; set; }
    public Exchange Exchange { get; set; }
    public string Isin { get; set; }
}

class Stock : Security {
}

class Bond : Security {
    public DateTime Expiry { get; set; }
}

class Trade {
    public decimal Price { get; set; }
    public decimal Quantity { get; set; }
    public Security Security { get; set; }
}

So far, so good - this seems like a sensible approach and so we go ahead and write a lot of code around this hierarchy.

The code gradually becomes deeply coupled to our type design - we expect all financial securities to possess an ISIN (an international identification number), a description and an exchange which itself possesses a name and a BIC (bank identification code), we expect stocks to possess no extra properties, bonds to possess expiry dates, and trades to possess a security, price and quantity. The client is happy, the system works well and your code is nice and clean.

Suddenly the client demands a change - they are about to trade options and need to bring them into the system. Fine you think, so you come up with a class:-

class Option : Security {
    public bool Call { get; set; }
    public decimal LotSize { get; set; }
    public DateTime Maturity { get; set; }
    public decimal StrikePrice { get; set; }
}

But a problem arises - options are typically not assigned ISINs, and now we have a property which is meaningless for options. We are faced with the dilemma - a lot of the code is now reliant on Isin, and NullReferenceExceptions are getting thrown all over the place because the field isn’t getting populated. Do we remove the Isin field from Security and create a separate classification between physical and derivative securities (or perhaps ISIN-possessing instruments and non-ISIN-possessing instruments) - one containing Isin and one not? Or do we find some other, less salubrious way around the problem?

The client is getting angry now - there’s a hold up, developers are arguing about what to do, and the trading systems needs to be in place by the next day or some P45s are going to be handed out. So it’s decided - quick-fix now, real fix later:-

// Lots of:-
if(security.Isin == null) {
    ...
}

// Not to mention:-
if(security is Option) {
    ...
} else {
    ...
}

// And maybe even some:-
switch(security.GetType().Name) {
    case "Option":
        ...
    case "Stock":
        ...
    ...
}

Our code is suddenly not looking so great. Our type hierarchy now falsely implies that all securities have ISINs, a particular issue for developers new to the project, we have hacks all over the place, maybe not enough (we’re fairly sure we got everything but there are always those nooks and crannies which slip through the test suite), we are forced to add new hacks as we go and confidence in our code is definitely eroded.

Suddenly a new requirement arises - it turns out securities need to refer to traded exchange which might be different for two otherwise identical securities, but our architecture has lumped exchange with securities. We are back to our dilemma again…

An Imperfect Example

Again, I emphasise that the above example is necessarily imperfect, as to practically fit an example of this problem into a blog post necessitates quite some trivialising. That being said, hopefully it makes the point a little more concrete.

An objection here might be that these change requests merely exposed design mistakes made early on in the project whose impact inevitably got magnified down the line as code was written on the assumption that these mistakes were in fact valid. The problem with that argument is to me the problem with the waterfall method for software development - it assumes you know a great deal up front, something which is very rarely the case.

The reality of software development is almost the opposite of that assumed by approaches which require large amounts of upfront structural foundations to be laid. Requirements and facts around your code tends to change constantly and often in utterly unexpected ways, so having a structure up front which lays down brittle laws about your system is setting yourself up to fail.

The brittleness of the laws is the real issue - if their failing didn’t result in hacks or yaks then there wouldn’t be as much of a problem.

Solutions

I hate to state a problem without suggesting solutions, I am after all a programmer, and our job is to solve problems, not just create them.

I am certainly not suggesting that object orientation is somehow fundamentally flawed, nor am I advocating writing code procedurally when it could benefit from the encapsulation, abstraction and de-duplication of an alternative approach purely out of FUD about potential future issues, rather I think that if you are going to write in a language which supports this approach it’s important to consider this issue before committing to representing your problem this way.

Some ideas:-

  • There are methods and patterns for separation of concerns and decoupling of related code, including techniques like dependency injection, which may help mitigate this problem to some degree while still using a C#-like language.

  • Functional programming is enjoying a great upswing in interest and popularity these days. I wonder whether the stronger type systems of these languages and the greater guarantees about what a function does/does not do (i.e. less likely to produce side-effects, immutable state) might provide a means to more quickly adapt a change to the model at compile- rather than run-time.

  • Bottom-up programming in a language like Lisp offers an enormous amount of flexibility in meta-programming and might make downstream changes easier to introduce later in the development process.

  • Dynamic programming languages like Python, Ruby and Lisp provide a far less rigid type structure - types don’t necessarily need to be known at compile time, meaning you have a great deal of flexibility to write functions which are less tied to a previously-determined structure than in a statically-typed language.

  • Go provides an intriguingly simplified version of static typing where no type hierarchy is permitted to be defined at all, rather you express relations between types through implicit interfaces which define types through what they do rather than what they are. They are implicit in that as soon as you’ve defined what you want, i.e. what methods a type possesses, then any type which possesses those methods implements the interface.

  • Smalltalk implements object orientation in quite a different fashion from C#-like languages, with emphasis on passing messages between objects rather than the structure of the classes themselves. This could help reduce the dependency on initial structural decisions.

  • (ECMA|Java)script allows you to define relations between objects based on object prototypes rather than static classes, you simply can’t declare static user-defined types at all.

I don’t want to advocate a particular solution above any other, as I am still undecided and exploring these ideas myself, not to mention the fact that a lot of this stuff sits decidedly in the grey area of rather subjective choices where it’s hard to definitely prove one approach is better than another.

I do however think that the brittleness of the upfront type hierarchy is a real issue which needs to be carefully considered before writing a large program and weighed up against other engineering approaches.

Notes

1

I have spent several years working with C#. Overall it’s a fantastic language which has grown ever more fantastic over time. Starting as, frankly, Microsoft Java, it has grown to incorporate generics, better support for functional style programming through a neat lambda syntax, libraries offering standard functional-style methods such as map, filter and fold (select, where and aggregate respectively in C# parlance), a declarative syntax for querying generic collections via LINQ as well as numerous other little features which make it a very nice language to work with. It’s well-engineered and surprisingly ambitious.

2

I say this, rather than just saying ‘I have a problem with object orientation’, as there are different interpretations as to how object orientation should be implemented, and a C#-ish implementation is just one approach - cf. smalltalk.

May 07, 2012 11:00 PM

May 02, 2012

golang.jp

翻訳更新のお知らせ

Goプログラミング言語仕様の翻訳を最新にアップデートしました。
細かい更新箇所は多いのですが、前回の翻訳からの変更点は以下です。

  • マップの要素を削除するdelete組み込み関数が追加された。
  • rune型(他言語のchar型のようなもの)が追加された。
  • init関数内でゴルーチンが起動できるようになった。
  • 標準関数が返却するエラー情報は、新たに追加されたerror組み込み型を使用するようになった。

 ※2012/5/9 タイプミスを修正しました。報告いただきありがとうございました。

by noboru at May 02, 2012 05:44 PM

April 25, 2012

codegrunt.co.uk

Upcoming

Okay, so I haven’t updated this blog in quite some time.

I don’t want to become one of those people whose blog consists of very few blog posts, mostly apologising for not blogging more, so I’ll keep this short and sweet and simply announce some posts I’m working on:-

  • Why Go? - A post discussing the merits of Go and what makes it different from other programming languages.

  • Series: Algorithms - A series of posts on algorithms of interest, with a focus on exploring how you go about actually implementing them in code.

  • Series: Go Standard Library - A series of highly indulgent posts exploring Go’s standard libraries and how they are actually implemented in practice, in the vein of Jeff Atwood’s and Scott Hanselman’s recent posts on reading other’s source code.

  • Series: Go Internals - A series of yet more indulgent posts exploring Go’s internal implementation details.

  • Series: Weak and Chess Engines - A series of posts on the implementation of Weak and chess engines in general.

  • General Programming/Personal Topics of Interest - Basically whatever I happen to be thinking about at a given point. I think about programming a lot, and I think it’s time to put it out there, whether it’s coherent or of interest to other geeks out there, or not :-)

I am committing to getting at least one blog post out a week. I intend to fill my blog with exactly the kind of stuff I love reading in other people’s blogs - lots of juicy, no messing about, unix-bearded, hardcore tech detail and geekery with pride.

Sorry Brogrammers, I’ve got nothing for you.

April 25, 2012 11:00 PM

April 24, 2012

golang.jp

翻訳更新のお知らせ

久しぶりの翻訳更新です。
Go言語のインストール
の翻訳を更新しました。

いままではGo言語をソースファイルから自分でコンパイルするしかなかったのですが、Version1からバイナリで配布されるようになりました。また、Windowsも正式にサポートされるようになりました。

 

 

by noboru at April 24, 2012 08:53 AM

April 22, 2012

Kyle Lemons

Rx: My prescription for your Go dependency headaches

XKCD: Online Package Tracking

Oddly appropriate, don't you think?


There has been a lot of discussion on the Go Nuts mailing list about how to manage versioning in the nascent Go package ecosystem. We muttered about it at first, and then muttered about it some more when goinstall came about, and there has been a pretty significant uptick in discussion since the go tool began to take shape and the Go 1 release date approached. In talking with other Gophers at the GoSF meet-up recently, there doesn’t seem to be anyone who really has a good solution.

TL;DR: kylelemons.net/go/rx

The Problem

Before I get too far, let me first summarize the problem.

When developing a Go application, you will most likely find yourself depending on another package, often written by another author. The ease of utilizing such third-party packages with the go tool makes this an even likelier scenario, and it is, in fact, encouraged. Inevitably, however, the author of some package on which you depend will make a change to his package; this could be anything from an innocuous bug fix to a large-scale API reorganization, and you are suddenly left with two choices: stick with the version you have (often by cloning it locally) or bite the bullet and update. This is complicated by the fact that you may both directly and indirectly depend on the same package, which means that both your project and your intermediate dependency need to agree on which of the above choices to take, and in a relatively timely manner.

There have been many proposals and complaints, both on- and offline, with respect to this problem. It’s not a problem that’s unique to Go, either; tools like Apache’s Maven, Ruby’s Bundler, etc all attempt to solve this problem to a greater or lesser degree. It is such a prevalent theme in development that a term, DLL Hell (and the more technically correct term dependency hell), has come into common use to describe it.

Strategies

The most obvious thing to do is to be paranoid about package maintainers, and thus copy your dependencies into your project. If this strategy is sufficient, I highly recommend checking out goven, which will streamline this process (it even rewrites the imports!) for you. I take a different tack because I am lazy and don’t want to have to maintain other people’s code. I also don’t think this strategy simplifies the process of pulling in new changes from upstream, because you still have to update them one at a time until/unless something breaks.

The next obvious thing is to specify somewhere what version you want to check out, in the source code, so that go get knows about it and can do the right thing. This essentially boils down to something like import "path/package/version" (though various proposals suggest using @rev or similar). This is certainly a solution, and I suspect we will see tools emerge that will download source and update it to the proper revisions as a go get alternative. I didn’t choose this solution because this requires rewriting import paths when you update code and it makes it difficult to ensure that there is only a single version of a library built into the same binary, which can cause problems (if there are more, the init() calls will run twice, for one thing). It also doesn’t help with pulling in changes: you still are taking a chance that you’ll break something (sometimes without realizing it) whenever you pull from upstream.

Another reasonable strategy is to version-control the entire (or at least the dependencies within) GOPATH(s). This has the advantage that multiple developers always check out the correct versions, and branches and merges work nicely. A very simple tool along these lines is being developed as gogo, which allows you to version control your dependencies and share them between developers. As long as your version control system doesn’t mind having other version control systems’ (or its own) metadata stored inside it, this will work. The downside of this is that you are storing a lot of redundant data in your vcs, and it still doesn’t address the issue of how to figure out when and if you can update what packages.

Enter `rx`

So, since my ancient pre-goinstall build tool has been obsoleted, I figured I’d try my hand at distilling a reasonable, achievable set of goals out of the sea of requirements and suggestions and turn them into a tool for people to use. If you didn’t guess this from the previous section, the biggest problem that I think I can solve is helping you figure out what dependencies you can update without breaking your world. This can probably work in addition to at least a few of the strategies listed above for a more complete versioning solution, depending on your particular needs. Here are my informal design ideas/goals/requirements/notes:

  1. It shouldn’t try to “solve” dependency hell. Making people’s lives easier is enough for now.
  2. It should leverage the existing go tool and GOPATH conventions as much as possible.
  3. It should be easy to see the versions of packages, and to change the active one.
  4. It should be intelligent about updating and notice when an update breaks something else.
  5. It should be able to save a “known good” set of versions for easy rollback and sharing.
  6. It should be fun to use, and should not get in the way of the developer.

In that vein, I have started work on rx, my prescription for your Go dependency version headaches. It’s starting to approach a few of the the requirements above already. To whet your appetite, here are a few examples of what it can do:

  • rx list will show you inter-repository dependencies
  • rx tags will show you the what tags are available in a repository
  • rx prescribe will update a repository and test its transitive dependents

Each command also has plenty of fun options to play with; rx tags has, for instance, options to only show tags that are up- or downgrades. The structure of the program is strongly reminiscent of the design of the go tool (and, in fact, uses it for a lot of backend logic), and so should be familiar for most Gophers and fit nicely into your existing workflows.

Installation is, of course, rather simple:
go get -u kylelemons.net/go/rx

Here’s a brief example of using rx:

$ rx --rescan list | grep rpc
/<gopath>/src/github.com/kylelemons/go-rpcgen: codec webrpc main main echoservice main main offload wire webrpc
$ rx tags go-rpcgen | egrep v\|HEAD
193746c88dfebdc5462382b93c1038a29496d9af v2.0.0
a6938fa6ec0fb6a63fefab2c462d3cd1102cc477 v1.2.0
bf28cdf3e683dd0919800f6916141c17aa93c36d HEAD
bf28cdf3e683dd0919800f6916141c17aa93c36d v1.1.0
f73c5c8ea85bdfbdc69e6aa24dd90b43c7265c67 v1.0.0
$ rx pre go-rpcgen v2.0.0
ok      github.com/kylelemons/go-rpcgen/codec   0.051s
ok      github.com/kylelemons/go-rpcgen/examples/echo   0.139s
ok      github.com/kylelemons/go-rpcgen/examples/remote 0.019s
ok      github.com/kylelemons/blightbot/bot     0.029s
ok      github.com/kylelemons/go-paxos/paxos    0.053s
$ rx tags go-rpcgen | egrep v\|HEAD
193746c88dfebdc5462382b93c1038a29496d9af HEAD
193746c88dfebdc5462382b93c1038a29496d9af v2.0.0
a6938fa6ec0fb6a63fefab2c462d3cd1102cc477 v1.2.0
bf28cdf3e683dd0919800f6916141c17aa93c36d v1.1.0
f73c5c8ea85bdfbdc69e6aa24dd90b43c7265c67 v1.0.0
</gopath>

There’s not a whole lot here, but you can see that the list command (in its short form) found the repository and listed the (short) names of the packages that exist under it. The --rescan option told it to actually scan my repositories, instead of using the cached dependency graph. The tags command then showed me the interesting tags in the repository (it’s git, so HEAD also shows where it was currently), and then the prescribe command updated it to the latest tag. Notice that the repository’s tests were run, as well as tests for packages that depended on packages in that repository (transitively). They were also built and installed (except binaries, by default), though this isn’t displayed unless you use the -v option.

Expected Use Cases

To help elucidate the problem I’m trying to solve, here are a few use cases that I’d like to support.

Hobbyist Developer

As a single developer, you’ve probably got a single GOPATH into which all of your dependencies are installed alongside your own projects. You freely import between them, and everything generally works. You don’t run go get very often to pull down remote packages, unless you find a bug that has been fixed or you find a new feature in a newer library.

  • The rx fetch command will let you fetch the latest changesets without actually applying them.
  • The rx tags --up command will show you what tags you can upgrade to.
  • The rx prescribe command will allow you to update to a new tag.
  • The rx prescribe command automatically builds and tests depenants transitively.
  • The rx prescribe command will roll back the update if it turns out to have broken something.

Small Team

As a small team working on a Go project, your concerns are much different from that of a single developer. You want your team members to easily stay in sync with one another, and you will only rarely pull changes in from upstream once you have your project working with a particular dependency.

  • The --rxdir flag and RX_DIR environment variable let you version or share an rx configuration.
  • The rx cabinet --save command saves the versions of all repositories.
  • The rx cabinet --load command reverts/upgrades repositories to their saved state.
  • The rx cabinet --export command saves a relocatable cabinet that can be sshared.
  • The rx pin command lets you configure what repositories are considered for upgrade.
  • The rx auto command will try to upgrade packages automatically, keeping seamless upgrades.

The common theme among these commands is maintaining a cohesive group of dependency versions. When you update a dependency (which we’ve seen that rx prescribe can do automatically), you can save that as a “known good” configuration that you can share, save, and (if things go south) restore later. For packages that are known to misbehave or for the package you’re editing, the rx pin command allows you to specify manually what behavior they should have (never upgrade, always tip, never change, etc). To help with exploring what updates might apply seamlessly, the rx auto command will do the heavy lifting of figuring out which repositories depend on each other and will successively try updates.

Large Project

On a large project, you care about most of the same things as a small team, but there is also a good chance that you are working on multiple versions of your software simultaneously. There is also a good chance that any given developer may have multiple projects on his workstation which are independently versioned.

  • The rx cabinet --exclude command (and friends) configure exactly what cabinets track.
  • The rx cabinet --diff command shows differences in dependencies between cabinets.
  • The advanced rx prescribe optiosn can manage package upgrades auto can’t handle.

The theme here is that the same commands that worked in a small and medium environment continue to work, but that their concepts can be extended (and modified slightly) to accomodate the needs of a larger development team. The larger the team is, the more chances are that there will be multiple branches in play, and rx will need to understand this.

The Catch

There are still problems with this approach. As long as you start with a working project, you should generally be able to keep it working. You may not be able to ever update a package if one of its dependents never comes into line, though, which leads me to the biggest problem with this approach: it doesn’t make it easy to simply install a remote repository that has external dependencies. It’s intended primarily to support development and releasing of e.g. a binary, where your local development environment doesn’t matter to the end user. I’d like for there to be a nice way to import a package’s cabinet file when you’re importing it (so that your version of rx learns about what versions do and don’t work with various dependency versions), but I haven’t fully mapped this out.

Another problem which remains currently unsolved is the requirement to manually update when a dependency’s API changes. It would be nice to have some way for the author of a package to provide a way for dependent packages to fix themselves automatically; a tool like gofix. If this convention were widespread enough, it could vastly simplify the process of updating packages. This is something else about which I am thinking, and I hope that there are good libraries for easily making gofix-like tools in the future as well as a convention for including them in your projects.

Coming Soon

There is a lot of work to do, but I think it’s at the point where the best feedback is feedback from real users who have a real need for a tool like this. The next priorities on my list are:

  1. Save and restore global repository state
  2. Intelligently run “upgrade” experiments to find what new tags can be seamlessly integrated
  3. Support branches and branch switching
  4. Clean up and document more of the code

Your feedback, constructive criticism, and pull requests are all greatly appreciated!

P.S. I’m slowly cleaning up my many side-projects and making sure they work with Go 1. I’ll be listing them on kylelemons.net/go as I do, so feel free to e-mail me or find me on IRC if you have a favorite package that you want updated.

by Kyle Lemons at April 22, 2012 03:23 AM

April 21, 2012

embrace change

Nice technical task

A few days ago I've been mentioned in Google+ by Tyler Tallman who is using my Tideland Common Go Library and here especially the Cells package. It is a framework for event-driven applications with networked cells which run a user-implemented behavior. He is using it for the rule-based evaluation of data streams with medical data, indeed a good use-case. And he already found something to optimize. I'm using maps for the subscription of cells to other cells. That has been ok for me so far, but not for the performance needs of Tyler. So he optimized it by using a tree here.

As a result I will also allow different implementations here later. A map like today, but also a B-tree. I've got an old implementation I've done several years ago in Java and now I port it to Go. But not as an exact copy. First steps already showed that the code is by far more compact. But I also want to use concurrency by implementing the nodes as goroutines (together with their data structure). The idea is to let complex stuff like balancing be done in the background as well as an optimal usage of resources, e.g. when iterating over the items.

by Frank Müller (noreply@blogger.com) at April 21, 2012 02:19 PM

April 19, 2012

Go's official blog

Error handling and Go

If you have written any Go code you have probably encountered the built-in error type. Go code uses error values to indicate an abnormal state. For example, the os.Open function returns a non-nil error value when it fails to open a file.

func Open(name string) (file *File, err error)

The following code uses os.Open to open a file. If an error occurs it calls log.Fatal to print the error message and stop.

    f, err := os.Open("filename.ext")
if err != nil {
log.Fatal(err)
}
// do something with the open *File f

You can get a lot done in Go knowing just this about the errortype, but in this article we'll take a closer look at error and discuss some good practices for error handling in Go.

The error type

The error type is an interface type. An errorvariable represents any value that can describe itself as a string. Here is the interface's declaration:

type error interface {
Error() string
}

The error type, as with all built in types, is predeclared in the universe block.

The most commonly-used error implementation is the errors package's unexported errorString type.

// errorString is a trivial implementation of error.
type errorString struct {
s string
}

func (e *errorString) Error() string {
return e.s
}

You can construct one of these values with the errors.Newfunction. It takes a string that it converts to an errors.errorStringand returns as an error value.

// New returns an error that formats as the given text.
func New(text string) error {
return &errorString{text}
}

Here's how you might use errors.New:

func Sqrt(f float64) (float64, error) {
if f < 0 {
return 0, errors.New("math: square root of negative number")
}
// implementation
}

A caller passing a negative argument to Sqrt receives a non-nil error value (whose concrete representation is an errors.errorString value). The caller can access the error string ("math: square root of...") by calling the error's Error method, or by just printing it:

    f, err := Sqrt(-1)
if err != nil {
fmt.Println(err)
}

The fmt package formats an error value by calling its Error() string method.

It is the error implementation's responsibility to summarize the context. The error returned by os.Open formats as "open /etc/passwd: permission denied," not just "permission denied." The error returned by our Sqrt is missing information about the invalid argument.

To add that information, a useful function is the fmt package's Errorf. It formats a string according to Printf's rules and returns it as an error created by errors.New.

    if f < 0 {
return 0, fmt.Errorf("math: square root of negative number %g", f)
}

In many cases fmt.Errorf is good enough, but since error is an interface, you can use arbitrary data structures as error values, to allow callers to inspect the details of the error.

For instance, our hypothetical callers might want to recover the invalid argument passed to Sqrt. We can enable that by defining a new error implementation instead of using errors.errorString:

type NegativeSqrtError float64

func (f NegativeSqrtError) Error() string {
return fmt.Sprintf("math: square root of negative number %g", float64(f))
}

A sophisticated caller can then use a type assertion to check for a NegativeSqrtError and handle it specially, while callers that just pass the error to fmt.Println or log.Fatal will see no change in behavior.

As another example, the json package specifies a SyntaxError type that the json.Decode function returns when it encounters a syntax error parsing a JSON blob.

type SyntaxError struct {
msg string // description of error
Offset int64 // error occurred after reading Offset bytes
}

func (e *SyntaxError) Error() string { return e.msg }

The Offset field isn't even shown in the default formatting of the error, but callers can use it to add file and line information to their error messages:

    if err := dec.Decode(&val); err != nil {
if serr, ok := err.(*json.SyntaxError); ok {
line, col := findLine(f, serr.Offset)
return fmt.Errorf("%s:%d:%d: %v", f.Name(), line, col, err)
}
return err
}

(This is a slightly simplified version of some actual codefrom the Camlistore project.)

The error interface requires only a Error method; specific error implementations might have additional methods. For instance, the net package returns errors of type error, following the usual convention, but some of the error implementations have additional methods defined by the net.Errorinterface:

package net

type Error interface {
error
Timeout() bool // Is the error a timeout?
Temporary() bool // Is the error temporary?
}

Client code can test for a net.Error with a type assertion and then distinguish transient network errors from permanent ones. For instance, a web crawler might sleep and retry when it encounters a temporary error and give up otherwise.

        if nerr, ok := err.(net.Error); ok && nerr.Temporary() {
time.Sleep(1e9)
continue
}
if err != nil {
log.Fatal(err)
}

Simplifying repetitive error handling

In Go, error handling is important. The language's design and conventions encourage you to explicitly check for errors where they occur (as distinct from the convention in other languages of throwing exceptions and sometimes catching them). In some cases this makes Go code verbose, but fortunately there are some techniques you can use to minimize repetitive error handling.

Consider an App Engineapplication with an HTTP handler that retrieves a record from the datastore and formats it with a template.

func init() {
http.HandleFunc("/view", viewRecord)
}

func viewRecord(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
key := datastore.NewKey(c, "Record", r.FormValue("id"), 0, nil)
record := new(Record)
if err := datastore.Get(c, key, record); err != nil {
http.Error(w, err.Error(), 500)
return
}
if err := viewTemplate.Execute(w, record); err != nil {
http.Error(w, err.Error(), 500)
}
}

This function handles errors returned by the datastore.Getfunction and viewTemplate's Execute method. In both cases, it presents a simple error message to the user with the HTTP status code 500 ("Internal Server Error"). This looks like a manageable amount of code, but add some more HTTP handlers and you quickly end up with many copies of identical error handling code.

To reduce the repetition we can define our own HTTP appHandlertype that includes an error return value:

type appHandler func(http.ResponseWriter, *http.Request) error

Then we can change our viewRecord function to return errors:

func viewRecord(w http.ResponseWriter, r *http.Request) error {
c := appengine.NewContext(r)
key := datastore.NewKey(c, "Record", r.FormValue("id"), 0, nil)
record := new(Record)
if err := datastore.Get(c, key, record); err != nil {
return err
}
return viewTemplate.Execute(w, record)
}

This is simpler than the original version, but the http package doesn't understand functions that return error. To fix this we can implement the http.Handler interface's ServeHTTP method on appHandler:

func (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if err := fn(w, r); err != nil {
http.Error(w, err.Error(), 500)
}
}

The ServeHTTP method calls the appHandler function and displays the returned error (if any) to the user. Notice that the method's receiver, fn, is a function. (Go can do that!) The method invokes the function by calling the receiver in the expression fn(w, r).

Now when registering viewRecord with the http package we use the Handle function (instead of HandleFunc) as appHandler is an http.Handler (not an http.HandlerFunc).

func init() {
http.Handle("/view", appHandler(viewRecord))
}

With this basic error handling infrastructure in place, we can make it more user friendly. Rather than just displaying the error string, it would be better to give the user a simple error message with an appropriate HTTP status code, while logging the full error to the App Engine developer console for debugging purposes.

To do this we create an appError struct containing an error and some other fields:

type appError struct {
Error error
Message string
Code int
}

Next we modify the appHandler type to return *appError values:

type appHandler func(http.ResponseWriter, *http.Request) *appError

(It's usually a mistake to pass back the concrete type of an error rather than error, for reasons discussed in the Go FAQ, but it's the right thing to do here because ServeHTTP is the only place that sees the value and uses its contents.)

And make appHandler's ServeHTTP method display the appError's Message to the user with the correct HTTP status Code and log the full Error to the developer console:

func (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if e := fn(w, r); e != nil { // e is *appError, not os.Error.
c := appengine.NewContext(r)
c.Errorf("%v", e.Error)
http.Error(w, e.Message, e.Code)
}
}

Finally, we update viewRecord to the new function signature and have it return more context when it encounters an error:

func viewRecord(w http.ResponseWriter, r *http.Request) *appError {
c := appengine.NewContext(r)
key := datastore.NewKey(c, "Record", r.FormValue("id"), 0, nil)
record := new(Record)
if err := datastore.Get(c, key, record); err != nil {
return &appError{err, "Record not found", 404}
}
if err := viewTemplate.Execute(w, record); err != nil {
return &appError{err, "Can't display record", 500}
}
return nil
}

This version of viewRecord is the same length as the original, but now each of those lines has specific meaning and we are providing a friendlier user experience.

It doesn't end there; we can further improve the error handling in our application. Some ideas:

  • give the error handler a pretty HTML template,
  • make debugging easier by writing the stack trace to the HTTP response when the user is an administrator,
  • write a constructor function for appError that stores the stack trace for easier debugging,
  • recover from panics inside the appHandler, logging the error to the console as "Critical," while telling the user "a serious error has occurred." This is a nice touch to avoid exposing the user to inscrutable error messages caused by programming errors. See the Defer, Panic, and Recoverarticle for more details.

Conclusion

Proper error handling is an essential requirement of good software. By employing the techniques described in this post you should be able to write more reliable and succinct Go code.

by Andrew Gerrand (noreply@blogger.com) at April 19, 2012 01:50 AM

April 14, 2012

RSC

_rsc: RT @iamdanw: This is proper New Aesthetic http://t.co/DkTdf0od disassemble the algorithms and make things with them

_rsc: RT @iamdanw: This is proper New Aesthetic http://t.co/DkTdf0od disassemble the algorithms and make things with them

April 14, 2012 02:24 AM

April 13, 2012

embrace change

Concurrency as a natural paradigm


Since I'm working with Erlang/OTP and Go and point out their powerful handling of concurrency I've often been asked what's special with it and how it can be used. Additionally many people just mixup concurrency and parallelism. So to make it more clear I have to start by leaving computer — don't panic, I'll return later.

I'm wondering what you're doing right now. Yes, one thing is reading this text. But please spend some seconds looking around. What do you see, what is your environment? Maybe you're sitting at home or at work in your office. Or you're possibly sitting in a café reading this text on your smartphone. Are you alone while the rest of the world is frozen when you started to read this text? No, definitely not. There are people around you, some you're interacting with and some you don't care for. So let's assume you are at work. Especially in our software business we use to work in teams. A number of people, sometimes smaller, sometimes larger, works on a project with different roles and different tasks. Some of those tasks can be handled by one developer alone, but many need the discussions between the colleagues, they have to fit into the rest of the software and be realized in a useful order.

The work in those environments is done concurrently. From an artifacts perspective it may look serialized from the requirements until deployment. But the people responsible for all those artifacts of a project work in an independent but structured way like it's done in house building or factories since many hundreds of years. And that's no pure human behavior, we already know it from nature. Just take a look at bees and ants or all other animals building prides or states. In fact we all have grown with it but so far haven't been able to handle it in our software.

Now times have changed. We not only have languages like Go and Erlang/OTP (and many others more), we also have computers and soon smartphones with a large number of cores. I'm writing this text on a quad-core with 8 hyper-threads, and that's only the beginning. Additionally our software has to handle more and more stuff independently but in a structured way. Think about server applications handling a large number of user sessions where each session may send several overlapping requests, inside the server we're communicating with databases (maybe several due to a business driven mix of traditional relational and NoSQL backends), directory servers or further external systems in case of a SOA. Even more may we've have to take care of a global state as well as time-based or other events.

Today we handle those tasks request by request in a serialized manner. And while we're waiting for the answer of a relative slow I/O based task like reading from a database our request execution kicks one's heels. Concurrent software follows a different idea. While analyzing your problem and designing your solution you have to ask yourself where your dependencies are, what can be handled independently and where the access have to be synchronized. So you break up your code in independent components which you now run and compose with the help of your selected language. In Go those are goroutines communicating via channels, in Erlang/OTP processes sending messages into their mailboxes. Goroutines and processes are lightweight threads and a system can run hundreds of thousands.

Let's show it with a little scenario. You have to read data from a source, transform it into an internal representation for further processing, enrich it with data from an additional external source, modify data in two further external targets, at last transform the enriched data into the target format and write it to a target in order — no real uncommon job. Let's now do a first naive implementation (pseudo language):

// One serialized job execution.
fun Job(source, addSource, addTargetA, addTargetB, target) {
    raw = source.Read()
    internal = Modify(raw)
    enriched = addSource.Enrich(internal)
    modificationA = ExtractModificationA(enriched)
    modificationB = ExtractModificationB(enriched)
    addTargetA.Write(modificationA)
    addTargetB.Write(modificationB)
    result = Transform(enriched)
    target.Write(result)
}

Nice job, step by step. With a lot of waiting due to the I/O and maybe longer processing steps. So let's speed it up by spawning it several times.

// Starting our job a number of times.
fun Starter(source, addSource, addTargetA, addTargetB, target, count) {
    for i = 1 to count {
        spawn Job(source, addSource, addTargetA, addTargetB, target)
    }
}

Wow, now with full speed, Starter(…, 10) brings ten times the power! But eh, stop, wait a moment. They all read in parallel from our source. Does it care for synchronization? And if so other jobs have to wait while one is reading. And the same trouble with the additional source, shit. And why do we have to wait for those two modification with their writings. We don't get any result, so we could go on to the transformation and the writing to the target. And here once again the synchronization problem. Additionally how do we handle the in-order writing and how do we know that all is done? Our starter returns immediately after all spawnings. (sigh)

So let's try a better approach. Not with brute-force, but more intelligent. Here we design our methods and functions so that they can read from channels or write to channels to pass data between them.

// Pipelined job execution.
fun Job(source, addSource, addTargetA, addTargetB, target) {
    channel raw
    channel enriched
    channel multicast
    channel transform
    channel transformed
    channel modificationA
    channel modifiedA
    channel modificationB
    channel modifiedB
    channel done


    spawn source.Read(raw)
    spawn addSource.Enrich(raw, multicast)
    spawn fun () {
        for e in multicast {
            send e to transform
            send e to modificationA
            send e to modificationB
        }
    }()
    spawn Transform(transform, transformed)
    spawn target.Write(transformed, done)
    spawn ExtractModificationA(modificationA, modifiedA)
    spawn addTargetA.Write(modifiedA)
    spawn ExtractModificationB(modificationB, modifiedB)
    spawn addTargetA.Write(modifiedB)


    receive done
}

Uuuh! Looks a bit more difficult in the beginning? That's mostly due to my funny pseudo language. (smile) You just have to visualize it. The process source.Read() reads continuously out of the source writes the data into the raw channel. There's no need for synchronization here. And while the next chunk of data is read the process addSource.Enrich() reads from raw and writes it result to multicast. This one and the following anonymous function as process are needed to read from multicast and write to transform, modificationA and modificationB. This allows to handle the transformation and both modifications in parallel, here once again passing the data from process to process using a channel. I assume in my little pseudo runtime that the channels are buffered and spawned processes continue their work if their spawning process ends — you see I'm mixing Go and Erlang/OTP here. (smile) So we come to the final trick. While both modifications paths are fire and forget the transformation has a channel named done. This is for signalization of the end of processing. After the last data is read, enriched, transformed and written the process target.Write() sends a signal via done and our job function can return.

We see, we win a wonderful way of little processes doing their work almost independently and interacting via communication. There are still possible problems, e.g. addSource.Enrich() may block due to an internal error or an I/O problem. So you may need a kind of error signalization. Or at least time-outs like Erlang/OTP has in its receive statement and Go easily create with a <-time.After() in a select statement. Like finding a proper design you have to take care for those kinds of errors. There's still no free lunch. But this — safety in concurrent applications — may be a topic in another blog entry.

by Frank Müller (noreply@blogger.com) at April 13, 2012 02:54 PM

April 12, 2012

RSC

_rsc: RT @valueof: @tomdale @fat @pamelafox I got into tabs because of #golang.

_rsc: RT @valueof: @tomdale @fat @pamelafox I got into tabs because of #golang.

April 12, 2012 10:07 PM

research!rsc

QArt Codes

<style type="text/css"> .matrix { font-family: sans-serif; font-size: 0.8em; } table.matrix { padding-left: 1em; padding-right: 1em; padding-top: 1em; padding-bottom: 1em; } .matrix td { padding-left: 0.3em; padding-right: 0.3em; border-left: 2px solid white; border-right: 2px solid white; text-align: center; color: #aaa; } .matrix td.gray { color: black; background-color: #ddd; } </style>

QR codes are 2-dimensional bar codes that encode arbitrary text strings. A common use of QR codes is to encode URLs so that people can scan a QR code (for example, on an advertising poster, building roof, volleyball bikini, belt buckle, or airplane banner) to load a web site on a cell phone instead of having to “type” in a URL.

QR codes are encoded using Reed-Solomon error-correcting codes, so that a QR scanner does not have to see every pixel correctly in order to decode the content. The error correction makes it possible to introduce a few errors (fewer than the maximum that the algorithm can fix) in order to make an image. For example, in 2008, Duncan Robertson took a QR code for “http://bbc.co.uk/programmes” (left) and introduced errors in the form of a BBC logo (right):

That's a neat trick and a pretty logo, but it's uninteresting from a technical standpoint. Although the BBC logo pixels look like QR code pixels, they are not contribuing to the QR code. The QR reader can't tell much difference between the BBC logo and the Union Jack. There's just a bunch of noise in the middle either way.

Since the BBC QR logo appeared, there have been many imitators. Most just slap an obviously out-of-place logo in the middle of the code. This Disney poster is notable for being more in the spirit of the BBC code.

There's a different way to put pictures in QR codes. Instead of scribbling on redundant pieces and relying on error correction to preserve the meaning, we can engineer the encoded values to create the picture in a code with no inherent errors, like these:

This post explains the math behind making codes like these, which I call QArt codes. I have published the Go programs that generated these codes at code.google.com/p/rsc and created a web site for creating these codes.

Background

For error correction, QR uses Reed-Solomon coding (like nearly everything else). For our purposes, Reed-Solomon coding has two important properties. First, it is what coding theorists call a systematic code: you can see the original message in the encoding. That is, the Reed-Solomon encoding of “hello” is “hello” followed by some error-correction bytes. Second, Reed-Solomon encoded messages can be XOR'ed: if we have two different Reed-Solomon encoded blocks b1 and b2 corresponding to messages m1 and m2, b1 ⊕ b2 is also a Reed-Solomon encoded block; it corresponds to the message m1 ⊕ m2. (Here, ⊕ means XOR.) If you are curious about why these two properties are true, see my earlier post, Finite Field Arithmetic and Reed-Solomon Coding.

QR Codes

A QR code has a distinctive frame that help both people and computers recognize them as QR codes. The details of the frame depend on the exact size of the code—bigger codes have room for more bits—but you know one when you see it: the outlined squares are the giveaway. Here are QR frames for a sampling of sizes:

The colored pixels are where the Reed-Solomon-encoded data bits go. Each code may have one or more Reed-Solomon blocks, depending on its size and the error correction level. The pictures show the bits from each block in a different color. The L encoding is the lowest amount of redundancy, about 20%. The other three encodings increase the redundancy, using 38%, 55%, and 65%.

(By the way, you can read the redundancy level from the top pixels in the two leftmost columns. If black=0 and white=1, then you can see that 00 is L, 01 is M, 10 is Q, and 11 is H. Thus, you can tell that the QR code on the T-shirt in this picture is encoded at the highest redundancy level, while this shirt uses the lowest level and therefore might take longer or be harder to scan.

As I mentioned above, the original message bits are included directly in the message's Reed-Solomon encoding. Thus, each bit in the original message corresponds to a pixel in the QR code. Those are the lighter pixels in the pictures above. The darker pixels are the error correction bits. The encoded bits are laid down in a vertical boustrophedon pattern in which each line is two columns wide, starting at the bottom right corner and ending on the left side:

We can easily work out where each message bit ends up in the QR code. By changing those bits of the message, we can change those pixels and draw a picture. There are, however, a few complications that make things interesting.

QR Masks

The first complication is that the encoded data is XOR'ed with an obfuscating mask to create the final code. There are eight masks:

An encoder is supposed to choose the mask that best hides any patterns in the data, to keep those patterns from being mistaken for framing boxes. In our encoder, however, we can choose a mask before choosing the data. This violates the spirit of the spec but still produces legitimate codes.

QR Data Encoding

The second complication is that we want the QR code's message to be intelligible. We could draw arbitrary pictures using arbitrary 8-bit data, but when scanned the codes would produce binary garbage. We need to limit ourselves to data that produces sensible messages. Luckily for us, QR codes allow messages to be written using a few different alphabets. One alphabet is 8-bit data, which would require binary garbage to draw a picture. Another is numeric data, in which every run of 10 bits defines 3 decimal digits. That limits our choice of pixels slightly: we must not generate a 10-bit run with a value above 999. That's not complete flexibility, but it's close: 9.96 bits of freedom out of 10. If, after encoding an image, we find that we've generated an invalid number, we pick one of the 5 most significant bits at random—all of them must be 1s to make an invalid number—hard wire that bit to zero, and start over.

Having only decimal messages would still not be very interesting: the message would be a very large number. Luckily for us (again), QR codes allow a single message to be composed from pieces using different encodings. The codes I have generated consist of an 8-bit-encoded URL ending in a # followed by a numeric-encoded number that draws the actual picture:

http://swtch.com/pjw/#123456789...

The leading URL is the first data encoded; it takes up the right side of the QR code. The error correction bits take up the left side.

When the phone scans the QR code, it sees a URL; loading it in a browser visits the base page and then looks for an internal anchor on the page with the given number. The browser won't find such an anchor, but it also won't complain.

The techniques so far let us draw codes like this one:

The second copy darkens the pixels that we have no control over: the error correction bits on the left and the URL prefix on the right. I appreciate the cyborg effect of Peter melting into the binary noise, but it would be nice to widen our canvas.

Gauss-Jordan Elimination

The third complication, then, is that we want to draw using more than just the slice of data pixels in the middle of the image. Luckily, we can.

I mentioned above that Reed-Solomon messages can be XOR'ed: if we have two different Reed-Solomon encoded blocks b1 and b2 corresponding to messages m1 and m2, b1 ⊕ b2 is also a Reed-Solomon encoded block; it corresponds to the message m1 ⊕ m2. (In the notation of the previous post, this happens because Reed-Solomon blocks correspond 1:1 with multiples of g(x). Since b1 and b2 are multiples of g(x), their sum is a multiple of g(x) too.) This property means that we can build up a valid Reed-Solomon block from other Reed-Solomon blocks. In particular, we can construct the sequence of blocks b0, b1, b2, ..., where bi is the block whose data bits are all zeros except for bit i and whose error correction bits are then set to correspond to a valid Reed-Solomon block. That set is a basis for the entire vector space of valid Reed-Solomon blocks. Here is the basis matrix for the space of blocks with 2 data bytes and 2 checksum bytes:

1111111111
111111111111
111111
111111
111111
111111
111111
111111
1111111111
1111
1111
1111
1111
1111
1111
1111

The missing entries are zeros. The gray columns highlight the pixels we have complete control over: there is only one row with a 1 for each of those pixels. Each time we want to change such a pixel, we can XOR our current data with its row to change that pixel, not change any of the other controlled pixels, and keep the error correction bits up to date.

So what, you say. We're still just twiddling data bits. The canvas is the same.

But wait, there's more! The basis we had above lets us change individual data pixels, but we can XOR rows together to create other basis matrices that trade data bits for error correction bits. No matter what, we're not going to increase our flexibility—the number of pixels we have direct control over cannot increase—but we can redistribute that flexibility throughout the image, at the same time smearing the uncooperative noise pixels evenly all over the canvas. This is the same procedure as Gauss-Jordan elimination, the way you turn a matrix into row-reduced echelon form.

This matrix shows the result of trying to assert control over alternating pixels (the gray columns):

1111111111
1111111111
111111
111111
1111
111111
111111
1111
1111111111
1111
1111
111111
11111111
1111
1111
1111

The matrix illustrates an important point about this trick: it's not completely general. The data bits are linearly independent, but there are dependencies between the error correction bits that mean we often can't have every pixel we ask for. In this example, the last four pixels we tried to get were unavailable: our manipulations of the rows to isolate the first four error correction bits zeroed out the last four that we wanted.

In practice, a good approach is to create a list of all the pixels in the Reed-Solomon block sorted by how useful it would be to be able to set that pixel. (Pixels from high-contrast regions of the image are less important than pixels from low-contrast regions.) Then, we can consider each pixel in turn, and if the basis matrix allows it, isolate that pixel. If not, no big deal, we move on to the next pixel.

Applying this insight, we can build wider but noisier pictures in our QR codes:

The pixels in Peter's forehead and on his right side have been sacrificed for the ability to draw the full width of the picture.

We can also choose the pixels we want to control at random, to make Peter peek out from behind a binary fog:

Rotations

One final trick. QR codes have no required orientation. The URL base pixels that we have no control over are on the right side in the canonical orientation, but we can rotate the QR code to move them to other edges.


Further Information

All the source code for this post, including the web server, is at code.google.com/p/rsc/source/browse/qr. If you liked this, you might also like Zip Files All The Way Down.

Acknowledgements

Alex Healy pointed out that valid Reed-Solomon encodings are closed under XOR, which is the key to spreading the picture into the error correction pixels. Peter Weinberger has been nothing but gracious about the overuse of his binary likeness. Thanks to both.

April 12, 2012 07:00 PM

April 11, 2012

Adam Langley

False Start's Failure

Eighteen months ago(ish), Chrome started using False Start. False Start reduces the average time for an SSL handshake by 30%.

Since the biggest problem with transport security is that most sites don't use it, anything that reduces the latency impact of HTTPS is important. Making things faster doesn't just make them faster, it also makes them cheaper and more prevalent. When HTTPS is faster, it'll be used in more places than it would otherwise be.

But, sadly, False Start will be disabled, except for sites doing NPN, in Chrome 20. NPN is a TLS extension that we use to negotiate SPDY, although you don't have to use it to negotiate SPDY, you can advertise http/1.1 if you wish.

False Start was known to cause problems with a very small number of servers and the initial announcement outlined the uncommon scheme that we used to deploy it: we scanned the public Internet and built up a list of problematic sites. That list was built into Chrome and we didn't use False Start for connections to those sites. Over time the list was randomly eroded away and I'd try to address any issues that came up. (Preemptively so in the case of large sites.)

It did work to some extent. Many sites that had problems were fixed and it's a deployment scheme that is worth considering in the future. But it didn't ultimately work well enough for False Start.

Initially we believed that False Start issues were deterministic so long as the TLS Finished and application data records were sent in the same TCP packet. We changed Chrome to do this in the hopes of making False Start issues deterministic. However, we later discovered some HTTPS servers that were still non-deterministically False Start intolerant. I hypothesise that the servers run two threads per connection: one for reading and one for writing. Although the TCP packet was received atomically, thread scheduling could mean that the read thread may or may not be scheduled before the write thread had updated the connection state in response to the Finished.

This non-determinism made False Start intolerance difficult to diagnose and reduced our confidence in the blacklist.

The `servers' with problems were nearly always SSL terminators. These hardware devices terminate SSL connections and proxy unencrypted data to backend HTTP servers. I believe that False Start intolerance is very simple to fix in the code and one vendor suggested that was the case. None the less, of the vendors who did issue an update, most failed to communicate that fact to their customers. (A pattern that has repeated with the BEAST fix.)

One, fairly major, SSL terminator vendor refused to update to fix their False Start intolerance despite problems that their customers were having. I don't believe that this was done in bad faith, but rather a case of something much more mundane along the lines of “the SSL guy left and nobody touches that code any more”. However, it did mean that there was no good answer for their customers who were experiencing problems.

Lastly, it was becoming increasingly clear that we had a bigger problem internationally. Foreign admins have problems finding information on the subject (which is mostly in English) and foreign users have problems reporting bugs because we can't read them. We do have excellent agents in countries who liaise locally but it was still a big issue, and we don't cover every country with them. I also suspect that the distribution of problematic SSL terminators is substantially larger in some countries and that the experience with the US and Europe caused us to underestimate the problem.

In aggregate this lead us to decide that False Start was causing more problems than it was worth. We will now limit it to sites that support the NPN extension. This unfortunately means that it'll be an arcane, unused optimisation for the most part: at least until SPDY takes over the world.

April 11, 2012 07:00 AM

April 10, 2012

research!rsc

Finite Field Arithmetic and Reed-Solomon Coding

Finite fields are a branch of algebra formally defined in the 1820s, but interest in the topic can be traced back to public sixteenth-century polynomial-solving contests. For the next few centuries, finite fields had little practical value, but all changed in the last fifty years. It turns out that they are useful for many applications in modern computing, such as encryption, data compression, and error correction.

In particular, Reed-Solomon codes are an error-correcting code based on finite fields and used everywhere today. One early significant use was in the Voyager spacecraft: the messages it still sends back today, from the edge of the solar system, are heavily Reed-Solomon encoded so that even if only a small fragment makes it back to Earth, we can still reconstruct the message. Reed-Solomon coding is also used on CDs to withstand scratches, in wireless communications to withstand transmission problems, in QR codes to withstand scanning errors or smudges, in disks to withstand loss of fragments of the media, in high-level storage systems like Google's GFS and BigTable to withstand data loss and also to reduce read latency (the read can complete without waiting for all the responses to arrive).

This post shows how to implement finite field arithmetic efficiently on a computer, and then how to use that to implement Reed-Solomon encoding.

What is a Finite Field?

One way mathematicians study numbers is to abstract away the numbers themselves and focus on the operations. (This is kind of an object-oriented approach to math.) A field is defined as a set F and operators + and · on elements of F that satisfy the following properties:

  1. (Closure) For all x, y in F, x+y and x·y are in F.
  2. (Associative) For all x, y, z in F, (x+y)+z = x+(y+z) and (x·y)·z = x·(y·z).
  3. (Commutative) For all x, y in F, x+y = y+x and x·y = y·x.
  4. (Distributive) For all x, y, z in F, x·(y+z) = (x·y)+(x·z).
  5. (Identity) There is some element we'll call 0 in F such that for all x in F, x+0 = x. Similarly, there is some element we'll call 1 in F such that for all x in F, x·1 = x.
  6. (Inverse) For all x in F, there is some element y in F such that x+y = 0. We write y = −x. Similarly, for all x in F except 0, there is some element y in F such that x·y = 1. We write y = 1/x.

You probably recognize those properties from high school algebra class: the most well-known example of a field is the real numbers, where + is addition and · is multiplication. Other examples are complex numbers and fractions.

A mathematician doesn't have to prove the same results over and over for the real numbers ℝ, the complex numbers ℂ, the fractions ℚ, and so on. Instead, she can prove that a particular result holds for all fields—by assuming only the above properties, called the field axioms. Then she can apply the result by substituting a specific instance like the real numbers for the general idea of a field, the same way that a programmer can implement just one vector(T) and then instantiate it as vector(int), vector(string) and so on.

The integers ℤ are not a field: they lack multiplicative inverses. For example, there is no number that you can multiply by 2 to get 1, no 1/2. Surprisingly, though, the integers modulo any prime p do form a field. For example, the integers modulo 5 are 0, 1, 2, 3, 4. 1+4 = 0 (mod 5), so we say that 4 = −1. Similarly, 2·3 = 1 (mod 5), so we say that 3 = 1/2. After we've proved that ℤ/p is in fact a field, all the results about fields can be applied to ℤ/p. This is very useful: it lets us apply our intuition about the very familiar real numbers to these less familiar numbers. This field is written ℤ/p to emphasize that we're dealing with what's left after subtracting out all the p's. That is, we're dealing with what's left if you assume that p = 0. When you make that assumption, you get math that wraps around at p. These fields are called finite fields because, in contrast to fields like the real numbers, they have a finite number of elements.

For a programmer, the most interesting finite field is ℤ/2, which contains just the integers 0, 1. Addition is the same as XOR, and multiplication is the same as AND. Note that ℤ/p is only a field when p is prime: arithmetic on uint8 variables corresponds to ℤ/256, but it is not a field: there is no 1/2.

What can you do with a field?

The only problem with fields is that there's not a ton you can do with just the field axioms. One thing you can do is build polynomials, which were the original motivation for the mathematicians who pioneered the use of fields in the early 1800s. If we introduce a symbolic variable x, then we can build polynomials whose coefficients are field values. We'll write F[x] to denote the polynomials over x using coefficients from F. For example, if we use the real numbers ℝ as our field, then the polynomials ℝ[x] include x2+1, x+2, and 3.14x2 − 2.72x + 1.41. Like integers, these polynomials can be added and multiplied, but not always divided—what is (x2+1)/(x+2)?—so they are not a field. However, remember how the integers are not a field but the integers modulo a prime are a field? The same happens here: polynomials are not a field but polynomials modulo some prime polynomial are.

What does “polynomials modulo some prime polynomial” mean anyway? A prime polynomial is one that cannot be factored, like x2+1 cannot be factored using real numbers. The field ℤ/5 is what you get by doing math under the assumption that 5 = 0; similarly, ℝ[x]/(x2+1) is what you get by doing math under the assumption that x2+1 = 0. Just as ℤ/5 math never deals with numbers as big as 5, ℝ[x]/(x2+1) math never deals with polynomials as big as x2: anything bigger can have some multiple of x2+1 subtracted out again. That is, the polynomials in ℝ[x]/(x2+1) are bounded in size: they have only x1 and x0 (constant) terms. To add polynomials, we just add the coefficients using the addition rule from the coefficient's field, independently, like a vector addition. To multiply polynomials, we have to do the multiplication and then subtract out any x2+1 we can. If we have (ax+b)·(cx+d), we can expand this to (a·c)x2 + (b·c+a·d)x + (b·d), and then subtract (a·c)(x2+1) = (a·c)x2 + (a·c), producing the final result: (b·c+a·d)x + (b·d−a·c). That might seem like a funny definition of multiplication, but it does in fact obey the field axioms. In fact, this particular field is more familiar than it looks: it is the complex numbers ℂ, but we've written x instead of the usual i. Assuming that x2+1 = 0 is, except for a renaming, the same as defining i2 = −1.

Doing all our math modulo a prime polynomial let us take the field of real numbers and produce a field whose elements are pairs of real numbers. We can apply the same trick to take a finite field like ℤ/p and product a field whose elements are fixed-length vectors of elements of ℤ/p. The original ℤ/p has p elements. If we construct (ℤ/p)[x]/f(x), where f(x) is a prime polynomial of degree n (f's maximum x exponent is n), the resulting field has pn elements: all the vectors made up of n elements from ℤ/p. Incredibly, the choice of prime polynomial doesn't matter very much: any two finite fields of size pn have identical structure, even if they give the individual elements different names. Because of this, it makes sense to refer to all the finite fields of size pn as one concept: GF(pn). The GF stands for Galois Field, in honor of Évariste Galois, who was the first to study these. The exact polynomial chosen to produce a particular GF(pn) is an implementation detail.

For a programmer, the most interesting finite fields constructed this way are GF(2n)—the polynomial extensions of ℤ/2—because the elements of GF(2n) are bit vectors of length n. As a concrete example, consider (ℤ/2)[x]/(x8+x4+x3+x+1) . The field has 28 elements: each can be represented by a single byte. The byte with binary digits b7b6b5b4b3b2b1b0 represents the polynomial b7·x7 + b6·x6 + b5·x5 + b4·x4 + b3·x3 + b2·x2 + b1·x1 + b0. To add polynomials, we add coefficients. Since the coefficients are from ℤ/2, adding coefficients means XOR'ing each bit position separately, which is something computer hardware can do easily. Multiplying the polynomials is more difficult, because standard multiplication hardware is based on adding, but we need a multiplication based on XOR'ing. Because the coefficient math wraps at 2, (x2+x)·(x+1) = x3+2x2+x = x3+x, while computer multiplication would choose 1102* 0112 = 6 * 3 = 18 = 100102. However, it turns out that we can implement this field multiplication with a simple lookup table. In a finite field, there is always at least one element α that can serve as a generator. All the other non-zero elements are powers of α: α, α2, α3, and so on. This α is not symbolic like x: it's a specific element. For example, in ℤ/5, we can use α=2: {α, α2, α3, α4} = {2, 4, 8, 16} = {2, 4, 3, 1}. In GF(2n) the math is more complex but still works. If we know the generator, then we can, by repeated multiplication, create a lookup table exp[i] = αⁱ and an inverse table log[αⁱ] = i. Multiplication is then just a few table lookups: assuming a and b are non-zero, a·b = exp[log[a]+log[b]]. (That's a normal integer +, to add the exponents, not an XOR.)

Why do we care?

The fact that GF(2n) can be implemented efficiently on a computer means that we can implement systems based on mathematical theorems without worrying about the usual overflow problems you get when modeling integers or real numbers. To be sure, GF(2n) behaves quite differently from the integers in many ways, but if all you need is the field axioms, it's good enough, and it eliminates any need to worry about overflow or arbitrary precision calculations. Because of the lookup table, GF(28) is by far the most common choice of field in a computer algorithm. For example, the Advanced Encryption Standard (AES, formerly Rijndael) is built around GF(28) arithmetic, as are nearly all implementations of Reed-Solomon coding.

Code

Let's begin by defining a Field type that will represent the specific instance of GF(28) defined by a given polynomial. The polynomial must be of degree 8, meaning that its binary representation has the 0x100 bit set and no higher bits set.

type Field struct {
    ...
}

Addition is just XOR, no matter what the polynomial is:

// Add returns the sum of x and y in the field.
func (f *Field) Add(x, y byte) byte {
    return x ^ y
}

Multiplication is where things get interesting. If you'd used binary (and Go) in grade school, you might have learned this algorithm for multiplying two numbers (this is not finite field arithmetic):

// Grade-school multiplication in binary: mul returns the product x×y.
func mul(x, y int) int {
    z := 0
    for x > 0 {
        if x&1 != 0 {
            z += y
        }
        x >>= 1
        y <<= 1
    }
    return z
}

The running total z accumulates the product of x and y. The first iteration of this loop adds y to z if the low bit (the 1s digit) of x is 1. The next iteration adds y*2 if the next bit (the 2s digit, now shifted down) of x is 1. The next iteration adds y*4 if the 4s digit is 1, and so on. Each iteration shifts x to the right to chop off the processed digit and shifts y to the left to multiply by two.

To adapt this to multiply in a finite field, we need to make two changes. First, addition is XOR, so we use ^= instead of += to add to z. Second, we need to make the multiply reduce modulo the polynomial. Assuming that the inputs have already been reduced, the only chance of exceeding the polynomial comes from the shift of y. After the shift, then, we can check to see if we've overflowed, and if so, subtract (XOR) out one copy of the polynomial. The finite field version, then, is:

// GF(256) mutiplication: mul returns the product x×y mod poly.
func mul(x, y, poly int) int {
    z := 0
    for x > 0 {
        if x&1 != 0 {
            z ^= y
        }
        x >>= 1
        y <<= 1
        if y&0x100 != 0 {
            y ^= poly
        }
    }
    return z
}

We might want to do a lot of multiplication, though, and this loop is too slow. There aren't that many inputs—only 28×28 of them—so one option is to build a 64kB lookup table. With some cleverness, we can build a smaller lookup table. In the NewField constructor, we can compute α0, α1, α2, ..., record the sequence in an exp array, and record the inverse in a log array. Then we can reduce multiplication to addition of logarithms, like a slide rule does.

// A Field represents an instance of GF(256) defined by a specific polynomial.
type Field struct {
    log [256]byte // log[0] is unused
    exp [510]byte
}

// NewField returns a new field corresponding to
// the given polynomial and generator.
func NewField(poly, α int) *Field {
    var f Field
    x := 1
    for i := 0; i < 255; i++ {
        f.exp[i] = byte(x)
        f.exp[i+255] = byte(x)
        f.log[x] = byte(i)
        x = mul(x, α, poly)
    }
    f.log[0] = 255
    return &f
}

The values of the exp function cycle with period 255 (not 256, because 0 is impossible): α255 = 1. The straightforward way to implement Exp, then, is to look up the entry given by the exponent modulo 255.

// Exp returns the base 2 exponential of e in the field.
// If e < 0, Exp returns 0.
func (f *Field) Exp(e int) byte {
    if e < 0 {
        return 0
    }
    return f.exp[e%255]
}

Log is an even simpler table lookup, because the input is only a byte:

// Log returns the base 2 logarithm of x in the field.
// If x == 0, Log returns -1.
func (f *Field) Log(x byte) int {
    if x == 0 {
        return -1
    }
    return int(f.log[x])
}

Mul is where things get interesting. The obvious implementation of Mul is exp[(log[x]+log[y])%255], but if we double the exp array, so that it is 510 elements long, we can drop the relatively expensive %255:

// Mul returns the product of x and y in the field.
func (f *Field) Mul(x, y byte) byte {
    if x == 0 || y == 0 {
        return 0
    }
    return f.exp[int(f.log[x])+int(f.log[y])]
}

Inv returns the multiplicative inverse, 1/x. We don't implement divide: instead of x/y, we can use x · 1/y.

// Inv returns the multiplicative inverse of x in the field.
// If x == 0, Inv returns 0.
func (f *Field) Inv(x byte) byte {
    if x == 0 {
        return 0
    }
    return f.exp[255-f.log[x]]
}

Reed-Solomon Coding

In 1960, Irving Reed and Gustave Solomon proposed a way to build an error-correcting code using GF(2n). The method interpreted the m message bits as coefficients of a polynomial f of degree m−1 over GF(2n) and then sent f(0), f(α), f(α2), f(α3), ..., f(1). Any m of these, if received correctly, suffice to reconstruct f, and then the message can be read off the coefficients. To find a correct set, Reed and Solomon's algorithm constructed the f corresponding to every possible subset of m received values and then chose the most common one in a majority vote. As long as no more than (2n−m)/2 values were corrupted in transit, the majority will agree on the correct value of f. This decoding algorithm is very expensive, too expensive for long messages. As a result, the Reed-Solomon approach sat unused for almost a decade. In 1969, however, Elwyn Berlekamp and James Massey proposed a variant with an efficient decoding algorithm. In the 1980s, Berlekamp and Lloyd Welch developed an even more efficient decoding algorithm that is the one typically used today. These decoding algorithms are based on systems of equations far too complex to explain here; in this post, we will only deal with encoding. (I can't keep the decoding algorithms straight in my head for more than an hour or two at a time, much less explain them in finite space.)

In Reed-Solomon encoding as it is practiced today, the choice of finite field F and generator α defines a generator polynomial g(x) = (x−1)(x−α)(x−α2)...(x−αn−m). To encode a message m, the message is taken as the top coefficients of a degree n polynomial f(x) = m0xn−1+m1xn−2+...+mmxn−m−1. Then that polynomial can be divided by g to produce the remainder polynomial r(x), the unique polynomial of degree less than n−m such that f(x) − r(x) is a multiple of g(x). Since r(x) is of degree less than n−m, subtracting r(x) does not affect any of the message coefficients, just the lower terms, so the polynomial f(x) − r(x) (= f(x) + r(x)) is taken as the encoded message. All encoded messages, then, are multiples of g(x). On the receiving end, the decoder does some magic to figure out the simplest changes needed to make the received polynomial a multiple of g(x) and then reads the message out of the top coefficients.

While decoding is difficult, encoding is easy: the first m bytes are the message itself, followed by the c bytes defining the remainder of m·xc/g(x). We can also check whether we received an error-free message by checking whether the concatenation defines a polynomial that is a multiple of g(x).

Code

The Reed-Solomon encoding problem is this: given a message m interpreted as a polynomial m(x), compute the error correction bytes, m(x)·xc mod g(x).

The grade-school division algorithm works well here. If we fill in p with m(x)·xc (m followed by c zero bytes), then we can replace p by the remainder by iteratively subtracting out multiples of the generator polynomial g.

for i := 0; i < len(m); i++ {
    k := f.Mul(p[i], f.Inv(gen[0]))  // k = pi / g0
    // p -= k·g
    for j, g := range gen {
        p[i+j] = f.Add(p[i+j], f.Mul(k, g))
    }
}

This implementation is correct but can be made more efficient. If you want to try, run:

go get code.google.com/p/rsc/gf256
go test code.google.com/p/rsc/gf256 -bench Blog

That benchmark measures the speed of the implementation in blog_test.go, which looks like the above. Optimize away, or follow along.

There's definitely room for improvement:

$ go test code.google.com/p/rsc/gf256 -bench ECC
PASS
BenchmarkBlogECC   500000   7031 ns/op   4.55 MB/s
BenchmarkECC      1000000   1332 ns/op  24.02 MB/s

To start, we can expand the definitions of Add and Mul. The Go compiler's inliner would do this for us; the win here is not the inlining but the simplifications it will enable us to make.

for i := 0; i < len(m); i++ {
    if p[i] == 0 {
        continue
    }
    k := f.exp[f.log[p[i]] + 255 - f.log[gen[0]]]  // k = pi / g0
    // p -= k·g
    for j, g := range gen {
        p[i+j] ^= f.exp[f.log[k] + f.log[g]]
    }
}

(The implementation handles p[i] == 0 specially because 0 has no log.)

The first thing to note is that we compute k but then use f.log[k] repeatedly. Computing the log will avoid that memory access, and it is cheaper: we just take out the f.exp[...] lookup on the line that computes k. This is safe because p[i] is non-zero, so k must be non-zero.

for i := 0; i < len(m); i++ {
    if p[i] == 0 {
        continue
    }
    lk := f.log[p[i]] + 255 - f.log[gen[0]]  // k = pi / g0
    // p -= k·g
    for j, g := range gen {
        p[i+j] ^= f.exp[lk + f.log[g]]
    }
}

Next, note that we repeatedly compute f.log[g]. Instead of doing that, we can iterate lgen—an array holding the logs of the coefficients—instead of gen. We'll have to handle zero somehow: let's say that the array has an entry set to 255 when the corresponding gen value is zero.

for i := 0; i < len(m); i++ {
    if p[i] == 0 {
        continue
    }
    lk := f.log[p[i]] + 255 - f.log[gen[0]]  // k = pi / g0
    // p -= k·g
    for j, lg := range lgen {
        if lg != 255 {
            p[i+j] ^= f.exp[lk + lg]
        }
    }
}

Next, we can notice that since the generator is defined as

g(x) = (x−1)(x−α)(x−α2)...(x−αn−m)

the first coefficient, g0, is always 1! That means we can simplify the k = pi / g calculation to just k = pi. Also, we can drop the first element of lgen and its subtraction, as long as we ignore the high bytes in the result (we know they're supposed to be zero anyway).

for i := 0; i < len(m); i++ {
    if p[i] == 0 {
        continue
    }
    lk := f.log[p[i]]
    // p -= k·g
    for j, lg := range lgen {
        if lg != 255 {
            p[i+1+j] ^= f.exp[lk + lg]
        }
    }
}

The inner loop, which is where we spend all our time, has two additions by loop-invariant constants: i+1+j and lk+lg. The i+1 and lk do not change on each iteration. We can avoid those additions by reslicing the arrays outside the loop:

for i := 0; i < len(m); i++ {
    if p[i] == 0 {
        continue
    }
    lk := f.log[p[i]]
    // p -= k·g
    q := p[i+1:]
    exp := f.exp[lk:]
    for j, lg := range lgen {
        if lg != 255 {
            q[j] ^= exp[lg]
        }
    }
}

As one final trick, we can replace p[i] by a range variable. The Go compiler does not yet use loop invariants to eliminate bounds checks, but it does eliminate bounds checks in the implicit indexing done by a range loop.

for i, pi := range p {
    if i == len(m) {
        break
    }
    if pi == 0 {
        continue
    }
    // p -= k·g
    q := p[i+1:]
    exp := f.exp[f.log[pi]:]
    for j, lg := range lgen {
        if lg != 255 {
            q[j] ^= exp[lg]
        }
    }
}

The code is in context in gf256.go.

Summary

We started with single bits 0 and 1. From those we constructed 8-bit polynomials—the elements of GF(28)—with overflow-free, easy-to-implement mathematical operations. From there we moved on to Reed-Solomon coding, which constructs its own polynomials built using elements of GF(28) as coefficients. That is, each Reed-Solomon message is interpreted as a polynomial, and each coefficient in that polynomial is itself a smaller polynomial.

Now that we know how to create Reed-Solomon encodings, the next post will look at some fun we can have with them.

April 10, 2012 06:00 PM

April 05, 2012

Command Center

The byte order fallacy

Whenever I see code that asks what the native byte order is, it's almost certain the code is either wrong or misguided. And if the native byte order really does matter to the execution of the program, it's almost certain to be dealing with some external software that is either wrong or misguided. If your code contains #ifdef BIG_ENDIAN or the equivalent, you need to unlearn about byte order.

The byte order of the computer doesn't matter much at all except to compiler writers and the like, who fuss over allocation of bytes of memory mapped to register pieces. Chances are you're not a compiler writer, so the computer's byte order shouldn't matter to you one bit.

Notice the phrase "computer's byte order". What does matter is the byte order of a peripheral or encoded data stream, but--and this is the key point--the byte order of the computer doing the processing is irrelevant to the processing of the data itself. If the data stream encodes values with byte order B, then the algorithm to decode the value on computer with byte order C should be about B, not about the relationship between B and C.

Let's say your data stream has a little-endian-encoded 32-bit integer. Here's how to extract it (assuming unsigned bytes):
i = (data[0]<<0) | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);
If it's big-endian, here's how to extract it:
i = (data[3]<<0) | (data[2]<<8) | (data[1]<<16) | (data[0]<<24);
Both these snippets work on any machine, independent of the machine's byte order, independent of alignment issues, independent of just about anything. They are totally portable, given unsigned bytes and 32-bit integers.

What you might have expected to see for the little-endian case was something like
i = *((int*)data);
#ifdef BIG_ENDIAN
/* swap the bytes */
i = ((i&0xFF)<<24) | (((i>>8)&0xFF)<<16) | (((i>>16)&0xFF)<<8) | (((i>>24)&0xFF)<<0);
#endif
or something similar. I've seen code like that many times. Why not do it that way? Well, for starters:
  1. It's more code.
  2. It assumes integers are addressable at any byte offset; on some machines that's not true.
  3. It depends on integers being 32 bits long, or requires more #ifdefs to pick a 32-bit integer type.
  4. It may be a little faster on little-endian machines, but not much, and it's slower on big-endian machines.
  5. If you're using a little-endian machine when you write this, there's no way to test the big-endian code.
  6. It swaps the bytes, a sure sign of trouble (see below).

By contrast, my version of the code:
  1. Is shorter.
  2. Does not depend on alignment issues.
  3. Computes a 32-bit integer value regardless of the local size of integers.
  4. Is equally fast regardless of local endianness, and fast enough (especially on modern processsors) anyway.
  5. Runs the same code on all computers: I can state with confidence that if it works on a little-endian machine it will work on a big-endian machine.
  6. Never "byte swaps".
In other words, it's simpler, cleaner, and utterly portable. There is no reason to ask about local byte order when about to interpret an externally provided byte stream.

I've seen programs that end up swapping bytes two, three, even four times as layers of software grapple over byte order. In fact, byte-swapping is the surest indicator the programmer doesn't understand how byte order works.

Why do people make the byte order mistake so often? I think it's because they've seen a lot of bad code that has convinced them byte order matters. "Here comes an encoded byte stream; time for an #ifdef." In fact, C may be part of the problem: in C it's easy to make byte order look like an issue. If instead you try to write byte-order-dependent code in a type-safe language, you'll find it's very hard. In a sense, byte order only bites you when you cheat.

There's plenty of software that demonstrates the byte order fallacy is really a fallacy. The entire Plan 9 system ran, without architecture-dependent #ifdefs of any kind, on dozens of computers of different makes, models, and byte orders. I promise you, your computer's byte order doesn't matter even at the level of the operating system.

And there's plenty of software that demonstrates how easily you can get it wrong. Here's one example. I don't know if it's still true, but some time back Adobe Photoshop screwed up byte order. Back then, Macs were big-endian and PCs, of course, were little-endian. If you wrote a Photoshop file on the Mac and read it back in, it worked. If you wrote it on a PC and tried to read it on a Mac, though, it wouldn't work unless back on the PC you checked a button that said you wanted the file to be readable on a Mac. (Why wouldn't you? Seriously, why wouldn't you?) Ironically, when you read a Mac-written file on a PC, it always worked, which demonstrates that someone at Adobe figured out something about byte order. But there would have been no problems transferring files between machines, and no need for a check box, if the people at Adobe wrote proper code to encode and decode their files, code that could have been identical between the platforms. I guarantee that to get this wrong took far more code than it would have taken to get it right.

Just last week I was reviewing some test code that was checking byte order, and after some discussion it turned out that there was a byte-order-dependency bug in the code being tested. As is often the case, the existence of byte-order-checking was evidence of the presence of a bug. Once the bug was fixed, the test no longer cared about byte order.

And neither should you, because byte order doesn't matter.

by rob (noreply@blogger.com) at April 05, 2012 04:49 AM

April 03, 2012

embrace change

Yesterdays Go talk

Yesterday afternoon I had my talk about Google Go at the GTUG Bremen - which soon btw. will be the GDG Bremen. The audience has been about 25 people, a good number. And the interest has been high, I got many questions during the talk. This interaction is definitely a lot better than just talking to a silent audience.

But there's still room for improvement. The presentation maybe should have been shorter, followed by a practical workshop. I prepared a little toy program that will be published like the slides. I wanted to show how Go looks in reality and to demonstrate, how to implement a wanted feature. But sadly due to the long talk there only has been little room left for that.

The GTUG team recorded the talk on a video that will be published soon and I just will fix some small detected errors on the slides and then publish it too. You'll find a notice here.

by Frank Müller (noreply@blogger.com) at April 03, 2012 02:25 PM

April 02, 2012

embrace change

Quick reminder: Go talk today at GTUG Bremen

Just a quick reminder: Today is the monthly regulars' table of the GTUG Bremen. This time I'll give a talk about Google Go.

by Frank Müller (noreply@blogger.com) at April 02, 2012 08:03 AM

April 01, 2012

embrace change

Common Go Library updated for Go 1

A few days ago the Go team has released Go 1. Congratulations again from my side, what a great work. I've used the last weeks with the both release candidates to apply some last changes to my Tideland Common Go Library. Especially the error handling using the new error type and own implementations of this interface, the flexible logging and the testing have been improved. So today I checked the new release in and tagged it for Go 1.

The packages are:
  • applog: Logging with multiple levels, caller details in debug and critical situations and pluggable own logging behavior.
  • asserts: Tests which can be used inside of unit tests or at runtime.
  • cache: Cache values which will be refreshed on demand.
  • cells: A framework for event and behavior based applications.
  • identifier: Generate UUIDs and other identifiers.
  • mapreduce: Use Googles great algorthim for data processing and aggregating.
  • markup: A simple markup language as an alternative to XML.
  • monitoring: Keep track of the performance, stay-set variables and dynamically retrieved statuses.
  • numerics: Some numerical types, intended to use them e.g. for statistical problems.
  • redis: A powerful client for the Redis database.
  • sort: A parallel quicksort to use the power of multiple cores.
  • state: A generic finite state machine.
  • time: Functions to work with times and an internal crontab server.
  • util: Some more smaller utilities.
  • web: A lean web framework. Especially the combination of REST and JSON is supported.
The next releases will contain a goroutine supervisor like they are inside the Erlang/OTP and an optional web interface for the monitoring package.

Beside that I'm now restart a project I've initially started for the Google App Engine. It's a web application using HTML / CSS / JavaScript / jQuery for the frontend, communicating with a Go backend via HTTP / JSON and using Redis for persistency. The kind of application? That's still a secret. (smile)

by Frank Müller (noreply@blogger.com) at April 01, 2012 08:59 PM

research!rsc

Random Hash Functions

A hash function for a particular hash table should always be deterministic, right? At least, that's what I thought until a few weeks ago, when I was able to fix a performance problem by calling rand inside a hash function.

A hash table is only as good as its hash function, which ideally satisfies two properties for any key pair k1, k2:

  1. If k1 == k2, hash(k1) == hash(k2).
  2. If k1 != k2, it should be likely that hash(k1) != hash(k2).

Normally, following rule 1 would prohibit the use of random bits while computing the hash, because if you pass in the same key again, you'd use different random bits and get a different hash value. That's why the fact that I got to call rand in a hash function is so surprising.

If the hash function violates rule 1, your hash table just breaks: you can't find things you put in, because you are looking in the wrong places. If the hash function satisfies rule 1 but violates rule 2 (for example, “return 42”), the hash table will be slow due to the large number of hash collisions. You'll still be able to find the things you put in, but you might as well be using a list.

The phrasing of rule 1 is very important. It is not sufficient to say simply “hash(k1) == hash(k1)”, because that does not take into account the definition of equality of keys. If you are building a hash table with case-insensitive, case-preserving string keys, then “HELLO” and “hello” need to hash to the same value. In fact, “hash(k1) == hash(k1)” is not even strictly necessary. How could it not be necessary? By reversing rule 1, hash(k1) and hash(k1) can be unequal if k1 != k1, that is, if k1 does not equal itself.

How can that happen? It happens if k1 is the floating-point value NaN (not-a-number), which by convention is not equal to anything, not even itself.

Okay, but why bother? Well, remember rule 2. Since NaN != NaN, it should be likely that hash(NaN) != hash(NaN), or else the hash table will have bad performance. This is very strange: the same input is hashed twice, and we're supposed to (at least be likely to) return different hash values. Since the inputs are identical, we need a source of external entropy, like rand.

What if you don't? You get hash tables that don't perform very well if someone can manage to trick you into storing things under NaN repeatedly:

$ cat nan.py
#!/usr/bin/python
import timeit
def build(n):
	m = {}
	for i in range(n):
		m[float("nan")] = 1
n = 1
for i in range(20):
	print "%6d %10.6f" % (n, timeit.timeit('build('+str(n)+')',
	    'from __main__ import build', number=1))
	n *= 2

$ python nan.py
     1   0.000006
     2   0.000004
     4   0.000004
     8   0.000008
    16   0.000011
    32   0.000028
    64   0.000072
   128   0.000239
   256   0.000840
   512   0.003339
  1024   0.012612
  2048   0.050331
  4096   0.200965
  8192   1.032596
 16384   4.657481
 32768  22.758963
 65536  91.899054
$

The behavior here is quadratic: double the input size and the run time quadruples. You can run the equivalent Go program on the Go playground. It has the NaN fix and runs in linear time. (On the playground, wall time stands still, but you can see that it's executing in far less than 100s of seconds. Run it locally for actual timing.)

Now, you could argue that putting a NaN in a hash table is a dumb idea, and also that treating NaN != NaN in a hash table is also a dumb idea, and you'd be right on both counts.

But the alternatives are worse:

  • If you define that NaN is equal to itself during hash key comparisons, now you have a second parallel definition of equality, to handle NaNs inside structs and so on, only used for map lookups. Languages typically have too many equality operators anyway; introducing a new one for this special case seems unwise.
  • If you define that NaN cannot appear as a hash table key, then you have a similar problem: you need to build up logic to test for invalid keys such as NaNs inside structs or arrays, and then you have to deal with the fact that your hash table might return an error or throw an exception when inserting values under certain keys.

The most consistent thing to do is to accept the implications of NaN != NaN: m[NaN] = 1 always creates a new hash table element (since the key is unequal to any existing entry), reading m[NaN] never finds any data (same reason), and iterating over the hash table yields each of the inserted NaN entries.

Behaviors surrounding NaN are always surprising, but if NaN != NaN elsewhere, the least surprising thing you can do is make your hash tables respect that. To do that well, it needs to be likely that hash(NaN) != hash(NaN). And you probably already have a custom floating-point hash function so that +0 and −0 are treated as the same value. Go ahead, call rand for NaN.

(Note: this is different from the hash table performance problem that was circulating in December 2011. In that case, the predictability of collisions on ordinary data was solved by making each different table use a randomly chosen hash function; there's no randomness inside the function itself.)

April 01, 2012 07:00 PM

March 29, 2012

Sonia Codes

Go 1 release

The news, if you hadn’t heard. :)  It’s a big thing with me because I’ve put so much time into using it—well, mostly playing with it.  I do write and maintain some Go programs for work, but most of my time with Go has been spent contributing solutions to Rosetta Code.  I’ve contributed hundreds of Go solutions over the last year or so, and Go has been in the top 10 languages there for some time now.  Recently I’ve tried to review all of the solutions to update them to Go 1, and I’m happy to announce that they (almost) all work with Go 1 now.

I wish I could announce that it represents a large body of idiomatic Go code, available as reference solutions common programming tasks, but I’m afraid it’s not.  Firstly, I’m not sure how idiomatic my code is.  I’ve worked mostly in isolation, and my code almost certainly displays my idiosyncrasies as much as it displays accepted idioms.  Secondly of course, is the nature of of the RC site, which is more a wonderland than reference library.

Still, I’d like to invite people to come and visit.  Browse the existing Go solutions and be amused or enlightened, hopefully both.  But then I’d really like to encourage people to make improvements as they can.  That’s the nature of a wiki, and as I said, since such a large fraction of the Go code is mine, there is certainly much room for the code to be improved.

Next there is the list of existing RC tasks with no Go solution yet.  Most of these are tasks that awkward for me because I don’t have a computer, and can’t freely do things like install software on the computers I do have access to.  If you have or can install up-to-date libraries and software on your computer, some of these tasks should be easy!  Please browse the list and contribute any solutions you can.  A few of them are simply tasks for which I don’t have the knowledge.  For example the HTTP task seemed simple enough, but I don’t know enough to do the HTTPS task.

Finally, if you really enjoy the site, consider contributing a new task that you feel really shows off some feature of Go.  I’ve added just a few, but probably still be designed are some great tasks illuminating interfaces, concurrency, and the varied capabilities of the Go standard package library.


by Sonia at March 29, 2012 12:04 AM

March 28, 2012

RSC

_rsc: go1 has been my goto language for a while now. - dlsspy on hacker news #golang

_rsc: go1 has been my goto language for a while now. - dlsspy on hacker news #golang

March 28, 2012 05:21 PM

Go's official blog

Go version 1 is released

Today marks a major milestone in the development of the Go programming language. We're announcing Go version 1, or Go 1 for short, which defines a language and a set of core libraries to provide a stable foundation for creating reliable products, projects, and publications.
Go 1 is the first release of Go that is available in supported binary distributions. They are available for Linux, FreeBSD, Mac OS X and, we are thrilled to announce, Windows.

The driving motivation for Go 1 is stability for its users. People who write Go 1 programs can be confident that those programs will continue to compile and run without change, in many environments, on a time scale of years. Similarly, authors who write books about Go 1 can be sure that their examples and explanations will be helpful to readers today and into the future.

Forward compatibility is part of stability. Code that compiles in Go 1 should, with few exceptions, continue to compile and run throughout the lifetime of that version, even as we issue updates and bug fixes such as Go version 1.1, 1.2, and so on. The Go 1 compatibility document explains the compatibility guidelines in more detail.

Go 1 is a representation of Go as it is used today, not a major redesign. In its planning, we focused on cleaning up problems and inconsistencies and improving portability. There had long been many changes to Go that we had designed and prototyped but not released because they were backwards-incompatible. Go 1 incorporates these changes, which provide significant improvements to the language and libraries but sometimes introduce incompatibilities for old programs. Fortunately, the go fix tool can automate much of the work needed to bring programs up to the Go 1 standard.

Go 1 introduces changes to the language (such as new types for Unicode characters and errors) and the standard library (such as the new time package and renamings in the strconv package). Also, the package hierarchy has been rearranged to group related items together, such as moving the networking facilities, for instance the rpc package, into subdirectories of net. A complete list of changes is documented in the Go 1 release notes. That document is an essential reference for programmers migrating code from earlier versions of Go.

We also restructured the Go tool suite around the new go command, a program for fetching, building, installing and maintaining Go code. The go command eliminates the need for Makefiles to write Go code because it uses the Go program source itself to derive the build instructions. No more build scripts!

Finally, the release of Go 1 triggers a new release of the Google App Engine SDK. A similar process of revision and stabilization has been applied to the App Engine libraries, providing a base for developers to build programs for App Engine that will run for years.

Go 1 is the result of a major effort by the core Go team and our many contributors from the open source community. We thank everyone who helped make this happen.

There has never been a better time to be a Go programmer. Everything you need to get started is at golang.org.

by Andrew Gerrand (noreply@blogger.com) at March 28, 2012 04:32 PM

The Go image package

The image and image/color packages define a number of types: color.Color and color.Model describe colors, image.Point and image.Rectangle describe basic 2-D geometry, and image.Image brings the two concepts together to represent a rectangular grid of colors. A separate article covers image composition with the image/draw package.

Colors and Color Models

Color is an interface that defines the minimal method set of any type that can be considered a color: one that can be converted to red, green, blue and alpha values. The conversion may be lossy, such as converting from CMYK or YCbCr color spaces.

type Color interface {
// RGBA returns the alpha-premultiplied red, green, blue and alpha values
// for the color. Each value ranges within [0, 0xFFFF], but is represented
// by a uint32 so that multiplying by a blend factor up to 0xFFFF will not
// overflow.
RGBA() (r, g, b, a uint32)
}

There are three important subtleties about the return values. First, the red, green and blue are alpha-premultiplied: a fully saturated red that is also 25% transparent is represented by RGBA returning a 75% r. Second, the channels have a 16-bit effective range: 100% red is represented by RGBA returning an r of 65535, not 255, so that converting from CMYK or YCbCr is not as lossy. Third, the type returned is uint32, even though the maximum value is 65535, to guarantee that multiplying two values together won't overflow. Such multiplications occur when blending two colors according to an alpha mask from a third color, in the style of Porter and Duff'sclassic algebra:


dstr, dstg, dstb, dsta := dst.RGBA()
srcr, srcg, srcb, srca := src.RGBA()
_, _, _, m := mask.RGBA()
const M = 1<<16 - 1
// The resultant red value is a blend of dstr and srcr, and ranges in [0, M].
// The calculation for green, blue and alpha is similar.
dstr = (dstr*(M-m) + srcr*m) / M

The last line of that code snippet would have been more complicated if we worked with non-alpha-premultiplied colors, which is why Color uses alpha-premultiplied values.

The image/color package also defines a number of concrete types that implement the Color interface. For example, RGBA is a struct that represents the classic "8 bits per channel" color.

type RGBA struct {
R, G, B, A uint8
}

Note that the R field of an RGBA is an 8-bit alpha-premultiplied color in the range [0, 255]. RGBA satisfies the Color interface by multiplying that value by 0x101 to generate a 16-bit alpha-premultiplied color in the range [0, 65535]. Similarly, the NRGBA struct type represents an 8-bit non-alpha-premultiplied color, as used by the PNG image format. When manipulating an NRGBA's fields directly, the values are non-alpha-premultiplied, but when calling the RGBA method, the return values are alpha-premultiplied.

A Model is simply something that can convert Colors to other Colors, possibly lossily. For example, the GrayModel can convert any Color to a desaturated Gray. A Palette can convert any Color to one from a limited palette.

type Model interface {
Convert(c Color) Color
}
type Palette []Color

Points and Rectangles

A Point is an (x, y) co-ordinate on the integer grid, with axes increasing right and down. It is neither a pixel nor a grid square. A Point has no intrinsic width, height or color, but the visualizations below use a small colored square.

type Point struct {
X, Y int
}

    p := image.Point{2, 1}

A Rectangle is an axis-aligned rectangle on the integer grid, defined by its top-left and bottom-right Point. A Rectangle also has no intrinsic color, but the visualizations below outline rectangles with a thin colored line, and call out their Min and Max Points.

type Rectangle struct {
Min, Max Point
}

For convenience, image.Rect(x0, y0, x1, y1) is equivalent to image.Rectangle{image.Point{x0, y0}, image.Point{x1, y1}}, but is much easier to type.

A Rectangle is inclusive at the top-left and exclusive at the bottom-right. For a Point p and a Rectangle r, p.In(r) if and only if r.Min.X <= p.X && p.X < r.Max.X, and similarly for Y. This is analagous to how a slice s[i0:i1] is inclusive at the low end and exclusive at the high end. (Unlike arrays and slices, a Rectangle often has a non-zero origin.)

    r := image.Rect(2, 1, 5, 5)
// Dx and Dy return a rectangle's width and height.
fmt.Println(r.Dx(), r.Dy(), image.Pt(0, 0).In(r)) // prints 3 4 false

Adding a Point to a Rectangle translates the Rectangle. Points and Rectangles are not restricted to be in the bottom-right quadrant.

    r := image.Rect(2, 1, 5, 5).Add(image.Pt(-4, -2))
fmt.Println(r.Dx(), r.Dy(), image.Pt(0, 0).In(r)) // prints 3 4 true

Intersecting two Rectangles yields another Rectangle, which may be empty.

    r := image.Rect(0, 0, 4, 3).Intersect(image.Rect(2, 2, 5, 5))
// Size returns a rectangle's width and height, as a Point.
fmt.Printf("%#v\n", r.Size()) // prints image.Point{X:2, Y:1}

Points and Rectangles are passed and returned by value. A function that takes a Rectangle argument will be as efficient as a function that takes two Point arguments, or four int arguments.

Images

An Image maps every grid square in a Rectangle to a Color from a Model. "The pixel at (x, y)" refers to the color of the grid square defined by the points (x, y), (x+1, y), (x+1, y+1) and (x, y+1).

type Image interface {
// ColorModel returns the Image's color model.
ColorModel() color.Model
// Bounds returns the domain for which At can return non-zero color.
// The bounds do not necessarily contain the point (0, 0).
Bounds() Rectangle
// At returns the color of the pixel at (x, y).
// At(Bounds().Min.X, Bounds().Min.Y) returns the upper-left pixel of the grid.
// At(Bounds().Max.X-1, Bounds().Max.Y-1) returns the lower-right one.
At(x, y int) color.Color
}

A common mistake is assuming that an Image's bounds start at (0, 0). For example, an animated GIF contains a sequence of Images, and each Image after the first typically only holds pixel data for the area that changed, and that area doesn't necessarily start at (0, 0). The correct way to iterate over an Image m's pixels looks like:


b := m.Bounds()
for y := b.Min.Y; y < b.Max.Y; y++ {
for x := b.Min.X; y < b.Max.X; x++ {
doStuffWith(m.At(x, y))
}
}

Image implementations do not have to be based on an in-memory slice of pixel data. For example, a Uniform is an Image of enormous bounds and uniform color, whose in-memory representation is simply that color.

type Uniform struct {
C color.Color
}

Typically, though, programs will want an image based on a slice. Struct types like RGBA and Gray (which other packages refer to as image.RGBA and image.Gray) hold slices of pixel data and implement the Image interface.

type RGBA struct {
// Pix holds the image's pixels, in R, G, B, A order. The pixel at
// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*4].
Pix []uint8
// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
Stride int
// Rect is the image's bounds.
Rect Rectangle
}

These types also provide a Set(x, y int, c color.Color) method that allows modifying the image one pixel at a time.

    m := image.NewRGBA(image.Rect(0, 0, 640, 480))
m.Set(5, 5, color.RGBA{255, 0, 0, 255})

If you're reading or writing a lot of pixel data, it can be more efficient, but more complicated, to access these struct type's Pix field directly.

The slice-based Image implementations also provide a SubImage method, which returns an Image backed by the same array. Modifying the pixels of a sub-image will affect the pixels of the original image, analagous to how modifying the contents of a sub-slice s[i0:i1] will affect the contents of the original slice s.

    m0 := image.NewRGBA(image.Rect(0, 0, 8, 5))
m1 := m0.SubImage(image.Rect(1, 2, 5, 5)).(*image.RGBA)
fmt.Println(m0.Bounds().Dx(), m1.Bounds().Dx()) // prints 8, 4
fmt.Println(m0.Stride == m1.Stride) // prints true

For low-level code that works on an image's Pix field, be aware that ranging over Pix can affect pixels outside an image's bounds. In the example above, the pixels covered by m1.Pix are shaded in blue. Higher-level code, such as the At and Setmethods or the image/draw package, will clip their operations to the image's bounds.

Image Formats

The standard package library supports a number of common image formats, such as GIF, JPEG and PNG. If you know the format of a source image file, you can decode from an io.Reader directly.


import (
"image/jpeg"
"image/png"
"io"
)

// convertJPEGToPNG converts from JPEG to PNG.
func convertJPEGToPNG(w io.Writer, r io.Reader) error {
img, err := jpeg.Decode(r)
if err != nil {
return err
}
return png.Encode(w, img)
}

If you have image data of unknown format, the image.Decode function can detect the format. The set of recognized formats is constructed at run time and is not limited to those in the standard package library. An image format package typically registers its format in an init function, and the main package will "underscore import" such a package solely for the side effect of format registration.


import (
"image"
"image/png"
"io"

_ "code.google.com/p/vp8-go/webp"
_ "image/jpeg"
)

// convertToPNG converts from any recognized format to PNG.
func convertToPNG(w io.Writer, r io.Reader) error {
img, _, err := image.Decode(r)
if err != nil {
return err
}
return png.Encode(w, img)
}

by Andrew Gerrand (noreply@blogger.com) at March 28, 2012 03:31 AM

March 27, 2012

Go's official blog

The Go image/draw package

Package image/draw defines only one operation: drawing a source image onto a destination image, through an optional mask image. This one operation is surprisingly versatile and can perform a number of common image manipulation tasks elegantly and efficiently.

Composition is performed pixel by pixel in the style of the Plan 9 graphics library and the X Render extension. The model is based on the classic "Compositing Digital Images" paper by Porter and Duff, with an additional mask parameter: dst = (src IN mask) OP dst. For a fully opaque mask, this reduces to the original Porter-Duff formula: dst = src OP dst. In Go, a nil mask image is equivalent to an infinitely sized, fully opaque mask image.

The Porter-Duff paper presented 12 different composition operators, but with an explicit mask, only 2 of these are needed in practice: source-over-destination and source. In Go, these operators are represented by the Over and Src constants. The Over operator performs the natural layering of a source image over a destination image: the change to the destination image is smaller where the source (after masking) is more transparent (that is, has lower alpha). The Src operator merely copies the source (after masking) with no regard for the destination image's original content. For fully opaque source and mask images, the two operators produce the same output, but the Src operator is usually faster.

Geometric Alignment

Composition requires associating destination pixels with source and mask pixels. Obviously, this requires destination, source and mask images, and a composition operator, but it also requires specifying what rectangle of each image to use. Not every drawing should write to the entire destination: when updating an animating image, it is more efficient to only draw the parts of the image that have changed. Not every drawing should read from the entire source: when using a sprite that combines many small images into one large one, only a part of the image is needed. Not every drawing should read from the entire mask: a mask image that collects a font's glyphs is similar to a sprite. Thus, drawing also needs to know three rectangles, one for each image. Since each rectangle has the same width and height, it suffices to pass a destination rectangle `r` and two points sp and mp: the source rectangle is equal to rtranslated so that r.Min in the destination image aligns with sp in the source image, and similarly for mp. The effective rectangle is also clipped to each image's bounds in their respective co-ordinate space.

The DrawMaskfunction takes seven arguments, but an explicit mask and mask-point are usually unnecessary, so the Draw function takes five:


// Draw calls DrawMask with a nil mask.
func Draw(dst Image, r image.Rectangle, src image.Image, sp image.Point, op Op)
func DrawMask(dst Image, r image.Rectangle, src image.Image, sp image.Point,
mask image.Image, mp image.Point, op Op)

The destination image must be mutable, so the image/draw package defines a draw.Imageinterface which has a Set method.

type Image interface {
image.Image
Set(x, y int, c color.Color)
}

Filling a Rectangle

To fill a rectangle with a solid color, use an image.Uniformsource. The ColorImage type re-interprets a Color as a practically infinite-sized Image of that color. For those familiar with the design of Plan 9's draw library, there is no need for an explicit "repeat bit" in Go's slice-based image types; the concept is subsumed by Uniform.

    // image.ZP is the zero point -- the origin.
draw.Draw(dst, r, &image.Uniform{c}, image.ZP, draw.Src)

To initialize a new image to all-blue:

    m := image.NewRGBA(image.Rect(0, 0, 640, 480))
blue := color.RGBA{0, 0, 255, 255}
draw.Draw(m, m.Bounds(), &image.Uniform{blue}, image.ZP, draw.Src)

To reset an image to transparent (or black, if the destination image's color model cannot represent transparency), use image.Transparent, which is an image.Uniform:

    draw.Draw(m, m.Bounds(), image.Transparent, image.ZP, draw.Src)

Copying an Image

To copy from a rectangle sr in the source image to a rectangle starting at a point dp in the destination, convert the source rectangle into the destination image's co-ordinate space:

    r := image.Rectangle{dp, dp.Add(sr.Size())}
draw.Draw(dst, r, src, sr.Min, draw.Src)

Alternatively:

    r := sr.Sub(sr.Min).Add(dp)
draw.Draw(dst, r, src, sr.Min, draw.Src)

To copy the entire source image, use sr = src.Bounds().

Scrolling an Image

Scrolling an image is just copying an image to itself, with different destination and source rectangles. Overlapping destination and source images are perfectly valid, just as Go's built-in copy function can handle overlapping destination and source slices. To scroll an image m by 20 pixels:

    b := m.Bounds()
p := image.Pt(0, 20)
// Note that even though the second argument is b,
// the effective rectangle is smaller due to clipping.
draw.Draw(m, b, m, b.Min.Add(p), draw.Src)
dirtyRect := b.Intersect(image.Rect(b.Min.X, b.Max.Y-20, b.Max.X, b.Max.Y))

Converting an Image to RGBA

The result of decoding an image format might not be an image.RGBA: decoding a GIF results in an image.Paletted, decoding a JPEG results in a ycbcr.YCbCr, and the result of decoding a PNG depends on the image data. To convert any image to an image.RGBA:

    b := src.Bounds()
m := image.NewRGBA(image.Rect(0, 0, b.Dx(), b.Dy()))
draw.Draw(m, m.Bounds(), src, b.Min, draw.Src)

Drawing Through a Mask

To draw an image through a circular mask with center p and radius r:

type circle struct {
p image.Point
r int
}

func (c *circle) ColorModel() color.Model {
return color.AlphaModel
}

func (c *circle) Bounds() image.Rectangle {
return image.Rect(c.p.X-c.r, c.p.Y-c.r, c.p.X+c.r, c.p.Y+c.r)
}

func (c *circle) At(x, y int) color.Color {
xx, yy, rr := float64(x-c.p.X)+0.5, float64(y-c.p.Y)+0.5, float64(c.r)
if xx*xx+yy*yy < rr*rr {
return color.Alpha{255}
}
return color.Alpha{0}
}
    draw.DrawMask(dst, dst.Bounds(), src, image.ZP, &circle{p, r}, image.ZP, draw.Over)

Drawing Font Glyphs

To draw a font glyph in blue starting from a point p, draw with an image.ColorImage source and an image.Alpha mask. For simplicity, we aren't performing any sub-pixel positioning or rendering, or correcting for a font's height above a baseline.

    src := &image.Uniform{color.RGBA{0, 0, 255, 255}}
mask := theGlyphImageForAFont()
mr := theBoundsFor(glyphIndex)
draw.DrawMask(dst, mr.Sub(mr.Min).Add(p), src, image.ZP, mask, mr.Min, draw.Over)

Performance

The image/draw package implementation demonstrates how to provide an image manipulation function that is both general purpose, yet efficient for common cases. The DrawMask function takes arguments of interface types, but immediately makes type assertions that its arguments are of specific struct types, corresponding to common operations like drawing one image.RGBA image onto another, or drawing an image.Alpha mask (such as a font glyph) onto an image.RGBA image. If a type assertion succeeds, that type information is used to run a specialized implementation of the general algorithm. If the assertions fail, the fallback code path uses the generic At and Set methods. The fast-paths are purely a performance optimization; the resultant destination image is the same either way. In practice, only a small number of special cases are necessary to support typical applications.

by Nigel Tao (noreply@blogger.com) at March 27, 2012 07:37 AM

Godoc: documenting Go code

The Go project takes documentation seriously. Documentation is a huge part of making software accessible and maintainable. Of course it must be well-written and accurate, but it also must be easy to write and to maintain. Ideally, it should be coupled to the code itself so the documentation evolves along with the code. The easier it is for programmers to produce good documentation, the better for everyone.

To that end, we have developed the godoc documentation tool. This article describes godoc's approach to documentation, and explains how you can use our conventions and tools to write good documentation for your own projects.

Godoc parses Go source code - including comments - and produces documentation as HTML or plain text. The end result is documentation tightly coupled with the code it documents. For example, through godoc's web interface you can navigate from a function's documentation to its implementation with one click.

Godoc is conceptually related to Python's Docstring and Java's Javadoc, but its design is simpler. The comments read by godoc are not language constructs (as with Docstring) nor must they have their own machine-readable syntax (as with Javadoc). Godoc comments are just good comments, the sort you would want to read even if godoc didn't exist.

The convention is simple: to document a type, variable, constant, function, or even a package, write a regular comment directly preceding its declaration, with no intervening blank line. Godoc will then present that comment as text alongside the item it documents. For example, this is the documentation for the fmt package's Fprintfunction:

// Fprint formats using the default formats for its operands and writes to w.
// Spaces are added between operands when neither is a string.
// It returns the number of bytes written and any write error encountered.
func Fprint(w io.Writer, a ...interface{}) (n int, err error) {

Notice this comment is a complete sentence that begins with the name of the element it describes. This important convention allows us to generate documentation in a variety of formats, from plain text to HTML to UNIX man pages, and makes it read better when tools truncate it for brevity, such as when they extract the first line or sentence.

Comments on package declarations should provide general package documentation. These comments can be short, like the sortpackage's brief description:

// Package sort provides primitives for sorting slices and user-defined
// collections.
package sort

They can also be detailed like the gob package's overview. That package uses another convention for packages that need large amounts of introductory documentation: the package comment is placed in its own file, doc.go, which contains only those comments and a package clause.

When writing package comments of any size, keep in mind that their first sentence will appear in godoc's package list.

Comments that are not adjacent to a top-level declaration are omitted from godoc's output, with one notable exception. Top-level comments that begin with the word "BUG(who)” are recognized as known bugs, and included in the "Bugs” section of the package documentation. The "who” part should be the user name of someone who could provide more information. For example, this is a known issue from the bytes package:


// BUG(r): The rule Title uses for word boundaries does not handle Unicode punctuation properly.

Godoc treats executable commands somewhat differently. Instead of inspecting the command source code, it looks for a Go source file belonging to the special package "documentation”. The comment on the "package documentation” clause is used as the command's documentation. For example, see the godoc documentation and its corresponding doc.go file.

There are a few formatting rules that Godoc uses when converting comments to HTML:

  • Subsequent lines of text are considered part of the same paragraph; you must leave a blank line to separate paragraphs.
  • Pre-formatted text must be indented relative to the surrounding comment text (see gob's doc.go for an example).
  • URLs will be converted to HTML links; no special markup is necessary.

Note that none of these rules requires you to do anything out of the ordinary.

In fact, the best thing about godoc's minimal approach is how easy it is to use. As a result, a lot of Go code, including all of the standard library, already follows the conventions.

Your own code can present good documentation just by having comments as described above. Any Go packages installed inside $GOROOT/src/pkgand any GOPATH work spaces will already be accessible via godoc's command-line and HTTP interfaces, and you can specify additional paths for indexing via the -path flag or just by running "godoc ."in the source directory. See the godoc documentationfor more details.

by Andrew Gerrand (noreply@blogger.com) at March 27, 2012 07:31 AM

The Laws of Reflection

Reflection in computing is the ability of a program to examine its own structure, particularly through types; it's a form of metaprogramming. It's also a great source of confusion.

In this article we attempt to clarify things by explaining how reflection works in Go. Each language's reflection model is different (and many languages don't support it at all), but this article is about Go, so for the rest of this article the word "reflection" should be taken to mean "reflection in Go".

Types and interfaces

Because reflection builds on the type system, let's start with a refresher about types in Go.

Go is statically typed. Every variable has a static type, that is, exactly one type known and fixed at compile time: int, float32, *MyType, []byte, and so on. If we declare

type MyInt int

var i int
var j MyInt

then i has type int and jhas type MyInt. The variables i and j have distinct static types and, although they have the same underlying type, they cannot be assigned to one another without a conversion.

One important category of type is interface types, which represent fixed sets of methods. An interface variable can store any concrete (non-interface) value as long as that value implements the interface's methods. A well-known pair of examples is io.Reader and io.Writer, the types Reader and Writer from the io package:

// Reader is the interface that wraps the basic Read method.
type Reader interface {
Read(p []byte) (n int, err error)
}

// Writer is the interface that wraps the basic Write method.
type Writer interface {
Write(p []byte) (n int, err error)
}

Any type that implements a Read (or Write) method with this signature is said to implement io.Reader (or io.Writer). For the purposes of this discussion, that means that a variable of type io.Reader can hold any value whose type has a Read method:

    var r io.Reader
r = os.Stdin
r = bufio.NewReader(r)
r = new(bytes.Buffer)
// and so on

It's important to be clear that whatever concrete value r may hold, r's type is always io.Reader: Go is statically typed and the static type of r is io.Reader.

An extremely important example of an interface type is the empty interface:


interface{}

It represents the empty set of methods and is satisfied by any value at all, since any value has zero or more methods.

Some people say that Go's interfaces are dynamically typed, but that is misleading. They are statically typed: a variable of interface type always has the same static type, and even though at run time the value stored in the interface variable may change type, that value will always satisfy the interface.

We need to be precise about all this because reflection and interfaces are closely related.

The representation of an interface

Russ Cox has written a detailed blog post about the representation of interface values in Go. It's not necessary to repeat the full story here, but a simplified summary is in order.

A variable of interface type stores a pair: the concrete value assigned to the variable, and that value's type descriptor. To be more precise, the value is the underlying concrete data item that implements the interface and the type describes the full type of that item. For instance, after

    var r io.Reader
tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)
if err != nil {
return nil, err
}
r = tty

r contains, schematically, the (value, type) pair, (tty, *os.File). Notice that the type *os.File implements methods other than Read; even though the interface value provides access only to the Read method, the value inside carries all the type information about that value. That's why we can do things like this:

    var w io.Writer
w = r.(io.Writer)

The expression in this assignment is a type assertion; what it asserts is that the item inside r also implements io.Writer, and so we can assign it to w. After the assignment, w will contain the pair (tty, *os.File). That's the same pair as was held in r. The static type of the interface determines what methods may be invoked with an interface variable, even though the concrete value inside may have a larger set of methods.

Continuing, we can do this:

    var empty interface{}
empty = w

and our empty interface value e will again contain that same pair, (tty, *os.File). That's handy: an empty interface can hold any value and contains all the information we could ever need about that value.

(We don't need a type assertion here because it's known statically that w satisfies the empty interface. In the example where we moved a value from a Reader to a Writer, we needed to be explicit and use a type assertion because Writer's methods are not a subset of Reader's.)

One important detail is that the pair inside an interface always has the form (value, concrete type) and cannot have the form (value, interface type). Interfaces do not hold interface values.

Now we're ready to reflect.

The first law of reflection

1. Reflection goes from interface value to reflection object.

At the basic level, reflection is just a mechanism to examine the type and value pair stored inside an interface variable. To get started, there are two types we need to know about in package reflect: Type and Value. Those two types give access to the contents of an interface variable, and two simple functions, called reflect.TypeOf and reflect.ValueOf, retrieve reflect.Typeand reflect.Value pieces out of an interface value. (Also, from the reflect.Value it's easy to get to the reflect.Type, but let's keep the Value and Type concepts separate for now.)

Let's start with TypeOf:

package main

import (
"fmt"
"reflect"
)

func main() {
var x float64 = 3.4
fmt.Println("type:", reflect.TypeOf(x))
}

This program prints


type: float64

You might be wondering where the interface is here, since the program looks like it's passing the float64variable x, not an interface value, to reflect.TypeOf. But it's there; as godoc reports, the signature of reflect.TypeOf includes an empty interface:


// TypeOf returns the reflection Type of the value in the interface{}.
func TypeOf(i interface{}) Type

When we call reflect.TypeOf(x), x is first stored in an empty interface, which is then passed as the argument; reflect.TypeOf unpacks that empty interface to recover the type information.

The reflect.ValueOf function, of course, recovers the value (from here on we'll elide the boilerplate and focus just on the executable code):

    var x float64 = 3.4
fmt.Println("value:", reflect.ValueOf(x))

prints


value: <float64 Value>

Both reflect.Type and reflect.Value have lots of methods to let us examine and manipulate them. One important example is that Value has a Type method that returns the Type of a reflect.Value. Another is that both Typeand Value have a Kind method that returns a constant indicating what sort of item is stored: Uint, Float64, Slice, and so on. Also methods on Value with names like Int and Float let us grab values (as int64 and float64) stored inside:

    var x float64 = 3.4
v := reflect.ValueOf(x)
fmt.Println("type:", v.Type())
fmt.Println("kind is float64:", v.Kind() == reflect.Float64)
fmt.Println("value:", v.Float())

prints


type: float64
kind is float64: true
value: 3.4

There are also methods like SetInt and SetFloat but to use them we need to understand settability, the subject of the third law of reflection, discussed below.

The reflection library has a couple of properties worth singling out. First, to keep the API simple, the "getter" and "setter" methods of Value operate on the largest type that can hold the value: int64 for all the signed integers, for instance. That is, the Int method of Value returns an int64 and the SetInt value takes an int64; it may be necessary to convert to the actual type involved:

    var x uint8 = 'x'
v := reflect.ValueOf(x)
fmt.Println("type:", v.Type()) // uint8.
fmt.Println("kind is uint8: ", v.Kind() == reflect.Uint8) // true.
x = uint8(v.Uint()) // v.Uint returns a uint64.

The second property is that the Kind of a reflection object describes the underlying type, not the static type. If a reflection object contains a value of a user-defined integer type, as in

    type MyInt int
var x MyInt = 7
v := reflect.ValueOf(x)

the Kind of v is still reflect.Int, even though the static type of x is MyInt, not int. In other words, the Kind cannot discriminate an int from a MyInt even though the Type can.

The second law of reflection

2. Reflection goes from reflection object to interface value.

Like physical reflection, reflection in Go generates its own inverse.

Given a reflect.Value we can recover an interface value using the Interface method; in effect the method packs the type and value information back into an interface representation and returns the result:


// Interface returns v's value as an interface{}.
func (v Value) Interface() interface{}

As a consequence we can say

    y := v.Interface().(float64) // y will have type float64.
fmt.Println(y)

to print the float64 value represented by the reflection object v.

We can do even better, though. The arguments to fmt.Println, fmt.Printf and so on are all passed as empty interface values, which are then unpacked by the fmt package internally just as we have been doing in the previous examples. Therefore all it takes to print the contents of a reflect.Value correctly is to pass the result of the Interface method to the formatted print routine:

    fmt.Println(v.Interface())

(Why not fmt.Println(v)? Because v is a reflect.Value; we want the concrete value it holds.) Since our value is a float64, we can even use a floating-point format if we want:

    fmt.Printf("value is %7.1e\n", v.Interface())

and get in this case


3.4e+00

Again, there's no need to type-assert the result of v.Interface() to float64; the empty interface value has the concrete value's type information inside and Printf will recover it.

In short, the Interface method is the inverse of the ValueOf function, except that its result is always of static type interface{}.

Reiterating: Reflection goes from interface values to reflection objects and back again.

The third law of reflection

3. To modify a reflection object, the value must be settable.

The third law is the most subtle and confusing, but it's easy enough to understand if we start from first principles.

Here is some code that does not work, but is worth studying.

    var x float64 = 3.4
v := reflect.ValueOf(x)
v.SetFloat(7.1) // Error: will panic.

If you run this code, it will panic with the cryptic message


panic: reflect.Value.SetFloat using unaddressable value

The problem is not that the value 7.1 is not addressable; it's that v is not settable. Settability is a property of a reflection Value, and not all reflection Values have it.

The CanSet method of Value reports the settability of a Value; in our case,

    var x float64 = 3.4
v := reflect.ValueOf(x)
fmt.Println("settability of v:", v.CanSet())

prints


settability of v: false

It is an error to call a Set method on an non-settable Value. But what is settability?

Settability is a bit like addressability, but stricter. It's the property that a reflection object can modify the actual storage that was used to create the reflection object. Settability is determined by whether the reflection object holds the original item. When we say

    var x float64 = 3.4
v := reflect.ValueOf(x)

we pass a copy of x to reflect.ValueOf, so the interface value created as the argument to reflect.ValueOf is a copy of x, not x itself. Thus, if the statement

    v.SetFloat(7.1)

were allowed to succeed, it would not update x, even though v looks like it was created from x. Instead, it would update the copy of xstored inside the reflection value and x itself would be unaffected. That would be confusing and useless, so it is illegal, and settability is the property used to avoid this issue.

If this seems bizarre, it's not. It's actually a familiar situation in unusual garb. Think of passing x to a function:


f(x)

We would not expect f to be able to modify x because we passed a copy of x's value, not x itself. If we want f to modify x directly we must pass our function the address of x (that is, a pointer to x):

f(&x)

This is straightforward and familiar, and reflection works the same way. If we want to modify x by reflection, we must give the reflection library a pointer to the value we want to modify.

Let's do that. First we initialize x as usual and then create a reflection value that points to it, called p.

    var x float64 = 3.4
p := reflect.ValueOf(&x) // Note: take the address of x.
fmt.Println("type of p:", p.Type())
fmt.Println("settability of p:", p.CanSet())

The output so far is


type of p: *float64
settability of p: false

The reflection object p isn't settable, but it's not p we want to set, it's (in effect) *p. To get to what p points to, we call the Elemmethod of Value, which indirects through the pointer, and save the result in a reflection Value called v:

    v := p.Elem()
fmt.Println("settability of v:", v.CanSet())

Now v is a settable reflection object, as the output demonstrates,


settability of v: true

and since it represents x, we are finally able to use v.SetFloat to modify the value of x:

    v.SetFloat(7.1)
fmt.Println(v.Interface())
fmt.Println(x)

The output, as expected, is


7.1
7.1

Reflection can be hard to understand but it's doing exactly what the language does, albeit through reflection Types and Values that can disguise what's going on. Just keep in mind that reflection Values need the address of something in order to modify what they represent.

Structs

In our previous example v wasn't a pointer itself, it was just derived from one. A common way for this situation to arise is when using reflection to modify the fields of a structure. As long as we have the address of the structure, we can modify its fields.

Here's a simple example that analyzes a struct value, t. We create the reflection object with the address of the struct because we'll want to modify it later. Then we set typeOfT to its type and iterate over the fields using straightforward method calls (see package reflect for details). Note that we extract the names of the fields from the struct type, but the fields themselves are regular reflect.Valueobjects.

    type T struct {
A int
B string
}
t := T{23, "skidoo"}
s := reflect.ValueOf(&t).Elem()
typeOfT := s.Type()
for i := 0; i < s.NumField(); i++ {
f := s.Field(i)
fmt.Printf("%d: %s %s = %v\n", i,
typeOfT.Field(i).Name, f.Type(), f.Interface())
}

The output of this program is


0: A int = 23
1: B string = skidoo

There's one more point about settability introduced in passing here: the field names of T are upper case (exported) because only exported fields of a struct are settable.

Because s contains a settable reflection object, we can modify the fields of the structure.

    s.Field(0).SetInt(77)
s.Field(1).SetString("Sunset Strip")
fmt.Println("t is now", t)

And here's the result:


t is now {77 Sunset Strip}

If we modified the program so that s was created from t, not &t, the calls to SetInt and SetString would fail as the fields of t would not be settable.

Conclusion

Here again are the laws of reflection:

  1. Reflection goes from interface value to reflection object.
  2. Reflection goes from reflection object to interface value.
  3. To modify a reflection object, the value must be settable.

Once you understand these laws reflection in Go becomes much easier to use, although it remains subtle. It's a powerful tool that should be used with care and avoided unless strictly necessary.

There's plenty more to reflection that we haven't covered — sending and receiving on channels, allocating memory, using slices and maps, calling methods and functions — but this post is long enough. We'll cover some of those topics in a later article.

by Andrew Gerrand (noreply@blogger.com) at March 27, 2012 07:27 AM

Gobs of data

To transmit a data structure across a network or to store it in a file, it mustbe encoded and then decoded again. There are many encodings available, ofcourse: JSON,XML, Google'sprotocol buffers, and more.And now there's another, provided by Go's gobpackage.

Why define a new encoding? It's a lot of work and redundant at that. Why notjust use one of the existing formats? Well, for one thing, we do! Go haspackages supporting all the encodings just mentioned (theprotocol buffer package is ina separate repository but it's one of the most frequently downloaded). And formany purposes, including communicating with tools and systems written in otherlanguages, they're the right choice.

But for a Go-specific environment, such as communicating between two serverswritten in Go, there's an opportunity to build something much easier to use andpossibly more efficient.

Gobs work with the language in a way that an externally-defined,language-independent encoding cannot. At the same time, there are lessons to belearned from the existing systems.

Goals

The gob package was designed with a number of goals in mind.

First, and most obvious, it had to be very easy to use. First, because Go hasreflection, there is no need for a separate interface definition language or"protocol compiler". The data structure itself is all the package should needto figure out how to encode and decode it. On the other hand, this approachmeans that gobs will never work as well with other languages, but that's OK:gobs are unashamedly Go-centric.

Efficiency is also important. Textual representations, exemplified by XML andJSON, are too slow to put at the center of an efficient communications network.A binary encoding is necessary.

Gob streams must be self-describing. Each gob stream, read from the beginning,contains sufficient information that the entire stream can be parsed by anagent that knows nothing a priori about its contents. This property means thatyou will always be able to decode a gob stream stored in a file, even longafter you've forgotten what data it represents.

There were also some things to learn from our experiences with Google protocolbuffers.

Protocol buffer misfeatures

Protocol buffers had a major effect on the design of gobs, but have threefeatures that were deliberately avoided. (Leaving aside the property thatprotocol buffers aren't self-describing: if you don't know the data definitionused to encode a protocol buffer, you might not be able to parse it.)

First, protocol buffers only work on the data type we call a struct in Go. Youcan't encode an integer or array at the top level, only a struct with fieldsinside it. That seems a pointless restriction, at least in Go. If all you wantto send is an array of integers, why should you have to put it into astruct first?

Next, a protocol buffer definition may specify that fields T.x andT.y are required to be present whenever a value of typeT is encoded or decoded. Although such required fields may seemlike a good idea, they are costly to implement because the codec must maintain aseparate data structure while encoding and decoding, to be able to report whenrequired fields are missing. They're also a maintenance problem. Over time, onemay want to modify the data definition to remove a required field, but that maycause existing clients of the data to crash. It's better not to have them in theencoding at all. (Protocol buffers also have optional fields. But if we don'thave required fields, all fields are optional and that's that. There will bemore to say about optional fields a little later.)

The third protocol buffer misfeature is default values. If a protocol bufferomits the value for a "defaulted" field, then the decoded structure behaves asif the field were set to that value. This idea works nicely when you havegetter and setter methods to control access to the field, but is harder tohandle cleanly when the container is just a plain idiomatic struct. Requiredfields are also tricky to implement: where does one define the default values,what types do they have (is text UTF-8? uninterpreted bytes? how many bits in afloat?) and despite the apparent simplicity, there were a number ofcomplications in their design and implementation for protocol buffers. Wedecided to leave them out of gobs and fall back to Go's trivial but effectivedefaulting rule: unless you set something otherwise, it has the "zero value"for that type - and it doesn't need to be transmitted.

So gobs end up looking like a sort of generalized, simplified protocol buffer.How do they work?

Values

The encoded gob data isn't about int8s and uint16s.Instead, somewhat analogous to constants in Go, its integer values are abstract,sizeless numbers, either signed or unsigned. When you encode anint8, its value is transmitted as an unsized, variable-lengthinteger. When you encode an int64, its value is also transmitted asan unsized, variable-length integer. (Signed and unsigned are treateddistinctly, but the same unsized-ness applies to unsigned values too.) If bothhave the value 7, the bits sent on the wire will be identical. When the receiverdecodes that value, it puts it into the receiver's variable, which may be ofarbitrary integer type. Thus an encoder may send a 7 that came from anint8, but the receiver may store it in an int64. Thisis fine: the value is an integer and as a long as it fits, everything works. (Ifit doesn't fit, an error results.) This decoupling from the size of the variablegives some flexibility to the encoding: we can expand the type of the integervariable as the software evolves, but still be able to decode old data.

This flexibility also applies to pointers. Before transmission, all pointers areflattened. Values of type int8, *int8,**int8, ****int8, etc. are all transmitted as aninteger value, which may then be stored in int of any size, or*int, or ******int, etc. Again, this allows forflexibility.

Flexibility also happens because, when decoding a struct, only those fieldsthat are sent by the encoder are stored in the destination. Given the value

type T struct{ X, Y, Z int } // Only exported fields are encoded and decoded.
var t = T{X: 7, Y: 0, Z: 8}

the encoding of t sends only the 7 and 8. Because it's zero, thevalue of Y isn't even sent; there's no need to send a zero value.

The receiver could instead decode the value into this structure:

type U struct{ X, Y *int8 } // Note: pointers to int8s
var u U

and acquire a value of u with only X set (to theaddress of an int8 variable set to 7); the Z field isignored - where would you put it? When decoding structs, fields are matched byname and compatible type, and only fields that exist in both are affected. Thissimple approach finesses the "optional field" problem: as the typeT evolves by adding fields, out of date receivers will stillfunction with the part of the type they recognize. Thus gobs provide theimportant result of optional fields - extensibility - without any additionalmechanism or notation.

From integers we can build all the other types: bytes, strings, arrays, slices,maps, even floats. Floating-point values are represented by their IEEE 754floating-point bit pattern, stored as an integer, which works fine as long asyou know their type, which we always do. By the way, that integer is sent inbyte-reversed order because common values of floating-point numbers, such assmall integers, have a lot of zeros at the low end that we can avoidtransmitting.

One nice feature of gobs that Go makes possible is that they allow you to defineyour own encoding by having your type satisfy theGobEncoder andGobDecoder interfaces, in a manneranalogous to the JSON package'sMarshaler andUnmarshaler and also to theStringer interface frompackage fmt. This facility makes it possible torepresent special features, enforce constraints, or hide secrets when youtransmit data. See the documentation fordetails.

Types on the wire

The first time you send a given type, the gob package includes in the datastream a description of that type. In fact, what happens is that the encoder isused to encode, in the standard gob encoding format, an internal struct thatdescribes the type and gives it a unique number. (Basic types, plus the layoutof the type description structure, are predefined by the software forbootstrapping.) After the type is described, it can be referenced by its typenumber.

Thus when we send our first type T, the gob encoder sends adescription of T and tags it with a type number, say 127. Allvalues, including the first, are then prefixed by that number, so a stream ofT values looks like:


("define type id" 127, definition of type T)(127, T value)(127, T value), ...

These type numbers make it possible to describe recursive types and send valuesof those types. Thus gobs can encode types such as trees:

type Node struct {
Value int
Left, Right *Node
}

(It's an exercise for the reader to discover how the zero-defaulting rule makesthis work, even though gobs don't represent pointers.)

With the type information, a gob stream is fully self-describing except for theset of bootstrap types, which is a well-defined starting point.

Compiling a machine

The first time you encode a value of a given type, the gob package builds alittle interpreted machine specific to that data type. It uses reflection onthe type to construct that machine, but once the machine is built it does notdepend on reflection. The machine uses package unsafe and some trickery toconvert the data into the encoded bytes at high speed. It could use reflectionand avoid unsafe, but would be significantly slower. (A similar high-speedapproach is taken by the protocol buffer support for Go, whose design wasinfluenced by the implementation of gobs.) Subsequent values of the same typeuse the already-compiled machine, so they can be encoded right away.

Decoding is similar but harder. When you decode a value, the gob package holdsa byte slice representing a value of a given encoder-defined type to decode,plus a Go value into which to decode it. The gob package builds a machine forthat pair: the gob type sent on the wire crossed with the Go type provided fordecoding. Once that decoding machine is built, though, it's again areflectionless engine that uses unsafe methods to get maximum speed.

Use

There's a lot going on under the hood, but the result is an efficient,easy-to-use encoding system for transmitting data. Here's a complete exampleshowing differing encoded and decoded types. Note how easy it is to send andreceive values; all you need to do is present values and variables to thegob package and it does all the work.

package main

import (
"bytes"
"encoding/gob"
"fmt"
"log"
)

type P struct {
X, Y, Z int
Name string
}

type Q struct {
X, Y *int32
Name string
}

func main() {
// Initialize the encoder and decoder. Normally enc and dec would be
// bound to network connections and the encoder and decoder would
// run in different processes.
var network bytes.Buffer // Stand-in for a network connection
enc := gob.NewEncoder(&network) // Will write to network.
dec := gob.NewDecoder(&network) // Will read from network.
// Encode (send) the value.
err := enc.Encode(P{3, 4, 5, "Pythagoras"})
if err != nil {
log.Fatal("encode error:", err)
}
// Decode (receive) the value.
var q Q
err = dec.Decode(&q)
if err != nil {
log.Fatal("decode error:", err)
}
fmt.Printf("%q: {%d,%d}\n", q.Name, *q.X, *q.Y)
}

You can compile and run this example code in theGo Playground.

The rpc package builds on gobs to turn thisencode/decode automation into transport for method calls across the network.That's a subject for another article.

Details

The gob package documentation, especially thefile doc.go, expands on many of thedetails described here and includes a full worked example showing how theencoding represents data. If you are interested in the innards of the gobimplementation, that's a good place to start.

by Andrew Gerrand (noreply@blogger.com) at March 27, 2012 07:25 AM

March 26, 2012

Going Along

自由的翼,鹏翔

有感MikeSpook的小诗,作新体诗一首:

自由的翼
——和http://www.mikespook.com/2012/03/73字小诗

桌面
照片里的苍鹰
在飞越高山
可是它却
无法
飞过
压住它的玻璃板

尽管
不一样的世界
就在
无形的墙外面
但不知
天的另一边
是否有
可以停留的驿站
不知
自己的下一步
是不是
就到了终点

如果
真是自由的翼
就不会在乎
在冲撞中折断


附,发到golang-china里的旧体诗:

鹏翔

孤鹏展翅勿彷徨,
冬去春回枝满霜。
负笈含辛十数载,
墙外开花墙内香。

by Fango (noreply@blogger.com) at March 26, 2012 03:49 AM

March 18, 2012

embrace change

Go talk at GTUG Bremen

The next regulars' table of the GTUG Bremen will be on April, 2nd. This time I'll give a talk on Googles programming language Go. Topics will be

  • a short introduction into the history,
  • the basic features,
  • the special combination of elegance and power, and
  • Go in the wilderness.
The talk will be in English and the slides will be available afterwords via SlideShare.

by Frank Müller (noreply@blogger.com) at March 18, 2012 08:27 PM

March 17, 2012

Adam Langley

Very large RSA public exponents

After yesterday's post that advocated using RSA public exponents of 3 or 216+1 in DNSSEC for performance, Dan Kaminsky asked me whether there was a potential DoS vector by using really big public exponents.

Recall that the RSA signature verification core is me mod n. By making e and n larger, we can make the operation slower. But there are limits, at least in OpenSSL:

/* for large moduli, enforce exponent limit */
if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) {
        if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) {
                RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE);
                return -1;
        }
}

So, if n is large, we enforce a limit on e. The values of the #defines are such that for n>3072 bits, e must be less than or equal to 64 bits. So the slowest operations happen with an n and e of 3072 bits. (The fact that e<n is enforced earlier in the code.)

So I setup *.bige.imperialviolet.org. This is a perfectly valid and well signed zone which happens to use a 3072-bit key with a 3072-bit public exponent. (I could probably have slowed things down more by picking a public exponent with lots of 1s in its binary representation, but it's just a random number in this case.) One can resolve records 1.bige.imperialviolet.org, 2.bige.imperialviolet.org, … and the server doesn't have to sign anything because it's a wildcard: a single signature covers all of the names. However, the resolver validates the signature every time.

On my 2.66GHz, Core 2 laptop, 15 requests per second causes unbound to take 95% of a core. A couple hundred queries per second would probably put most DNSSEC resolvers in serious trouble.

So I'd recommend limiting the public exponent size in DNSSEC to 216+1, except that people are already mistakenly using 232+1, so I guess that needs to be the limit. The DNSSEC spec limits the modulus size to 4096-bits, and 4096-bit signatures are about 13 times slower to verify than the typical 1024-bit signatures used in DNSSEC. But that's a lot less of a DoS vector than bige.imperialviolet.org, which is 2230 times slower than normal.

March 17, 2012 07:00 AM

March 16, 2012

Adam Langley

RSA public exponent size

RSA public operations are much faster than private operations. Thirty-two times faster for a 2048-bit key on my machine. But the two operations are basically the same: take the message, raise it to the power of the public or private exponent and reduce modulo the key's modulus.

What makes the public operations so much faster is that the public exponent is typically tiny, while the private exponent should be the same size as the modulus. One can actually use a public exponent of three in RSA, and clearly cubing a number should be faster than raising it to the power of a 2048-bit number.

In 2006, Daniel Bleichenbacher (a fellow Googler) gave a talk at the CRYPTO 2006 rump session where he outlined a bug in several, very common RSA signature verification implementations at the time. The bug wasn't nearly as bad as it could have been because it only affected public keys that used a public exponent of three and most keys used a larger exponent: 216+1. But the fact that a slightly larger public exponent saved these buggy verifiers cemented 216+1 as sensible default value for the public exponent.

But there's absolutely no reason to think that a public exponent larger than 216+1 does any good. I even checked that with Bleichenbacher before writing this. Three should be fine, 216+1 saved some buggy software a couple of times and any larger is probably a mistake.

Because of that, when writing the Go RSA package, I didn't bother supporting public exponents larger than 231-1. But then several people reported that they couldn't verify some DNSSEC signatures. Sure enough, the DNSKEY records for .cz and .us are using a public exponent of 232+1.

DNSSEC is absolutely the last place to use large, public exponents. Busy DNS resolvers have to resolve tens or hundreds of thousands of records a second; fast RSA signature verification is big deal in DNSSEC. So I measured the speed impact of various public exponent sizes with OpenSSL (1.0.1-beta3):

Public exponentVerification time (µs)
310.6
216+123.9
232+142.7
2127-1160.7

So a public exponent of 232+1 makes signature verification over four times slower than an exponent of three. As DNSSEC grows, and DNSSEC resolvers too, that extra CPU time is going to be a big deal.

It looks like the zones using a value of 232+1 are just passing the -e flag to BIND's dnssec-keygen utility. There's some suggestion that -e used to select 216+1 but silently changed semantics in some release.

So today's lesson is don't pass -e to dnssec-keygen! The default of dnssec-keygen is 216+1 and that's certainly safe. The .com zone uses a value of three and I think that's probably the best choice given the CPU cost and the fact that the original Bleichenbacher bug has been long since fixed.

March 16, 2012 07:00 AM

March 05, 2012

embrace change

Added commit log

For those of your who are using my Tideland Common Go Library I've added a commit log to this blog. So you can easily see how it evolves. Currently I'm working on a refactoring of the cells package for event-driven applications. The handling has been too complex and uncomfortable and I also want to provide more default cell behaviors for an easy start.

by Frank Müller (noreply@blogger.com) at March 05, 2012 09:34 AM

March 04, 2012

Miek Gieben

Super-short guide to getting q (Part II)

The development of the language Go is going at a fast pace, hence an updated version of Super-short guide to gettinq q.

Get the latest version (called weekly) of Go:

  1. Get Go: hg clone -u release https://go.googlecode.com/hg/ go Note the directory you have downloaded it to and set add its bin directory to your PATH: PATH=$PWD/go/bin.

  2. Update Go to the latest weekly: cd go; hg pull; hg update weekly

  3. Compile Go: cd src, you should now sit in go/src. And compile: ./all.bash

Install missing commands (gcc, sed, bison, etc.) if needed.

The latest Go is now installed. You should now have the go-tool, this is the central interface to all Go program building tasks.

$ go
Go is a tool for managing Go source code.

Usage: go command [arguments]

The commands are:

build       compile packages and dependencies
clean       remove object files
doc         run godoc on package sources
fix         run go tool fix on packages
....
....
lost more

If you can not run go, check your PATH.

Install Go DNS and set GOPATH

The GOPATH variable specifies (among things) where your Go code lives. Using the go tool does bring a few requirements to the table in how to layout the directory structure.

  1. Create toplevel directory (~/g) for your code: mkdir -p ~/g/src
  2. Set GOPATH to this toplevel directory: export GOPATH=~/g
  3. Get dns: cd ~/g/src; git clone git://github.com/miekg/dns.git
  4. Compile it: cd dns; go build
  5. Compile and install the examples, there is a helper Makefile here, but it just calls go multiple times: cd ex; make
  6. Look in $GOPATH/bin for the binaries, in this setup that will be ~/g/bin
  7. Query with q: ~/g/bin/q mx miek.nl (or add ~/g/bin to your $PATH too)
  8. Report bugs

by Miek Gieben at March 04, 2012 09:54 AM

March 02, 2012

Adam Langley

Forward secrecy for IE and Safari too

When we announced forward secrecy for Google HTTPS we noted that “we hope to support IE in the future”. It wasn't that we didn't want to support IE, but IE doesn't implement the combination of ECDHE with RC4. IE (or rather, SChannel) does implement ECDHE with AES on Vista and Windows 7, but I only wanted to make one change at a time.

With the release of MS12-006 a month ago to address the BEAST weakness in TLS 1.0's CBC design, we've now made ECDHE-RSA-AES128-SHA our second preference cipher. That means that Chrome and Firefox will still use ECDHE-RSA-RC4-SHA, but IE on Vista and Windows 7 will get ECDHE now. This change also means that we support ECDHE with Safari (at least on Lion, where I tried it.)

March 02, 2012 08:00 AM

February 29, 2012

Airs – Ian Lance Taylor

Piece of PIE

Modern ELF systems can randomize the address at which shared libraries are loaded. This is generally referred to as Address Space Layout Randomization, or ASLR. Shared libraries are always position independent, which means that they can be loaded at any address. Randomizing the load address makes it slightly harder for attackers of a running program to exploit buffer overflows or similar problems, because they have no fixed addresses that they can rely on. ASLR is part of defense in depth: it does not by itself prevent any attacks, but it makes it slightly more difficult for attackers to exploit certain kinds of programming errors in a useful way beyond simply crashing the program.

Although it is straightforward to randomize the load address of a shared library, an ELF executable is normally linked to run at a fixed address that can not be changed. This means that attackers have a set of fixed addresses they can rely on. Permitting the kernel to randomize the address of the executable itself is done by generating a Position Independent Executable, or PIE.

It turns out to be quite simple to create a PIE: a PIE is simply an executable shared library. To make a shared library executable you just need to give it a PT_INTERP segment and appropriate startup code. The startup code can be the same as the usual executable startup code, though of course it must be compiled to be position independent.

When compiling code to go into a shared library, you use the -fpic option. When compiling code to go into a PIE, you use the -fpie option. Since a PIE is just a shared library, these options are almost exactly the same. The only difference is that since -fpie implies that you are building the main executable, there is no need to support symbol interposition for defined symbols. In a shared library, if function f1 calls f2, and f2 is globally visible, the code has to consider the possibility that f2 will be interposed. Thus, the call must go through the PLT. In a PIE, f2 can not be interposed, so the call may be made directly, though of course still in a position independent manner. Similarly, if the processor can do PC-relative loads and stores, all global variables can be accessed directly rather than going through the GOT.

Other than that ability to avoid the PLT and GOT in some cases, a PIE is really just a shared library. The dynamic linker will ask the kernel to map it at a random address and will then relocate it as usual.

This does imply that a PIE must be dynamically linked, in the sense of using the dynamic linker. Since the dynamic linker and the C library are closely intertwined, linking the PIE statically with the C library is unlikely to work in general. It is possible to design a statically linked PIE, in which the program relocates itself at startup time. The dynamic linker itself does this. However, there is no general mechanism for this at present.


by Ian Lance Taylor at February 29, 2012 03:33 PM

embrace change

Go usage at Google

Go is an interesting language moving towards its first release Go 1. And it's really exciting to see how it gets better each weekly release. But so far there are only few projects known where Go is used for real productive software (here is a first list containing also my employer Canonical). And it would be helpful to know that Google itself trusts in Go for their systems.

One first step has been the adding of Go to the Google App Engine, another one the usage of Go for the code search. Sadly that service has been shut down. But now they presented vitess, a project for the scaling of MySQL. And it's no theoretical project, it's used at YouTube.

There are also two interesting quotes by the developers why they've chosen Go:
"Go is miles ahead of C++ and Java in terms of expressibility and close in terms of performance. It is also relatively simple and has a straightforward interaction with Linux system calls."
It's the same experience I made using Go in professional and personal projects. But the next quote shows the importance of the improvement of the garbage collector:
"The main drawback is also its strength - the garbage collector. vtocc has made spot optimizations to minimize most of the adverse effects of Go’s stop-the-world gc. At this point, we are trading some amount of performance for greater creativity and efficiency at lower layers. unless you’re trying to max out on qps for your servers, you should see acceptable performance from vtocc. Also, go’s garbage collector is being improved. So, this should only get better over time. Go’s existing mark-and-sweep garbage collector is sub-optimal for systems that use large amounts of static memory (like caches). In the case of vtocc, this would be the row cache. To alleviate this, we intend to use memcache for the time being. If the gc ends up addressing this, it should be fairly trivial to switch to an in-memory row cache. Note that the row cache functionality is not fully ready yet."
Here I'm really looking forward to the next releases.

by Frank Müller (noreply@blogger.com) at February 29, 2012 09:59 AM

Go environment setup


A good start for Go development is a root directory for all further directories like /home/themue/projects. It will be the home for the Go SDK, 3rd party packages and own projects. The current weekly will be installed with the command hg clone -u weekly https://code.google.com/p/go in the directory go. http://weekly.golang.org/doc/install.html documents all needed steps in detail. The two other directories have to be created by hand, together with a src and a pkg subdirectory each. This way you get the structure
/home/themue/projects
        /go
                /bin
                ...
                /test
        /own
                /pkg
                /src
        /3rdparty
                /pkg
                /src
Why this 3rd party directory? The new Go tools have a very intelligent way to install external packages in a different directory than own packages. It's based on the environment variable $GOPATH. The naming already shows that it's a path, not only one directory. $GOPATH is the path where commands like go build and go install look for referenced packages they need to compile and link the software. To do so external packages have to be installed before. The command go get will install the sources and the compiled package into the first directory of the path. So the order in the case above should be
GOPATH=$HOME/projects/3rdparty:$HOME/projects/own
When installing own packages which source is located in .../own/src it will be installed into .../own/pkg.

Which environment variables else are needed? One is $GOROOT. It has to point to the root of the Go SDK, here /home/themue/projects/go. The compiled binaries will by default be installed in $GOROOT/bin. But there are two further options for the work with the SDK:

  • The location for the binaries is ok. Here the standard $PATH should point to this directory too with PATH=$PATH:$HOME/projects/go/bin.
  • The other way is that you've got a directory like $HOME/bin for all your private binaries and scripts and it's already in your $PATH. In this case you can set GOBIN=$HOME/bin before installing the Go SDK. In this case after the compilation the Go binaries get installed in your $HOME/bin.

Inside your own source directory you may need further subdirectories for your different projects. Their naming depends on possible external SCM environments you're using. Mine is code.google.com. So for the Tideland Common Go Library (see http://code.google.com/p/tcgl) I placed the source in
.../own/src/code.google.com/p/tcglThis project contains several packages which I now can import as code.google.com/p/tcgl/foo, regardless if I'm inside the same project or another one. And more important is that people who are taking a look into my code can easily see how to get and import it as their 3rd party code.

by Frank Müller (noreply@blogger.com) at February 29, 2012 09:01 AM

February 28, 2012

embrace change

Convinced by Sublime Text

During my now almost 30 years of software development I've used many editors (as well as IDEs). And you know, once you found your favorite one it's hard to change. There are holy wars on the net between the different fan groups. And everyone surely knows enough advantages for his acme, emacs, vim or any other one. After SPF/2 and SNiFF++ my favorite for about 17 years has been gvim. Straight, powerful, extendable and multi-platform. Also when working on remote machines via ssh the vim is a great partner. I've also tried emacs for some time and have been impressed by its power. But I stuck too deep into vim, so I never switched.

Now the situation changed. It started with the announcement of Sublime Text 2 Build 2165. Based on the good user resonance I gave it a try. It's available for my two operating systems Linux and OS X as well as for Windows, that's an important fact. I've been impressed immediately. The usage is exactly like expected, the feature list is long, all my languages a supported very well and there are many ways to extend and customized the system.


What I like most are the high level view on the content and the very good code completion. The later not only narrows the choices based on your written text from left to right. It analyzes all tokens the way the panicFailFunc() mentioned in the screenshot above may be found by entering pff or even pfc. Together with the language depending intelligent code snippets which are part of the code completion too it makes you really fast.

So for my Go code I'm writing tf which almost always leads directly to the tfunc snippet. Now a tab and the body of a type based function (aka method) is printed. The cursor is right in the type brackets. I'm typing m *mft and tab again which is expanded to m *MyFantasticType. Now the cursor is right where I've got to add the function name, after that where to put the argument, then the result and then right indented inside the function body. And here I can use other snippets as well as the intelligent code completion again. That's fun.

Also the navigation in the code is great. Cursor movement like expected doesn't wonder. But jumping word by word in an identifier like myLongFunctionNameExample() is great. Or jumping to a line (nothing new), jumping to a symbol (with the same way of code recognition like when coding) or just to any file in the current project (yes, it also has a project management). Also the highlighting of other occurrences of the selected text, multi-select, the Vintage mode for vim fans, powerful find and replace, and, and, and ...

But what do you do in case of missing parts? Here Sublime Text 2 is very configurable, so that the integration of new tools and programming languages is simple. Additionally you can record macros or extend the system using Python. Additionally there are many packages, most of them can be installed easily by Sublime Package Control. I used it so far to install SublimeHg for an easy access to Mercurial and SublimeREPL for different REPL environments - in my case LISP and the shell.

I haven't yet discovered everything, but I've been able to use it fluently with a remarkable speed-up from day 1. So I switched and use it now on Linux and Mac.

by Frank Müller (noreply@blogger.com) at February 28, 2012 11:18 AM

February 27, 2012

embrace change

New article about Redis

Tomorrow it will be available at the shops, I've got my copy already today like the other subscribers too: the new (German) iX magazine 3/2012. This time it contains my newest article about the great NoSQL database Redis. Its fantastic mix of performance and powerful data types and commands makes it my choice for my current Tideland project.

For those who need a Go client for Redis take a look at http://code.google.com/p/tcgl/.

by Frank Müller (noreply@blogger.com) at February 27, 2012 03:19 PM

February 26, 2012

embrace change

Restart of this blog

So, re-started this blog. It is now hosted at blogger.com and focussed on software development. Privat topics are handled at frank.mweb.de. But that blog is in German. The first topics are in the pipe, so stay tuned.

by Frank Müller (noreply@blogger.com) at February 26, 2012 07:41 PM

February 12, 2012

Adam Langley

RSA 2012

Just a brief note that I'll be at RSA 2012 in San Francisco at the end of the month and will be speaking with several others about certificate revocation. (tech-106, Tuesday, 1pm.).

If you want to chat and don't manage to grab me then, drop me an email. (agl at imperialviolet.org if you didn't already know.)

February 12, 2012 08:00 AM

February 11, 2012

Miek Gieben

godns is now dns

Due to the new go tool (long story), I've renamed godns to dns. This means the github repo is also somewhere else.

godns installed itself as dns so code using it does not need to be changed.

by Miek Gieben at February 11, 2012 10:09 PM

February 09, 2012

Going Along

Google App Engine with Go [1]

Google 的 App Engine 简称 GAE, 那我们的就叫 GAE Go, 读作"给够".

众所周知, GAE 就是谷歌"云运算"的那个"云". 为什么叫"云"? 传统的说法是互联网的模型画在纸上画不出来, 就随便圈几笔代表抽象的远端共享的意思, 据说又是继承了20世纪初老平电话系统的伟大光荣正确的优良传统. 而另一个貌似科学的说法, 是说云就是天上的水啊, 是湖里海里的水蒸腾上去, 再化成甘露滋润大地. 这番云雨过程, 是我们这些刚刚开始摆脱稍微软些的硬体束缚的 flower children 所热切渴望的. 我之所以要云雨呀的, 是想让程序员告诉另一半, 我们所从的业, 不总是干巴巴的, 有时也可以很湿润.

言归正传. GAE 开发者把 python 或 Java 的代码传上去, 申请一个 URL 指向它, 就可以用浏览器运行那些代码提供的服务了. 现在, 或说, 马上, 我们也可以在云端运行 Go 的云代码了.

开始写云代码的第一步, 当然是下载一个软件开发包. 没有 Linux 或 OSX 的窗口们, 还要再等等, 或者如前篇所示, 先 coLinux 着.

展开压缩包, 用 console 进入目录, 遵照传统仪式执行我们的第一个打招呼程式.

./dev_appserver.py demos/go-helloworld

GAE一直坚持使用Python 2.5, 所以可能会有个提醒说你的Python太新了会出问题. 现在还不会, 所以, 如果出了错, 可能是你拼写错了, 找不到 go-helloworld.

如果一切 ok, 它会说到 http://localhost:8080 看结果. 那我们就要用浏览器了. 记住这是云运算, 接收雨露要打开世界之窗, 把自己闭锁在再伟大的长墙里, 也造不出好车, 只能自己慢慢臭掉, 要死了也没人知道.

作为程序员, 我们不能只满足弄出个活就完了. 我们要有强烈的求知欲和审美观, 要揭开表面看内涵, 要学着鉴别那些僵化的, 冗长的, 低效的, 缺乏监督的东西, 是用再多钱也美化不了的丑, 再强权也遮掩不住的陋. 同时, 要欣赏那种灵活的, 简洁的, 能极速运行又有 compiler 滴水不漏纪律检查的体制设计, 所能带给我们的实实在在的安全和舒适.

又是口水一滩. 再次回到正题, 我们逐行审视这个招呼程式:

package counter            

应该是个笔误, 叫 package helloworld 比较准确, 但其实只要不叫 main, 又没和其他用到的 package 重名, 叫什么都无所谓. main 比较特殊, 它是每个 Go 程式的入口, 此处由 GAE 提供. 我们程式的入口, 是 init.

import(
    "fmt"
    "http"
)

引入 package fmt 和 http 这两个 Go 的标准包, 以便使用其提供的 format 和 http 功能.

func init(){
   http.HandleFunc("/", handle)
}

我们程序的入口, 注册 URL 根路径的访问由 handle 处理.

func handle(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "text/plain; charset=utf-8")
    fmt.Fprint(w, "Hello, World!\n")
}

我们的 handle 中, 浏览器的访问请求由 r 指向, 回应写入 w 缓冲区, 在 handle 返回时, 交由 GAE 传送给浏览器.

为了让 GAE 能正确找到我们的程序, 在 go-helloworld 目录下要准备一个叫 app.yaml 的配置文件, 主要内容为:

runtime: go

指定 GAE 运行的不是什么 Python 或 Java 模块, 而是我们亲爱的 Go.

handlers:
- url: /.*
  script: _go_app

告诉 GAE 把 / 下所有路径都交由 _go_app 处理. 小心不要拼错, 否则会莫明其妙的一堆 Python 错误, 害我浪费3个小时, 试图搞明白 Python 到底想告诉我什么. 其实也搞不明白, 因为它压根儿没提是我用 vi 的时候, 不小心在 _go_app 后面, 留下一个 d.

这个 _go_app 出现在 google/appengine/ext/go/ 的 __init__.py 里, 它是架通 _dev_appserver.py 和我们 Go 程序的桥梁.  当浏览器指向我们的 URL 的时候, _dev_appserver 会编译我们的 Go 程序, 并存放在 /tmp 下新创建一个的目录. 不出所料, 文件名就叫 _go_app, 是个货真价实的可执行文件, 而不像 Python 和 Java 那样要委身虚假机. 文件很大, 2.8兆个字节, 所有用到的库和运行环境全部打包独立自主, 不存在外部依赖, SAC? Stand-Alone Complex, 每个 _go_app 都是孤胆特种兵.

/tmp 下还有两个文件用来通信, 有兴趣就自己看看源代码, Open Source 在行政主管头里只是另一个主义, 在我们程序员眼里, 是破除封建迷信, 重拾科学民主精神的身体力行的源动力.

本来要就此收笔, 可 blogger 维修下线了, 就多唠叨两句, 也算是发个呼吁: "咱们搞语言的人, 可别荒废了母语, 大家多认真写写, 即整理思路, 总结经验, 也给别人个参考. 利己利人, 共同进步."

by Fango (noreply@blogger.com) at February 09, 2012 04:26 AM

Google App Engine with Go [2]

上篇我们和"给够"打了招呼. 一回生, 二回熟, 这次我们再看一个 SDK 的 demo, 主要针对对'给够'感兴趣, 还没接触 Go 的, 但有 C/C++, Java/Javascript 等 C 类语言基础的同学, 能对 Go 大体有个了解, 进而激发深入的情趣. 其实, Go 很简单, 简单到一夜 html 就能把最真实的全部, 完整细致的规范出来.

上篇 go-helloworld 的 package 叫 counter, 可能是此处 go-counter 的笔误:

package counter

import (
    "fmt"
    "http"
    "io"
    "os"
    "strconv"

    "appengine"
    "appengine/memcache"
)

我们看到 Go 要求列出所有引用的包, 哪怕, 比如, 如果你查找 os, 只有一处提到 os, 是 os.Error, 是 Go 中习惯使用的错误处理类型. 所谓"习惯", idiom, 在 Go 中有很大的分量. Go 的标准库是 open source 的, 是鼓励大家去学习, 去体会, 去习惯 Go 语言的各种使用方法的. 如果大家都默契的使用同一种约定俗成的 idiomatic use, 便可以更容易的架构和维护很大的项目.


func serveError(c appengine.Context, w http.ResponseWriter, err os.Error) {
    w.WriteHeader(http.StatusInternalServerError)
    w.Header().Set("Content-Type", "text/plain")
    io.WriteString(w, "Internal Server Error")
    c.Logf("%v", err)
}

和 C 类的其它语言不同, Go 的变量类型放在名后, 例如 err 是 os.Error 类型. 目的是使复杂的类型更容易理解. 函数由 func 定义, 此处的 serveError 函数, 使用 w 提供的函数, 和 io 包的函数, 在 http 缓冲区写入标准的出错返回. 同时, c, 作为 appengine 的 Context 类型, 提供一个 Logf 函数, 类似 printf, 打印记录 err. 

w 提供 http 回应缓存界面. 界面 - interface, 是 Go 的一个发明, 规定其类型必须实现此界面定义的那些函数. 例如, ResponseWriter 界面类型, 就定义了 Header, Write 和 WriteHeader 三个函数. 

func handle(w http.ResponseWriter, r *http.Request) {

"给够"的 URL 服务函数, r 指针指向 http 请求. Go 和 C 一样,  使用 & 取内存地址,  使用 * 作为内存地址指针, 但没有指针操作, 即不存在 *p++ 这种用法. 目的是把程序员从内存管理中解放出来, 交由 GC 处理, 同时, 也允许, 并鼓励程序员明确的使用内存, 从而在安全方便和时空效率两方便取得平衡. 多说几句, 在 Go 之前, 我挣扎着用过 Erlang, 其不可思议的 OTP (one time programmable) 变量, 据说从根本上避免 race condition, 但大量 GC 之低效, 大量无中生有的创造新变量名, 加上其古怪的模式匹配和 tail recursion, 让我如同被钓起的鱼, 窒息中体味针扎般死亡的恐惧. 

    c := appengine.NewContext(r)
    n := 0
    item, err := memcache.Get(c, r.URL.Path)

Go 的赋值和变量类型声明可以放在一起, 由 := 完成, 编译器会从赋值推导出对应变量的类型. 例如, c 是 App Engine 的(新的)上下文类型. n 是整数型, 其值为0. item 和 err 同时得到 Get 返回值, 及其类型. 多重赋值也是 Go 的一个新颖之处, 例如 a, b = b, a 可交换 a 和 b 的值.

    if err == memcache.ErrCacheMiss { 
     // Not found, new item  
    } else if err != nil { 
     //  Error
        serveError(c, w, err)
        return
    } else { 
     // Got
     n, err = strconv.Atoi(string(item.Value))
     if err != nil {
     serveError(c, w, err)
     return
     }
    } 

此处我故意对原文做了修改, 以突出三种可能的 err 及其分支处理. 这又是一个习惯, 明确全部逻辑分支, 并尽早出错返回. 
        
    n++
    item = &memcache.Item{
        Key:   r.URL.Path,
        Value: []byte(strconv.Itoa(n)),
    }

Item 是 memcache 包里定义的一个 struct, 除了 Key 和 Value 在此处赋值之外, 还有 Object, Flags 和 Expiration 三个项, 没有在 {} 里赋值, 所以都默认为 0. {} 这种赋值格式称为 literal, & 取地址, 以符合下面 Set 指针 item 的要求.

    err = memcache.Set(c, item)
    if err != nil {
        serveError(c, w, err)
        return
    }

    w.Header().Set("Content-Type", "text/plain")
    fmt.Fprintf(w, "%q has been visited %d times", r.URL.Path, n)
}

如果有错, 交由 serveError 返回标准出错信息. 否则, 如果 Get 没有找到对应的 URL, n 是 0. 然后访问次数加一, Set 回 memchache 的对应 URL 项, 由 http (即 w) 完成显示.

新上手的同学, 可以到 golang.org 查看大量的文档. 中文部分, 可以参考 golang-china.org, 以及笔者翻译的入门指导, 效率手册和部分的语言规范. 还有一个出于好玩写的 Go 编程小说, 可以无聊时读读.  

by Fango (noreply@blogger.com) at February 09, 2012 04:26 AM

Google App Engine with Go [3]

'给够'三部曲: "一顾钟情", "再顾倾城", 现在我们来"三顾", 请高人出世.

我们温习一下 Andrew 和 Rob 在 Google IO 演示的 moustach-io 的 http.go, 以此了解一个貌似实用的 App Engine 程序, 是怎样使用 Go 的高级知识的. 当然, 我们还是用 dev_appserver 来冒充真正的云运算.

import (
    "bytes"
    "fmt"
    "http"
    "image"
    "image/jpeg"
    _ "image/png" // import so we can read PNG files.

此例中的图像压缩使用 JPEG 的函数, 所以引入 image/jpeg 包. image.Decode 图像解压(读取)也可以使用 PNG 格式. 但由于 Go 不允许引入没用到其函数的包, 例如, 此程序没有 png 的函数. 所以, 用 _ 空白标识符来引入 image/png 包, 目的是为了使用其 init 函数注册 decode 用的 PNG 格式.

    "io"
    "json"
    "os"
    "strconv"
    "template"
    "goauth2.googlecode.com/hg/oauth"
)

goauth2 和 freetype (在 draw.go中 ) 是独立于'给够' SDK 外的第三方的库, 参考 README 用 hg clone 安装, 以便能编译到 _go_app 可执行代码中.

import (
    "appengine"
    "appengine/datastore"
    "appengine/urlfetch"
    "crypto/sha1"
    "resize"
)

const (
    CLIENT_ID     = "Your Client ID here."
    CLIENT_SECRET = "Your Client Secret here."
)

var (
    uploadTemplate = template.MustParseFile("upload.html", nil)
    editTemplate   *template.Template // set up in init()
    postTemplate   = template.MustParseFile("post.html", nil)
    errorTemplate  = template.MustParseFile("error.html", nil)
)

常量 const 和变量 var 声明也可以使用类似 import 的格式, 并可多次出现. 
template 是 Go 的一个标准包, 匹配文件或字串中定义的模式变量, 用真正变量的值替换. 

func init() {
    http.HandleFunc("/", errorHandler(upload))
    http.HandleFunc("/edit", errorHandler(edit))
    http.HandleFunc("/img", errorHandler(img))
    http.HandleFunc("/share", errorHandler(share))
    http.HandleFunc("/post", errorHandler(post))
    editTemplate = template.New(nil)
    editTemplate.SetDelims("{{{", "}}}")
    if err := editTemplate.ParseFile("edit.html"); err != nil {
        panic("can't parse edit.html: " + err.String())
    }
}

我们程序的入口, 注册 URL 路径的处理函数, 模式变量的分隔符设定为三个{}, 因为默认的{}和 Javascript 起冲突. errorHandler 很有趣, 我们先来和 check 一起看一下.

func errorHandler(fn http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        defer func() {
            if err, ok := recover().(os.Error); ok {
                w.WriteHeader(http.StatusInternalServerError)
                errorTemplate.Execute(w, err)
            }
        }()
        fn(w, r)
    }
}

// check aborts the current execution if err is non-nil.
func check(err os.Error) {
    if err != nil {
        panic(err)
    }
}

panic, defer 和 recover 是 Go 的崭新的异常处理方式. 可以这样看: 当 check 的 err 非空时, panic, 导致 check 及其调用栈的所有函数 (例如 upload 和 errorHandler) 立即退出. 但 errorHandler 定义了 defer, 会在退出前执行, 而其定义了 recover, 会拿到 panic 的变量, 即 err, 使用 type assertion 肯定它是 os.Error 类型, 并结束 panic 导致的退出, 从而在此处完成 panic 引起的异常, 用 errorTemplate 的模版在浏览器显示出错信息. 如果没有 panic, 或 panic 传入的不是 os.Error 类型, defer 没有动作.

另外, 注意到没有? errorHandler 接受一个函数, 包装 defer 后, 返回一个无名函数. Go 的函数可以像普通变量一样使用, 还可以使用 closure, 等一下会看到.

type Image struct {
    Data []byte
}

定义 Image 结构, 其 Data 项是 byte slice, 字节切片, 能方便安全的完成类似 C 的指针操作, 因为, slice 其实就是个指针指向某块内存, 但同时记录目前的长度 len, 供读写, 还有容量 cap, 供编译器地址越界检查. 

func upload(w http.ResponseWriter, r *http.Request) {
    if r.Method != "POST" {
        // No upload; show the upload form.
        uploadTemplate.Execute(w, nil)
        return
    }

    f, _, err := r.FormFile("image")
    check(err)
    defer f.Close()

defer 是在函数 (upload) 退出时执行的, 紧跟着打开文件写, 以防忘记关闭. 并且每个 err 都用 check 异常处理. 

    var buf bytes.Buffer
    io.Copy(&buf, f)
    i, _, err := image.Decode(&buf)
    check(err)

bytes.Buffer 能自动管理字节内存, io.Copy 可以最高效的从文件 f 拷贝内存到 buf 的地址. image.Decode 能分析图像格式, 并自动用 jpeg 或 png 包的 Decode 函数解压. 

    const max = 1200
    if b := i.Bounds(); b.Dx() > max || b.Dy() > max {

if 语句可以有初始赋值子句. 此处的变量 b 只在 if 后的 {} 块里有效, 即其作用域由 {} 限定.

        if b.Dx() > 2*max || b.Dy() > 2*max {
            w, h := max, max
            if b.Dx() > b.Dy() {
                h = b.Dy() * h / b.Dx()
            } else {
                w = b.Dx() * w / b.Dy()
            }
            i = resize.Resample(i, i.Bounds(), w, h)
            b = i.Bounds()
        }
        w, h := max/2, max/2
        if b.Dx() > b.Dy() {
            h = b.Dy() * h / b.Dx()
        } else {
            w = b.Dx() * w / b.Dy()
        }
        i = resize.Resize(i, i.Bounds(), w, h)
    }

由于变量的局部作用域, 变量名可以很短, 而不用担心会和作用域外的同名变量起冲突.

    // Encode as a new JPEG image.
    buf.Reset()
    err = jpeg.Encode(&buf, i, nil)
    check(err)

    // Create an App Engine context for the client's request.
    c := appengine.NewContext(r)

    // Save the image under a unique key, a hash of the image.
    key := datastore.NewKey("Image", keyOf(buf.Bytes()), 0, nil)
    _, err = datastore.Put(c, key, &Image{buf.Bytes()})
    check(err)

    // Redirect to /edit using the key.
    http.Redirect(w, r, "/edit?id="+key.StringID(), http.StatusFound)
}

用 r 的 FromFile 从浏览器上传的图像, 解压检查, 重新采样改变大小, 再压缩回 JPEG 格式, 放入 App Engine 的 datastore, 再让浏览器重定向到 edit 编辑页面, 添加大胡子. 

func edit(w http.ResponseWriter, r *http.Request) {
    editTemplate.Execute(w, r.FormValue("id"))
}

由 init() 中指定处理 URL /edit 的请求, 简单的执行对应的模版. 

func keyOf(data []byte) string {
    sha := sha1.New()
    sha.Write(data)
    return fmt.Sprintf("%x", string(sha.Sum())[0:8])
}

由 sha1 得到对应数据的唯一指纹, 注意看其 API 是多么的简单, 一写一读即告完成. 

func img(w http.ResponseWriter, r *http.Request) {
    c := appengine.NewContext(r)
    key := datastore.NewKey("Image", r.FormValue("id"), 0, nil)
    im := new(Image)
    err := datastore.Get(c, key, im)
    check(err)

    m, _, err := image.Decode(bytes.NewBuffer(im.Data))
    check(err)

    get := func(n string) int { // helper closure
        i, _ := strconv.Atoi(r.FormValue(n))
        return i
    }
    x, y, s, d := get("x"), get("y"), get("s"), get("d")

这里用到了 closure. get 是只限此处使用的函数, 其内部的 r 从外包的函数传入 (闭包), n 和 i 是正常的参数和返回值. 

    if x > 0 { // only draw if coordinates provided
        m = moustache(m, x, y, s, d)
    }

moustache 在 draw.go 中定义, 也使用 package moustachio, 编译器会把他们一起编译. 

    w.Header().Set("Content-type", "image/jpeg")
    jpeg.Encode(w, m, nil)
}

如此简单的把 jpeg 图像传回浏览器. 

func share(w http.ResponseWriter, r *http.Request) {
    url := config(r.Host).AuthCodeURL(r.URL.RawQuery)
    http.Redirect(w, r, url, http.StatusFound)
}

使用 OAuth 签证用户, 在 dev_appserver 不可用, 和其后的 post 及 postPhoto 一起, 此处就不深入了 . 

这样, 我们分三步学习了 Go 在 Google App Engine 的使用. 读过的会忘记, 写过的会留下些什么, 但只有做过错过改过的才会刻骨铭心. 为了大家不错过这个推广 Go 的好时机, 特作此文, 希望大家多多推介, 让笔者最钟爱的编程语言, 能迅速的普及开. 谢谢.




by Fango (noreply@blogger.com) at February 09, 2012 04:25 AM

February 07, 2012

research!rsc

go blog()

Let my start by apologizing for the noisy duplicate posts. I know that people using RSS software to read this blog got a whole bunch of old posts shown as new yesterday, and the same thing happened again just now. I made some mistakes while moving the blog from one platform to another, which caused the first burp, and then I had to fix the mistakes, which caused the second burp. But it's done, and there won't be another batch of duplicates waiting for you tomorrow.

I've moved this blog off of Blogger onto App Engine, running on a custom app written in Go. The down side is that I had to implement functionality that Blogger used to handle for me, like generating the RSS feed, and that's both extra work and a chance to make mistakes, which I took full advantage of. The up side, however, is that it makes it significantly easier for me to automate the writing and publishing of posts, and to create posts with a computational aspect to the content. I'll be blogging in the coming months about both the new setup, which has some interesting technical aspects behind it (I can edit live posts in a real text editor, for one thing), and about other topics that can make use of the computation.

For now, though, it's just the same content on a new server. Enjoy.

February 07, 2012 05:00 AM

February 05, 2012

Adam Langley

Revocation checking and Chrome's CRL

When a browser connects to an HTTPS site it receives signed certificates which allow it to verify that it's really connecting to the domain that it should be connecting to. In those certificates are pointers to services, run by the Certificate Authorities (CAs) that issued the certificate, that allow the browser to get up-to-date information.

All the major desktop browsers will contact those services to inquire whether the certificate has been revoked. There are two protocols/formats involved: OCSP and CRL, although the differences aren't relevant here. I mention them only so that readers can recognise the terms in other discussions.

The problem with these checks, that we call online revocation checks, is that the browser can't be sure that it can reach the CA's servers. There are lots of cases where it's not possible: captive portals are one. A captive portal frequently requires you to sign in on an HTTPS site, but blocks traffic to all other sites, including the CA's OCSP servers.

If browsers were to insist on talking to the CA before accepting a certificate, all these cases would stop working. There's also the concern that the CA may experience downtime and it's bad engineering practice to build in single points of failure.

Therefore online revocation checks which result in a network error are effectively ignored (this is called “soft-fail”). I've previously documented the resulting behaviour of several browsers.

But an attacker who can intercept HTTPS connections can also make online revocation checks appear to fail and so bypass the revocation checks! In cases where the attacker can only intercept a subset of a victim's traffic (i.e. the SSL traffic but not the revocation checks), the attacker is likely to be a backbone provider capable of DNS or BGP poisoning to block the revocation checks too.

If the attacker is close to the server then online revocation checks can be effective, but an attacker close to the server can get certificates issued from many CAs and deploy different certificates as needed. In short, even revocation checks don't stop this from being a real mess.

So soft-fail revocation checks are like a seat-belt that snaps when you crash. Even though it works 99% of the time, it's worthless because it only works when you don't need it.

While the benefits of online revocation checking are hard to find, the costs are clear: online revocation checks are slow and compromise privacy. The median time for a successful OCSP check is ~300ms and the mean is nearly a second. This delays page loading and discourages sites from using HTTPS. They are also a privacy concern because the CA learns the IP address of users and which sites they're visiting.

On this basis, we're currently planning on disabling online revocation checks in a future version of Chrome. (There is a class of higher-security certificate, called an EV certificate, where we haven't made a decision about what to do yet.)

Pushing a revocation list

Our current method of revoking certificates in response to major incidents is to push a software update. Microsoft, Opera and Firefox also push software updates for serious incidents rather than rely on online revocation checks. But our software updates require that users restart their browser before they take effect, so we would like a lighter weight method of revoking certificates.

So Chrome will start to reuse its existing update mechanism to maintain a list of revoked certificates, as first proposed to the CA/Browser Forum by Chris Bailey and Kirk Hall of AffirmTrust last April. This list can take effect without having to restart the browser.

An attacker can still block updates, but they have to be able to maintain the block constantly, from the time of revocation, to prevent the update. This is much harder than blocking an online revocation check, where the attacker only has to block the checks during the attack.

Since we're pushing a list of revoked certificates anyway, we would like to invite CAs to contribute their revoked certificates (CRLs) to the list. We have to be mindful of size, but the vast majority of revocations happen for purely administrative reasons and can be excluded. So, if we can get the details of the more important revocations, we can improve user security. Our criteria for including revocations are:

  1. The CRL must be crawlable: we must be able to fetch it over HTTP and robots.txt must not exclude GoogleBot.
  2. The CRL must be valid by RFC 5280 and none of the serial numbers may be negative.
  3. CRLs that cover EV certificates are taken in preference, while still considering point (4).
  4. CRLs that include revocation reasons can be filtered to take less space and are preferred.

For the curious, there is a tool for fetching and parsing Chrome's list of revoked certificates at https://github.com/agl/crlset-tools.

February 05, 2012 08:00 AM

February 03, 2012

RSC

_rsc: https://t.co/iRXEwiWm @goroutine @app_engine @go_nuts #golang

_rsc: https://t.co/iRXEwiWm @goroutine @app_engine @go_nuts #golang

February 03, 2012 05:11 PM

January 30, 2012

Adam Langley

Extracting Mozilla's Root Certificates

When people need a list of root certificates, they often turn to Mozilla's. However, Mozilla doesn't produce a nice list of PEM encoded certificates. Rather, they keep them in a form which is convenient for NSS to build from: https://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1.

Several people have written quick scripts to try and convert this into PEM format, but they often miss something critical: some certificates are explicitly distrusted. These include the DigiNotar certificates and the misissued COMODO certificates. If you don't parse the trust records from the NSS data file, then you end up trusting these too! There's at least one, major example of this that I know of.

(Even with a correct root file, unless you do hard fail revocation checking you're still vulnerable to the misissued COMODO certificates.)

So, at the prodding of Denton Gentry, I've open-sourced a tool for converting NSS's file to PEM format: extract-nss-root-certs. (At the time of writing it requires a 6g built from the weekly or current tree (hg -r weekly), not the release tree. A few of the APIs have changed since the last Go release was done. This will be resolved when Go 1.0 is released.)

January 30, 2012 08:00 AM

January 29, 2012

codegrunt.co.uk

The Wisdom of Fearless Stupidity

A problem I’ve had for a long while has been the fear of looking stupid. It’s held back projects, study, blog posts (you can see this from the sparseness of this blog), and more generally things I’ve wanted to do which risk looking stupid - translated: worthwhile things.

Ironically this fear has often been self-fulfilling as I’ve ran through the familiar cycle of publicly promising to do something → fearing looking stupid since this thing is tough and I’ve hit up on a brick wall → engaging in endless procrastination → end up looking stupid for not having made progress on said thing.

This is all highly applicable to programming. Computers are so ridiculously complicated that there will always be something to defeat you, the field so wide that there will always be something you don’t know about, or even if you do know something relatively deeply there is always something (actually many things) which will crop up to surprise you (C sharpies should read Eric Lippert’s blog to bring this point home).

A curious aspect of our craft is how quickly you can find yourself in a situation where your particular problem is a unique enough combination of factors for you to be out there on your own at least in some regard or another. That is enough to make the most hardened, experienced developer insecure and is yet another factor in my own battle with the stupid.

Another consequence of this fear is that, since it’s really impossible to improve at something without questioning whether you have the best approach to the problem at hand (and thus risking looking stupid for having got something wrong), you end up less great than you could potentially be.

In terms of programming this fear stands in the way of better code. Without considering whether your code might be suboptimal (and therefore you possibly looking stupid), you end up almost definitely ensuring your code will be suboptimal. This is not unconnected to the only valid measure of code quality.

Clearly a big factor in all of this is pride, especially when you consider future employability, and especially when you have a name which is globally unique over the whole of the internet (the intersection of people with forename of Lorenzo and people with surname of Stoakes, rather than the more common Stokes, is small).

Fuck pride. Fuck not doing things you want to do because you might end up looking stupid, fuck getting stuck on a problem and not bringing the awesome power of crowdsourcing to bear on it.

Expect some stupidity going forward, but also intelligence as I work hard on fixing my stupidity, little-by-little. Sucking a little less each year.

January 29, 2012 12:00 AM

January 28, 2012

Miek Gieben

DNS Fingerprinting

Announcing FP

The tool for DNS fingerprinting is fpdns, which is Perl based. In recent times development seems to have picked up, but a little competition never hurt anyone, so I wrote fp in Go. Fp is also a fingerprint program for DNS servers. Its aim is to be more readable then fpdns is (was?). And make it more easy to add new server types.

Help needed!

Do you have some old(er) nameserver laying around that can be queried? Does your (sick) mind know of a few extra evil queries that can be sent to nameservers? If so, please contact me: query@evilquery.nl. I want to get to a point where fp sends about 10 queries that can be used to identify a server.

Fingerprint

A fingerprint in fp looks like this:

.,CH,TXT,QUERY,NOERROR,qr,aa,tc,RD,ra,ad,cd,z,1,0,0,0,DO,4097,NSID

It has 20 fields, which are:

  1. Domain name, . in this example;
  2. Class, CH here;
  3. Type, TXT here;
  4. Opcode, QUERY;
  5. Rcode, NOERROR;
  6. Query response, qr, lowercase means false (not set), uppercase means true;
  7. Authoritative, aa, lowercase. Thus not set here;
  8. Truncated, tc, not set;
  9. Recursion Desired, RD, uppercase, thus set;
  10. Recursion Available, ra;
  11. Authenticated Data, ad;
  12. Checking Disabled, cd;
  13. Zero, z;
  14. Question section length, 1 here;
  15. Answer section length, 0;
  16. Authoritative section length, 0;
  17. Additional section length, 0;
  18. DNSSEC OK, DO (uppercase, thus set);
  19. UDP bufsize, set to 4097;
  20. NSID, uppercase: request NSID (or NSID was set).

These fingerprints are also used in creating the DNS queries that are send to nameserver(s) being tested.

A full nameserver fingerprint consists out of multiple of these fingerprints. Right now fp fires off 3 queries to test a server, so each nameserver fingerprint must also consist out of 3 fingerprints. The nameserver fingerprint of BIND9 looks like:

# BIND9 fingerprints
.,CH,TXT,QUERY,REFUSED,QR,aa,tc,RD,ra,ad,cd,z,1,0,0,1,DO,4096,NSID
auThoRs.bInD.,CH,TXT,QUERY,NOERROR,QR,AA,tc,rd,ra,ad,cd,z,1,15,1,0,do,0,nsid
bind.,NONE,SOA,NOTIFY,REFUSED,QR,aa,tc,RD,ra,ad,cd,z,1,0,0,0,do,0,nsid

When fp is extended with an extra fingerprint, this BIND9 fingerprint also needs to get an extra fingerprint.

Trying it yourself

As said, Currently fp only uses three queries, but this is expected to be increased in the near future. In the data directory, the file q holds the fingerprints of the queries to ask. Currently it looks like this:

# These are the queries that we ask the nameserver being identified
#
# The order is important, as the data files of the known nameservers are compared
# in this order.
.,CH,TXT,QUERY,NOERROR,qr,aa,tc,RD,ra,ad,cd,z,1,0,0,0,DO,4097,NSID
auThoRs.bInD.,CH,TXT,QUERY,NOERROR,qr,aa,tc,rd,ra,ad,cd,z,1,0,0,0,do,0,nsid
bind.,NONE,SOA,NOTIFY,NOERROR,qr,AA,tc,RD,ra,ad,cd,Z,1,0,0,0,do,0,nsid

A local run looks like this (this is abbreviated):

% ./fp @localhost
Server type     Diffs       Fingerprint         Recevied
Bind9   0 .,CH,TXT,QUERY,REFUSED,QR,aa,tc,RD,ra,ad,cd,z,1,0,0,1,DO,4096,NSID .,CH,TXT,QUERY,REFUSED,QR,aa,tc,RD,ra,ad,cd,z,1,0,0,1,DO,4096,NSID
Bind9   0 auThoRs.bInD.,CH,TXT,QUERY,NOERROR,QR,AA,tc,rd,ra,ad,cd,z,1,15,1,0,do,0,nsid auThoRs.bInD.,CH,TXT,QUERY,NOERROR,QR,AA,tc,rd,ra,ad,cd,z,1,15,1,0,do,0,nsid
Bind9   0 bind.,NONE,SOA,NOTIFY,REFUSED,QR,aa,tc,RD,ra,ad,cd,z,1,0,0,0,do,0,nsid bind.,NONE,SOA,NOTIFY,REFUSED,QR,aa,tc,RD,ra,ad,cd,z,1,0,0,0,do,0,nsid
        =
Differences:    0

Nsd3    2 .,CH,TXT,QUERY,NOERROR,QR,aa,tc,RD,ra,ad,cd,z,1,0,0,1,DO,4096,nsid .,CH,TXT,QUERY,REFUSED,QR,aa,tc,RD,ra,ad,cd,z,1,0,0,1,DO,4096,NSID
Nsd3    3 auThoRs.bInD.,CH,TXT,QUERY,NOERROR,QR,aa,tc,rd,ra,ad,cd,z,1,0,0,0,do,0,nsid auThoRs.bInD.,CH,TXT,QUERY,NOERROR,QR,AA,tc,rd,ra,ad,cd,z,1,15,1,0,do,0,nsid
Nsd3    6 .,CLASS0,TYPE0,NOTIFY,NXDOMAIN,QR,AA,tc,RD,ra,ad,cd,z,0,0,0,0,do,0,nsid bind.,NONE,SOA,NOTIFY,REFUSED,QR,aa,tc,RD,ra,ad,cd,z,1,0,0,0,do,0,nsid
            =
Differences:    11

What do you see here? On the left the nameserver type we're testing, then a number. This number represent the number of differences with the stored fingerprint for this server. When this number is zero, it means the reply from the unknown server is an exact match with one of the stored fingerprints. In general, the lower the number, the more exact the hit was. For bind9 in the example above, the accumulated number of differences is zero. This indicates the server is probably a BIND9 server.

For nsd3 the story is completely different. The accumulated number of differences is 11, so this server probably isn't a NSD3 server.

Report

With, -report fp will just show the fingerprint of a nameserver. If the server is positively identified, the finger print can be added to fp:

% ./fp -report @localhost
# Fingerprint of <Nameserver> <version>
# Supplied by <Name> on <Date>
#
.,CH,TXT,QUERY,REFUSED,QR,aa,tc,RD,ra,ad,cd,z,1,0,0,1,DO,4096,NSID
auThoRs.bInD.,CH,TXT,QUERY,NOERROR,QR,AA,tc,rd,ra,ad,cd,z,1,15,1,0,do,0,nsid
bind.,NONE,SOA,NOTIFY,REFUSED,QR,aa,tc,RD,ra,ad,cd,z,1,0,0,0,do,0,nsid

by Miek Gieben at January 28, 2012 03:03 PM

codegrunt.co.uk

Rulemotion

For those who didn’t know, I have quit my job at a hedge fund to work at a startup - Rulemotion (website under construction). Exciting! Scary! Awesome! All at the same time :-)

I don’t move until early March, at which I point I am sure I shall blog some more about what I’m getting up to there/what we are all about.

Already looking to be an interesting year, this!

January 28, 2012 12:00 AM

January 23, 2012

Miek Gieben

Super-short guide to getting q

Get the latest version (called weekly) of Go:

  1. Get Go: hg clone -u release https://go.googlecode.com/hg/ go Note the directory you have downloaded it to and set $GOROOT to it: export GOROOT=$PWD/go. Add the GOROOT bin directory to your path: PATH=$PATH:$GOROOT/bin

  2. Update Go to the latest weekly: cd $GOROOT; hg pull; hg update weekly

  3. Compile Go: cd $GOROOT/src ; ./all.bash

    Install missing commands (gcc, sed, bison, etc.) if needed.

The latest Go is now installed.

Install GoDNS

  1. Get GoDNS: cd ~; git clone git://github.com/miekg/godns.git
  2. Compile it: cd godns; make ; make install
  3. Compile the examples; cd examples; make ; make install
  4. Query with q: q mx miek.nl
  5. Report bugs

by Miek Gieben at January 23, 2012 05:07 PM

January 19, 2012

RSC

_rsc: Miss Code Search? https://t.co/5LLDCqVv

_rsc: Miss Code Search? https://t.co/5LLDCqVv

January 19, 2012 04:04 PM

research!rsc

Regular Expression Article #4

In January 2007 I posted an article on my web site titled “Regular Expression Matching Can Be Simple And Fast.” I intended this to be the first of three; the second would explain how to do submatching using automata, and the third would explain how to make a really fast DFA. These were inspired by my work on Google Code Search.

Today, the fourth article in my three-part series is available, accompanied by source code (as usual). This one describes how Code Search worked.

January 19, 2012 12:00 AM

January 15, 2012

Adam Langley

BEAST followup

(See the original post for background.)

Everyone seems to have settled on 1/n-1 record splitting as a workaround for the BEAST attack in TLS 1.0 and SSLv3. Briefly: 1/n-1 record splitting breaks CBC encrypted records in two: the first with only a single byte of application data and the second with the rest. This effectively randomises the IV and stops the attack.

The workaround which OpenSSL tried many years ago, and which hit significant issues, was 0/n record splitting. It's the same thing, but with the first record being empty. The problem with it was that many stacks processed the empty record and returned a 0-byte read, which higher levels took to mean EOF.

1/n-1 record splitting doesn't hit that problem, but it turns out that there's a fair amount of code out there that assumes that the entire HTTP request comes in a single read. The single byte record breaks that.

We first implemented 1/n-1 record splitting in Chrome 15 but backed off after only a couple of days because logging into several large sites broke. But that did motivate the sites to fix things so that we could switch it on in Chrome 16 and it stuck that time.

Opera also implemented it around this time, but I think Chrome took the brunt of the bug reports and it's time consuming dealing with them. Myself and a colleague have been emailing and phoning a lot of sites and vendors while dealing with upset users and site admins. Chrome certainly paid a price for moving before Firefox and IE but then we're nice like that.

Thankfully, this week, Microsoft released a security update which implements 1/n-1 record splitting in SChannel and switches it on in IE. (Although it defaults to off for other users of SChannel, unlike NSS.) Now the sites which broke with Chrome 16 are also broken in a patched IE and that takes some pressure off us. In a few weeks, Firefox 10 should be released and then we'll be about as good as we're going to get.

After taking the brunt with Chrome 16, there is one case that I'm not going to fight: Plesk can't handle POST payloads that don't come in a single read. Chrome (currently) sends POSTs as two writes: one for the HTTP headers and a second for the POST body. That means that each write is split into two records and Plesk breaks because of the second split. IE and Firefox send the headers and body in a single write, so there's only a single split in the HTTP headers, which Plesk handles.

Chrome will start merging small POST bodies into the headers with Chrome 17 (hopefully) and this will fix Plesk. Also, merging as Firefox and IE do saves an extra packet so it's worthwhile on its own. Once again, anything that's mostly true soon becomes an unwritten rule on the Internet.

It's worth contrasting the BEAST response to the renegotiation attack. The BEAST workaround caused a number of problems, but it worked fine for the vast majority of sites. The renegotiation fix requires that very nearly every HTTPS site on the Internet be updated and then that browsers refuse to talk to unpatched servers.

I'd bet that we'll not manage to get enough patched servers for any browser to require it this side of 2020. Unpatched servers can still disable renegotiation to protect themselves, but it's still not hard to find major sites that allow insecure renegotiation (www.chase.com was literally the second site that I tried).

January 15, 2012 08:00 AM

January 14, 2012

Adam Langley

OTR in Go

“Off the record” is, unfortunately, an overloaded term. To many it's feature in gTalk and AOL IM which indicates that the conversation isn't logged. However, to crypto folks it's a protocol for secure chat.

(In fact, resoloving the ambiguity is on the EFF's wish list.)

Pidgin has been my chat client of choice for some time because it's pretty fully featured and supports OTR via a plugin. However, I just don't trust it from a security point of view. The latest incident was only a couple of weeks ago: CVE-2011-3919.

So, I implemented otr in Go, as well as an XMPP library and client. It's an absolutely minimal client (except for OTR support) and implements only what I absolutely need in a client.

But it does mean that the whole stack, including the TLS library, is implemented in a memory safe language. (On the other hand, pretty much everything in that stack, from the modexp function to the terminal handling code was written by me and has never really been audited. I'm a decent programmer but I'm sure there are some howlers of security issues in there somewhere.)

January 14, 2012 08:00 AM

January 11, 2012

Kyle Lemons

Quote: Gentleness and Strength

“Nothing is so strong as gentleness, nothing so gentle as real strength”
- St. Francis de Sales

by Kyle Lemons at January 11, 2012 10:16 PM

January 06, 2012

Kyle Lemons

Go: A New Language for a New Year

Go Gopher Logo

Go Gopher

<style>p{text-indent:1em}</style>

As 2011 makes its way out and 2012 takes its place, it’s time for a bit of reflection and a bit of looking forward. I haven’t been writing software professionally for particularly long, but I have written software in a number of languages (everything from Pascal to Python), and I think we can all agree that none of the usual suspects are particularly ideal. If you’re like me, you hunker down with your favorite set of language features and write your code in as much isolation as possible, so that you can work around or ignore whatever problems your language and/or environment cause you. You probably have some tools lying around to help you do various things for which the language or your editor/environment aren’t well-equipped. You probably don’t even realize all of the things that bother you about the language after awhile, because it’s the norm: every programmer has to deal with them, it just comes with the territory. Please note: I will be comparing Go to other languages extensively in this blog post; do not take it to be an indictment of them or even, really, as reasons to not use them. I’m simply giving my opinion on their differences and why I personally find that Go is a more suitable language for my development. I have used all of the languages that I discuss and will continue to use them when their particular strengths are required.

Let’s start with Python. I loved my time writing Python, because I felt like I could be really productive. I created a library that my team and I could use to replace huge pieces of boilerplate with a few lines of very terse but legible code. I used just about every new, shiny feature of Python on which I could get my grubby little hands: I used context objects, generators, fancy inheritance and especially I abused the data model in ways that now make me cringe. My code was a pleasure to read and even more of a pleasure to write. It got the job done with a really small amount of code, and my team and managers loved me for how productive I was and how productive I was making my team. What I knew somewhere in the back of my mind but didn’t tell anyone was how horribly painful it was to debug the code written this way. My code reviewers were able to read the code and admit that it looked right, see that the test cases were comprehensive enough and verify that I was covering all of the requirements, but I doubt that they had any idea what was really going on behind-the-scenes or how brittle some of the libraries could be. Since I had written one of the libraries myself and knew most of the nuances of the Python features employed, I was able to debug problems with the library (or my use of it) with relative ease. Unfortunately, it often meant tracing through many layers and scrutinizing pieces of code with a fine-toothed comb to find all of the places where Python was secretly calling (or not calling) out to other pieces of code. Often, it was simply a matter of hiding yet another __special__ function to an object to handle a new use case (for those of you familiar with C++ and the Rule of 3, there needs to be a Python Rule of 17 or something…) that wasn’t already covered. The rest of the team pretty much just used my example code as a template and never ran into these issues, but if they’re still using this particular library I really hope that it’s not causing them more problems than it solved. I’m not even going to get into the various issues that flimsy duck-typing and non-static typing can cause, often a long time after the offending code is written… What remains clear to me is that Python (and langauges like it) are not suitable for large-scale development without very strict adherence to a style guide which precludes almost all of what I described above, and to me that would just take all of the fun out of it.

That, however, is Python, and is the price you expect to pay for such a dynamic language. Even lower-level languages like C and Pascal have their issues. Don’t get me wrong, I absolutely love C and feel like I am a deus intra machinam whenever I write it; I still think it’s the first programming language that a student should learn, and that they shouldn’t be able to move to a higher- or lower-level language until they’ve mastered it. The problem with these languages, especially C, is that you have to take such care when writing and reviewing any significant amount of code that verifying that the code is correct, robust, and has no memory leaks is the next closest thing to impossible. The boilerplate and the bookkeeping that have to be done before you even get to the meat of your application or algorithm are tedious and error-prone in the worst way. There are certainly situations in which such lower-level languages are the only language that can solve your problem, whether it be for performance, real-time/deterministic execution or bare metal proximity reasons, but they just aren’t the most suitable languages for large-scale development.

I’ve also done a bit of graphical (read: drag-and-drop, flow chart) programming, which is interesting to say the least. I won’t go into much detail here, except to say that from my limited exposure, it seems best suited as a special-purpose tool for small- to medium-scale logic at best, and should probably not be used when there are more than a few developers on a particular piece of “code.” It’s fun at first, but the limitations show up fast, and after awhile it seems more tedious, repetitive, and limiting than anything else.

Go Gopher Understudy from Squishable

Go even has an adorable mascot

Enter Go. It is a new programming language by pretty much any definition, despite having been in development at Google since 2007 and as an open source project since 2009. It’s a compiled, statically typed, garbage collected language with some cool primitives for concurrency. Despite being compiled and statically typed, it has a very dynamic feel. The syntax has some concise shortcuts to minimize repetition and variable typing. The presence of closures, a garbage collector, and a fairly expansive standard library also contribute to its dynamic feel. These things, coupled with the clarity and explicit nature of Go source code, all help make Go one of the best general purpose languages that I have ever used. I won’t be providing code directly (this blog post is long enough already), but many of the links I provide will be to the documentation or to the relevant portions of the Go Tour, where you can play with the features yourself.

We look forward to the first long-term stable release of the Go standard library and compilers sometime early this year: Go version 1. I’ve been convinced for awhile now that Go is a production-ready language, but in my mind this piece is really the last thing left barring wider adoption. There are some exciting language changes leading up to this Go 1 release, and I am really excited to see what gets done after it is finished. To date, the fast pace at which Go has evolved (both the language and the standard libraries) has posed a challenge for third-party library maintainers, who often have to maintain both a “release” branch of their code and a “weekly” branch due to the rate at which the weekly branch progresses and the relatively high percentage of Go users who are doing their development at (or beyond) the “weekly” branch to take advantage of the new, shiny features or to get the latest bug fixes. With Go 1 this should change, and the number of libraries available to use with a single command (more on that later) will be able to grow even faster.

Why Go?

Compared to most languages in use today, Go was designed with many programmers, concurrent systems, and large-scale problems in mind. Some languages, like C, were simply not designed at a time where multicore and multiprocessor systems were in broad deployment. Some languages, like Python, weren’t originally intended to scale well onto multiple cores and have been slow to adopt strategies for utilizing such resources. Many languages to this day don’t have networking libraries which work predictably and have a clean, understandable API. Programs written in many languages, especially those with operator overloading, require in-depth knowledge of both the architecture of the program itself and the libraries in use in order to be able to understand the code well. Go attempts to address all of these problems and more; in my opinion, it does so brilliantly.

Two of the first things you will hear most people talk about when you hear about Go are channels and goroutines. They’re certainly two of the “shiniest” features of the language, and are the reasons why I tried out Go back in late 2009. They’re far from the biggest reasons why I think you should try Go, but they’re as good a place as any to start.

Channels and Goroutines

These two features are inspired by Hoare’s Communicating Sequential Processes (CSP). A goroutine (similar to a coroutine) is a function that runs independently of the calling function. They’re similar to threads in that a scheduler manages which ones are running at any given time, but they are much lighter-weight than their operating system counterparts. In fact, a Go application with many thousands of goroutines can run comfortably on a single operating system thread.

Channels are a data type in Go which allows for simple, clear communication between goroutines. They are first-class values that have a data type associated with them. Any value of the associated type can be sent over the channel and then received from the channel, usually by another goroutine. They can be passed into functions and goroutines, stored in objects, even sent through other channels.

In most programming languages, when you have multiple threads that need to share data or communicate, you arrange to do so via the use of mutual exclusion locks (mutexes). At first glance, it seems simple: before you access the data you lock it, and when you’re done you unlock it. It gets more complicated very quickly, of course. In Go, a mutex (while available) is not the preferred solution to most problems. As stated in Effective Go, the slogan has become:
Do not communicate by sharing memory; instead, share memory by communicating.Thus instead of using a mutex to protect a shared, global object, you either pass the object around (changing ownership as you do) or you maintain a single owner and all other goroutines access the object by sending requests to that goroutine.

Using these two tools, it turns out to be quite easy to implement solutions to a problem that make logical sense and that very closely reflect the way we might solve the problem in our head. Small, focused pieces of code are concerned with specific aspects of the solution, and are either given their input via the usual way (function parameters) or continually from channels (they also have the same alternatives available for their output). Ownership of data is clear, communication is explicit, the code is highly legible. Such designs are also often easy to unit test; simulating the input and verifying the output via channels is straightforward and very common.

Closures and Deferred Functions

One of the many features of Go that makes it have a very dynamic feel are closures. Like lambdas in python or blocks in ruby, a function can be declared as a local variable or even passed as a literal to a function. All local variables in scope at the closure declaration are also in scope within the closure. They’re powerful tools for functional-style APIs and can be a really fun alternative to (or improvement upon) callbacks. They are also commonly executed directly as a goroutine.

In addition to the “go” directive that runs a function in its own goroutine, Go also has a “defer” directive. When a function (or closure) call is preceded by the “defer,”, the call is evaluated but not executed until just before the function returns. Multiple deferred calls will be executed in reverse order. This turns out to be a very powerful tool for using any object or API which requires cleanup: as soon as you create it or lock it, you can defer the cleanup or unlock. This makes it very easy to spot when you forgot to close a file descriptor or (should you find yourself using one) unlocking a mutex.

These two features provide the ability to confine relevant code all in the same place, which in turn makes reading, debugging, and maintaining the code easier. This is a common theme, and I think was at or near the top of the Go designers’ priority list when designing the language. The concepts are simple, orthogonal, and flexible without sacrificing readability, debuggability, or maintainability.

Interfaces

Interfaces in Go are a welcome twist on a familiar concept. Typically, in a language like Java, interfaces must be explicitly declared by any implementing class. This, of course, means that adding a new interface requires modifying (and having access to modify) all classes that you plan to use in values of that interface type. The paradigm in Go is reversed: instead of defining an interface and declaring all of the objects that satisfy it, the interface is defined and any object which could satisfy the interface can implicitly be used as a value of the interface. This also provides a useful tool, the empty interface, which acts as a container for any possible value (similar to Java’s Object, from which all classes are derived) because all values satisfy it.

In contrast to interfaces in other languages (for instance, in Java), Go interfaces are often very small, and contain one or just a few methods. Because of the presence of such small interfaces in the standard library, they have naturally given rise to some common, idiomatic function names and signatures. Possibly the best examples of these from the standard library are the io.Reader and io.Writer interfaces. Because of the prevalence of objects which implement these two interfaces, stringing together producers and consumers of a data stream is often reminiscent of a unix pipeline. It is simple, for instance, to open a file, unzip it, decrypt its contents, and stream it directly to an HTTP client because all of these interfaces satisfy or consume the above interfaces. Even Go’s version of the old favorite printf can write to any object which satisfies the io.Writer interface, which gives rise to the very concise web-based version of “Hello, World!” in Go.

Simplicity and Explicitness

Some of the best features of Go are, unlike those listed above, not something you’ll find listed in the specification. They probably stem from the guiding philosophy behind its design more than anything else. I think that the simplicity, orthogonality, and explicitness of the features of the Go language make it a prime candidate for a teaching language, especially at the middle- or high-school level.

First, the features of Go are simple and minimal. The entire language specification fits in 45 printed pages. By contrast, the C++ specification clocks in at 750 pages and Javascript has nearly 250. It is short enough that an average programmer can actually read it, understand it, and internalize it in its entirety. This turns out to be quite an asset in a large project setting with multiple developers, each of whom will have a slightly different coding style and may utilize a different different set of features. Being able to understand all of the language features in use, their nuances, and their side effects turns out to be easy in Go when it could be a nearly impossible task in many others.

Second, the features of Go are designed to be orthogonal to one another. When you understand two concepts independently, you understand them together. I have already given one example of this: deferred function calls. If you understand defer (e.g. that it doesn’t make the call immediately, that it evaluates arguments at the defer site, and that it is executed after any subsequent defer calls as the function returns) and you understand closures (that any local variables are in scope, etc), you already understand what happens if you defer a call to a function literal. Compare this to my Python anecdotes earlier, and you’ll find that this is not as ubiquitous a quality as you might expect. There are also a fair number of C++ and Java features that interact non-orthogonally and require some more in-depth understanding (hence the 750-page C++ specification).

Ease of Development

This one is more difficult to quantify. I have found, qualitatively, that writing Go is easier and more fun than pretty much any other language I have used to date. Dynamic languages like Python and Ruby are fun to learn and are fun languages with which to experiment, but I have found that the amount of time spent debugging them (especially when it’s somebody else’s code) takes almost all of the fun out of large project and multi-developer situations. By contrast, languages like C and C++ (and to a somewhat lesser extent, Java) are more painful to write up front but have well-established tools that make analyzing and debugging them a much more pleasant experience. Until I tried Go, I accepted this as the nature of the beast. You just had to to choose. With Go, however, I think the designers managed to strike a balance.

On the development side, I have found that it is easy to translate designs into code. As I mentioned previously, channels and goroutines make it easy to implement your design in pieces that all connect together and communicate. The lack of verbose syntaxes for declarations and the implicit nature of interfaces reduce the amount of arguably unnecessary up-front work. The simplicity of the type system lets you (or forces you to) focus on the implementation instead of fixating on design patterns or type hierarchies. The lack of certain features in the language like operator overloading, destructors, exceptions, and the like all force code to be explicit. An oft-quoted mailing list post by Andrew Gerrand states that “[in] Go, the code does exactly what it says on the page.” Error handling, function calls, math, map/slice access and inter-goroutine communication all look exactly like what they are. When examining a function in isolation, it is a relatively small feat to understand the side-effects of a given statement, which makes the debugging process much more pleasant than in some other languages in which the simplest statement like “a+b” could potentially have unlimited side effects.

Outside of the code itself, there are many benefits to the Go programming language. The standard library is very complete, cohesive, and easy to understand. The third party package ecosystem is nurtured by the Go team, and the standard distribution includes an application called “goinstall” (soon to be bundled into a “go” meta-command) by means of which a package hosted in any web-accessible Git, Mercurial, or Subversion repository can be installed (and any such dependencies, ad infinitum) with a single command. By default, such installations are anonymized and aggregated on a package dashboard, which shows the most- and most-recently installed packages as well as their build status as of the latest release. The standard distribution also includes a formatting tool called “gofmt” which knows how to format a piece of source code according to “Go style,” which reduces or eliminates the need for unproductive debating within a project about things like brace placement or whitespace around operators. There is also a tool called “gofix” which contains modules to automatically fix up any mechanical changes that have been made to the standard library or language between releases (for instance, changing function names, package imports or method signatures) where possible. The last of the tools that I will mention is “godoc,” which is similar to pydoc or javadoc. It uses the comments in the source to provide easily accessible documentation both on the command-line and from a web browser. All of these tools add up to make even the experience of development that doesn’t involve code production as easy as possible.

Summary

Go is an industrial-strength programming language for solving industrial-sized problems. There are many features that I haven’t even touched upon, like the fact that Go is now the third runtime on Google App Engine, which could probably fill another equally long blog post. If you read this far, I hope you at least take the time to take the Go tour or peruse the language specification. Keep an eye out for future projects or tools where you might be able to try out a new language. You may not like it, it may not be accepted in your place of work, or it may simply not be adequate for your needs, but I think that it has the potential to make significant waves in the software industry and I encourage everyone (even if you’ve never programmed before in your life) to give it a shot.

by Kyle Lemons at January 06, 2012 07:30 PM

January 01, 2012

Command Center

Esmerelda's Imagination

An actress acquaintance of mine—let's call her Esmerelda—once said, "I can't imagine being anything except an actress." To which the retort was given, "You can't be much of an actress then, can you?"

I was reminded of this exchange when someone said to me about Go, "I can't imagine programming in a language that doesn't have generics." My retort, unspoken this time, was, "You can't be much of a programmer, then, can you?"

This is not an essay about generics (which are a fine thing and may arrive in Go one day, or may not) but about imagination, or at least what passes for imagination among computer programmers: complaint. A friend observed that the definitive modern pastime is to complain on line. For the complainers, it's fun, for the recipients of the complaint it can be dispiriting. As a recipient, I am pushing back—by complaining, of course.

Not so long ago, a programmer was someone who programs, but that seems to be the last thing programmers do nowadays. Today, the definition of a programmer is someone who complains unless the problem being solved has already been solved and whose solution can be expressed in a single line of code. (From the point of view of a language designer, this reduces to a corollary of language success: every program must be reducible to single line of code or your language sucks. The lessons of APL have been lost.)

A different, more liberal definition might be that a programmer is someone who approaches every problem exactly the same way and complains about the tools if the approach is unsuccessful.

For the programmer population, the modern pastime demands that if one is required to program, or at least to think while programming, one blogs/tweets/rants instead. I have seen people write thousands of words of on-line vituperation that problem X requires a few extra keystrokes than it might otherwise, missing the irony that had they spent those words on programming, they could have solved the problem many times over with the saved keystrokes. But, of course, that would be programming.

Two years ago Go went public. This year, Dart was announced. Both came from Google but from different teams with different goals; they have little in common. Yet I was struck by a property of the criticisms of Dart in the first few days: by doing a global substitution of "Go" for "Dart", many of the early complaints about Go would have fit right into the stream of Dart invective. It was unnecessary to try Go or Dart before commenting publicly on them; in fact, it was important not to (for one thing, trying them would require programming). The criticisms were loud and vociferous but irrelevant because they weren't about the languages at all. They were just a standard reaction to something new, empty of meaning, the result of a modern programmer's need to complain about everything different. Complaints are infinitely recyclable. ("I can't imagine programming in a language without XXX.") After all, they have a low quality standard: they need not be checked by a compiler.

A while after Go launched, the criticisms changed tenor somewhat. Some people had actually tried it, but there were still many complainers, including the one quoted above. The problem now was that imagination had failed: Go is a language for writing Go programs, not Java programs or Haskell programs or any other language's programs. You need to think a different way to write good Go programs. But that takes time and effort, more than most will invest. So the usual story is to translate one program from another language into Go and see how it turns out. But translation misses idiom. A first attempt to write, for example, some Java construct in Go will likely fail, while a different Go-specific approach might succeed and illuminate. After 10 years of Java programming and 10 minutes of Go programming, any comparison of the language's capabilities is unlikely to generate insight, yet here come the results, because that's a modern programmer's job.

It's not all bad, of course. Two years on, Go has lots of people who've spent the time to learn how it's meant to be used, and for many willing to invest such time the results have been worthwhile. It takes time and imagination and programming to learn how to use any language well, but it can be time well spent. The growing Go community has generated lots of great software and has given me hope, hope that there may still be actual programmers out there.

However, I still see far too much ill-informed commentary about Go on the web, so for my own protection I will start 2012 with a resolution:

I resolve to recognize that a complaint reveals more about the complainer than the complained-about. Authority is won not by rants but by experience and insight, which require practice and imagination. And maybe some programming.

by rob (noreply@blogger.com) at January 01, 2012 07:17 PM

December 31, 2011

codegrunt.co.uk

New Year

It’s been a long time since I’ve updated this blog, and a completely crazy past few months, so I hope to rectify the former by using the latter as the basis for this post :)

I turned 30 this September, and the force of switching from the deferring-friendly 20’s (‘I can achieve these things, don’t worry, I’m still young’) to the ‘oh shit I’m an adult now’ 30’s has hit harder than I expected (in fact, to be honest, I didn’t expect it at all).

So what’s happened? Well in my personal life, I finally did something about my weight issue and lost ~3.5 stone (~50lb, ~23kg).

In my intellectual/geek life I committed to the open Stanford AI course and completed it with a 98.7% average*, and wrote notes for the purposes of actual applying the course to real things (the notes are not yet fully complete, however I do plan to finish that later), which has really helped with my recently very low intellectual confidence.

Two fundamental things have changed - firstly I’ve got organised about things (for weight loss - food diary, for study - committed, realistic work schedule), secondly and far more importantly, I’ve stopped beating myself up quite as badly about everything. Beating yourself up like that makes you incapable of doing anything since you feel constantly bad about whatever it is you’re doing, and thus reticent to do it, which means you don’t improve/change anything, which means you beat yourself up more, etc. - a vicious, vicious cycle.

Another thing to note here is the amazing usefulness of timeboxing. The past week I have got more hacking done in a week than I have for hundreds of weeks prior.

So what about resolutions? Over the coming year I plan to contribute considerably more to go, and build weak into a fully-fledged chess engine (though I can make no guarantees to its eventual strength) and I intend to work on improving my algorithmic and computer science fundamentals knowledge. On the final bit - I plan to enter the google code jam and blog about the experience, though I don’t expect or predict any sort of performance, it’s more of a motivation and point of focus.

Happy New Year!

* I’m not boasting here. I fell considerably below the performance of many other participants and wish I’d been more careful with many of the answers. Also I realised how rusty I am at this stuff. Also I couldn’t stand to carry on attending the meetup I was attending given how erudite, intelligent and informed the other people were compared to me.

December 31, 2011 12:00 AM

December 27, 2011

Airs – Ian Lance Taylor

Non-free Services

As both of my faithful readers can see, my blog postings have dropped significantly. I’ve been posting my random little comments on Google+ instead.

Which leads me to the following. There is a hard-core group of people who only use free software. I’m not quite that hard-core, but in practice I do use only free software, except perhaps for some binary drivers in the kernel (I don’t actually know whether the systems I’m running use binary drivers or not, and I’m not hard-core enough to find out).

I’ve seen some people argue that if you are serious about using free software, you should also only use Internet services which are themselves free software. For example, you should not use Facebook or Google+, because the software used to run those services is not free.

I don’t agree with that argument. The key goal of free software is that I always have the right to change the software that I am running. When I use an Internet service like Google+, I am not running the software. Even if I had a copy of the software, I would not be able to run it, because I don’t have enough servers. And even if I had enough servers, it would be useless for me to run the software, because I don’t have the data. And there is no way to grant me access to the data, because that would violate the reasonable privacy choices of everybody else using the service.

When it comes to a service like Google+, whether the software is free is not important. Releasing the software would not give me any more freedom than I already have. Google+ is only interesting when many people are operating out of a single shared data base, and that data base must have privacy safeguards to ensure that it is not copied.

What matters with Google+ is not the software, but the data. It is important that I be able to retrieve all my data associated with Google+, and that I be able to retrieve it in a way that makes it possible to use with other software. That is, I should be able to retrieve my posts, my comments on other people’s posts, my list of followers, my photos, etc. And I should be able to plug them into some other software service if I so choose.

In fact Google+ does have a set of APIs which permit me to retrieve my data. I haven’t verified that all Google+ data is available via the APIs, but all the obvious stuff seems to be available. Given those APIs, it should be possible for me to move all my data to some other service which provides te required APIs itself.

So I personally don’t see any reason why even a hard-core free software supporter should avoid using a service like Google+. This isn’t to say that it wouldn’t be nice if Google freed up the software and accepted patches from outside users. It’s just that that is not a critical part of freedom to use software.


by Ian Lance Taylor at December 27, 2011 05:54 PM

December 21, 2011

Go's official blog

Getting to know the Go community

Over the past couple of years Go has attracted a lot of users and contributors, and I've had a great time meeting and talking with many of you. However, for every Gopher I know there are dozens I know nothing about. In order to address this imbalance I've prepared a survey for Go users everywhere.

The survey is short. It asks about you, your involvement with Go, and and your interest in Go-related events. Among other things, this data will help myself and the rest of the Go team plan future Go events and schedule conference appearances.

Please take a minute to complete the survey now.

Thanks!
Andrew

by Andrew Gerrand (noreply@blogger.com) at December 21, 2011 11:55 PM

December 19, 2011

Go's official blog

Building StatHat with Go

My name is Patrick Crosby and I'm the founder of a company called Numerotron. We recently released StatHat. This post is about why we chose to develop StatHat in Go, including details about how we are using Go.

StatHat is a tool to track statistics and events in your code. Everyone from HTML designers to backend engineers can use StatHat easily, as it supports sending stats from HTML, JavaScript, Go, and twelve other languages.

You send your numbers to StatHat; it generates beautiful, fully-embeddable graphs of your data. StatHat will alert you when specified triggers occur, send you daily email reports, and much more. So instead of spending time writing tracking or reporting tools for your application, you can concentrate on the code. While you do the real work, StatHat remains intensely vigilant, like an eagle in its mountaintop nest, or a babysitter on meth.

Here's an example of a StatHat graph of the temperature in NYC, Chicago, and San Francisco:


(click to enlarge)

Architecture Overview

StatHat consists of two main services: incoming statistic/event API calls and the web application for viewing and analyzing stats. We wanted to keep these as separate as possible to isolate the data collection from the data interaction. We did this for many reasons, but one major reason is that we anticipate handling a ton of automated incoming API HTTP requests and would thus have different optimization strategies for the API service than a web application interacting with humans.

The web application service is multi-tiered. The web server processes all requests and sends them to an interactor layer. For simple tasks, the interactor will handle generating any necessary data. For complex tasks, the interactor relies on multiple application servers to handle tasks like generating graphs or analyzing data sets. After the interactor is finished, the web server sends the result to a presenter. The presenter responds to the HTTP request with either HTML or JSON. We can horizontally scale the web, API, application servers, and databases as the demand for services grows and changes over time. There is no single point of failure as each application server has multiple copies running. The interactor layer allows us to have different interfaces to the system: http, command line, automated tests, mobile API. StatHat uses MySQL for data storage.

Choosing Go

When we designed StatHat, we had the following check list for our development tools:

  • same programming language for backend and frontend systems
  • good, fast HTML templating system
  • fast start-up, recompilation, testing for lots of tinkering
  • lots of connections on one machine
  • language tools for handling application-level concurrency
  • good performance
  • robust RPC layer to talk between tiers
  • lots of libraries
  • open source

We evaluated many popular and not-so-popular web technologies and ended up choosing to develop it in Go.

When Go was released in November 2009, I immediately installed it and loved the fast compilation times, goroutines, channels, garbage collection, and all the packages that were available. I was especially pleased with how few lines of code my applications were using. I soon experimented with making a web app called Langalot that concurrently searched through five foreign language dictionaries as you typed in a query. It was blazingly fast. I put it online and it's been running since February, 2010.

The following sections detail how Go meets StatHat's requirements and our experience using Go to solve our problems.

Runtime

We use the standard Go http package for our API and web app servers. All requests first go through Nginx and any non-file requests are proxied to the Go-powered http servers. The backend servers are all written in Go and use the rpc package to communicate with the frontend.

Templating

We built a template system using the standard template package. Our system adds layouts, some common formatting functions, and the ability to recompile templates on-the-fly during development. We are very pleased with the performance and functionality of the Go templates.

Tinkering

In a previous job, I worked on a video game called Throne of Darkness that was written in C++. We had a few header files that, when modified, required a full rebuild of the entire system, 20-30 minutes long. If anyone ever changed `Character.h`, he would be subject to the wrath of every other programmer. Besides this suffering, it also slowed down development time significantly.

Since then, I've always tried to choose technologies that allowed fast, frequent tinkering. With Go, compilation time is a non-issue. We can recompile the entire system in seconds, not minutes. The development web server starts instantly, tests complete in a few seconds. As mentioned previously, templates are recompiled as they change. The result is that the StatHat system is very easy to work with, and the compiler is not a bottleneck.

RPC

Since StatHat is a multi-tiered system, we wanted an RPC layer so that all communication was standard. With Go, we are using the rpc package and the gob package for encoding Go objects. In Go, the RPC server just takes any Go object and registers its exported methods. There is no need for an intermediary interface description language. We've found it very easy to use and many of our core application servers are under 300 lines of code.

Libraries

We don't want to spend time rewriting libraries for things like SSL, database drivers, JSON/XML parsers. Although Go is a young language, it has a lot of system packages and a growing number of user-contributed packages. With only a few exceptions, we have found Go packages for everything we have needed.

Open source

In our experience, it has been invaluable to work with open source tools. If something is going awry, it is immensely helpful to be able to examine the source through every layer and not have any black boxes. Having the code for the language, web server, packages, and tools allows us to understand how every piece of the system works. Everything in Go is open source. In the Go codebase, we frequently read the tests as they often give great examples of how to use packages and language features.

Performance

People rely on StatHat for up to the minute analysis of their data and we need the system to be as responsive as possible. In our tests, Go's performance blew away most of the competition. We tested it against Rails, Sinatra, OpenResty, and Node. StatHat has always monitored itself by tracking all kinds of performance metrics about requests, the duration of certain tasks, the amount of memory in use. Because of this, we were able to easily evaluate different technologies. We've also taken advantage of the benchmark performance testing features of the Go testing package.

Application-Level Concurrency

In a former life, I was the CTO at OkCupid. My experience there using OKWS taught me the importance of async programming, especially when it comes to dynamic web applications. There is no reason you should ever do something like this synchronously: load a user from the database, then find their stats, then find their alerts. These should all be done concurrently, yet surprisingly, many popular frameworks have no async support. Go supports this at the language level without any callback spaghetti. StatHat uses goroutines extensively to run multiple functions concurrently and channels for sharing data between goroutines.

Hosting and Deployment

StatHat runs on Amazon's EC2 servers. Our servers are divided into several types:

  • API
  • Web
  • Application servers
  • Database

There are at least two of each type of server, and they are in different zones for high availability. Adding a new server to the mix takes just a couple of minutes.

To deploy, we first build the entire system into a time-stamped directory. Our packaging script builds the Go applications, compresses the CSS and JS files, and copies all the scripts and configuration files. This directory is then distributed to all the servers, so they all have an identical distribution. A script on each server queries its EC2 tags and determines what it is responsible for running and starts/stops/restarts any services. We frequently only deploy to a subset of the servers.

More

For more information on StatHat, please visit stathat.com. We are releasing some of the Go code we've written. Go to www.stathat.com/srcfor all of the open source StatHat projects.

To learn more about Go, visit golang.org.

by Andrew Gerrand (noreply@blogger.com) at December 19, 2011 05:00 PM

December 17, 2011

Go on web

Go lang on OS X (lion)

Recently I’ve moved from linux to OS X, yep I’m using a so-called “hackintosh”.   Having spent the past week learning how to live in the environment, which for the record I really live, it’s time to hack some Go! … Continue reading


by hokapoka at December 17, 2011 11:43 AM

December 14, 2011

Go's official blog

From zero to Go: launching on the Google homepage in 24 hours

This article was written by Reinaldo Aguiar, a software engineer from the Search team at Google. He shares his experience developing his first Go program and launching it to an audience of millions - all in one day!

I was recently given the opportunity to collaborate on a small but highly visible "20% project": the Thanksgiving 2011 Google Doodle. The doodle features a turkey produced by randomly combining different styles of head, wings, feathers and legs. The user can customize it by clicking on the different parts of the turkey. This interactivity is implemented in the browser by a combination of JavaScript, CSS and of course HTML, creating turkeys on the fly.

Once the user has created a personalized turkey it can be shared with friends and family by posting to Google+. Clicking a "Share" button (not pictured here) creates in the user's Google+ stream a post containing a snapshot of the turkey. The snapshot is a single image that matches the turkey the user created.

With 13 alternatives for each of 8 parts of the turkey (heads, pairs of legs, distinct feathers, etc.) there are more than than 800 million possible snapshot images that could be generated. To pre-compute them all is clearly infeasible. Instead, we must generate the snapshots on the fly. Combining that problem with a need for immediate scalability and high availability, the choice of platform is obvious: Google App Engine!

The next thing we needed to decide was which App Engine runtime to use. Image manipulation tasks are CPU-bound, so performance is the deciding factor in this case.

To make an informed decision we ran a test. We quickly prepared a couple of equivalent demo apps for the new Python 2.7 runtime (which provides PIL, a C-based imaging library) and the Go runtime. Each app generates an image composed of several small images, encodes the image as a JPEG, and sends the JPEG data as the HTTP response. The Python 2.7 app served requests with a median latency of 65 milliseconds, while the Go app ran with a median latency of just 32 milliseconds.

This problem therefore seemed the perfect opportunity to try the experimental Go runtime.

I had no previous experience with Go and the timeline was tight: two days to be production ready. This was intimidating, but I saw it as an opportunity to test Go from a different, often overlooked angle: development velocity. How fast can a person with no Go experience pick it up and build something that performs and scales?

Design

The approach was to encode the state of the turkey in the URL, drawing and encoding the snapshot on the fly.

The base for every doodle is the background:

A valid request URL might look like this: http://google-turkey.appspot.com/thumb/20332620

The alphanumeric string that follows "/thumb/" indicates (in hexadecimal) which choice to draw for each layout element, as illustrated by this image:

The program's request handler parses the URL to determine which element is selected for each component, draws the appropriate images on top of the background image, and serves the result as a JPEG.

If an error occurs, a default image is served. There's no point serving an error page because the user will never see it - the browser is almost certainly loading this URL into an image tag.

Implementation

In the package scope we declare some data structures to describe the elements of the turkey, the location of the corresponding images, and where they should be drawn on the background image.

var (
// dirs maps each layout element to its location on disk.
dirs = map[string]string{
"h": "img/heads",
"b": "img/eyes_beak",
"i": "img/index_feathers",
"m": "img/middle_feathers",
"r": "img/ring_feathers",
"p": "img/pinky_feathers",
"f": "img/feet",
"w": "img/wing",
}

// urlMap maps each URL character position to
// its corresponding layout element.
urlMap = [...]string{"b", "h", "i", "m", "r", "p", "f", "w"}

// layoutMap maps each layout element to its position
// on the background image.
layoutMap = map[string]image.Rectangle{
"h": {image.Pt(109, 50), image.Pt(166, 152)},
"i": {image.Pt(136, 21), image.Pt(180, 131)},
"m": {image.Pt(159, 7), image.Pt(201, 126)},
"r": {image.Pt(188, 20), image.Pt(230, 125)},
"p": {image.Pt(216, 48), image.Pt(258, 134)},
"f": {image.Pt(155, 176), image.Pt(243, 213)},
"w": {image.Pt(169, 118), image.Pt(250, 197)},
"b": {image.Pt(105, 104), image.Pt(145, 148)},
}
)

The geometry of the points above was calculated by measuring the actual location and size of each layout element within the image.

Loading the images from disk on each request would be wasteful repetition, so we load all 106 images (13 * 8 elements + 1 background + 1 default) into global variables upon receipt of the first request.

var (
// elements maps each layout element to its images.
elements = make(map[string][]*image.RGBA)

// backgroundImage contains the background image data.
backgroundImage *image.RGBA

// defaultImage is the image that is served if an error occurs.
defaultImage *image.RGBA

// loadOnce is used to call the load function only on the first request.
loadOnce sync.Once
)

// load reads the various PNG images from disk and stores them in their
// corresponding global variables.
func load() {
defaultImage = loadPNG(defaultImageFile)
backgroundImage = loadPNG(backgroundImageFile)
for dirKey, dir := range dirs {
paths, err := filepath.Glob(dir + "/*.png")
if err != nil {
panic(err)
}
for _, p := range paths {
elements[dirKey] = append(elements[dirKey], loadPNG(p))
}
}
}

Requests are handled in a straightforward sequence:

  1. Parse the request URL, decoding the decimal value of each character in the path.
  2. Make a copy of the background image as the base for the final image.
  3. Draw each image element onto the background image using the layoutMap to determine where they should be drawn.
  4. Encode the image as a JPEG
  5. Return the image to user by writing the JPEG directly to the HTTP response writer.

Should any error occur, we serve the defaultImage to the user and log the error to the App Engine dashboard for later analysis.

Here's the code for the request handler with explanatory comments:

func handler(w http.ResponseWriter, r *http.Request) {
// Defer a function to recover from any panics.
// When recovering from a panic, log the error condition to
// the App Engine dashboard and send the default image to the user.
defer func() {
if err := recover(); err != nil {
c := appengine.NewContext(r)
c.Errorf("%s", err)
c.Errorf("%s", "Traceback: %s", r.RawURL)
if defaultImage != nil {
w.Header().Set("Content-type", "image/jpeg")
jpeg.Encode(w, defaultImage, &imageQuality)
}
}
}()

// Load images from disk on the first request.
loadOnce.Do(load)

// Make a copy of the background to draw into.
bgRect := backgroundImage.Bounds()
m := image.NewRGBA(bgRect.Dx(), bgRect.Dy())
draw.Draw(m, m.Bounds(), backgroundImage, image.ZP, draw.Over)

// Process each character of the request string.
code := strings.ToLower(r.URL.Path[len(prefix):])
for i, p := range code {
// Decode hex character p in place.
if p < 'a' {
// it's a digit
p = p - '0'
} else {
// it's a letter
p = p - 'a' + 10
}

t := urlMap[i] // element type by index
em := elements[t] // element images by type
if p >= len(em) {
panic(fmt.Sprintf("element index out of range %s: "+
"%d >= %d", t, p, len(em)))
}

// Draw the element to m,
// using the layoutMap to specify its position.
draw.Draw(m, layoutMap[t], em[p], image.ZP, draw.Over)
}

// Encode JPEG image and write it as the response.
w.Header().Set("Content-type", "image/jpeg")
w.Header().Set("Cache-control", "public, max-age=259200")
jpeg.Encode(w, m, &imageQuality)
}

For brevity, I've omitted several helper functions from these code listings. See the source code for the full scoop.

Performance

This chart - taken directly from the App Engine dashboard - shows average request latency during launch. As you can see, even under load it never exceeds 60 ms, with a median latency of 32 milliseconds. This is wicked fast, considering that our request handler is doing image manipulation and encoding on the fly.

Conclusions

I found Go's syntax to be intuitive, simple and clean. I have worked a lot with interpreted languages in the past, and although Go is instead a statically typed and compiled language, writing this app felt more like working with a dynamic, interpreted language.

The development server provided with the SDK quickly recompiles the program after any change, so I could iterate as fast as I would with an interpreted language. It's dead simple, too - it took less than a minute to set up my development environment.

Go's great documentation also helped me put this together fast. The docs are generated from the source code, so each function's documentation links directly to the associated source code. This not only allows the developer to understand very quickly what a particular function does but also encourages the developer to dig into the package implementation, making it easier to learn good style and conventions.

In writing this application I used just three resources: App Engine's Hello World Go example, the Go packages documentation, and a blog post showcasing the Draw package. Thanks to the rapid iteration made possible by the development server and the language itself, I was able to pick up the language and build a super fast, production ready, doodle generator in less than 24 hours.

Download the full app source code (including images) at the Google Code project.

Special thanks go to Guillermo Real and Ryan Germick who designed the doodle.

by Andrew Gerrand (noreply@blogger.com) at December 14, 2011 11:23 PM

December 09, 2011

RSC

_rsc: RT @littlecalculist: "The syntax is weird." — Everyone, of every new language, ever

_rsc: RT @littlecalculist: "The syntax is weird." — Everyone, of every new language, ever

December 09, 2011 11:10 PM

December 05, 2011

RSC

_rsc: RT @cahooon: watching the #golang html parser's progress (http://t.co/UuYbADmd) is impressive, and makes me excited to never write an ht ...

_rsc: RT @cahooon: watching the #golang html parser's progress (http://t.co/UuYbADmd) is impressive, and makes me excited to never write an ht ...

December 05, 2011 02:07 PM

_rsc: RT @ehedgehog: These three considerations ... bring us to the year -292277022399. #golang #epoch #newtimeAPI

_rsc: RT @ehedgehog: These three considerations ... bring us to the year -292277022399. #golang #epoch #newtimeAPI

December 05, 2011 02:04 PM

November 29, 2011

Adam Langley

Certificate Transparency

(I don't have comments on this blog, but you can comment on my Google+ post.)

Ben Laurie and I have been working on a longer term plan for improving the foundations of the certificate infrastructure on which most Internet transport security is based on these days. Although Chrome has public key pinning for some domains, which limits the set of permitted certificates, we don't see public key pinning as a long term solution (and nor was it ever designed to be).

For the 10 second summary of the plan, I'll quote Ben: “certificates are registered in a public audit log. Servers present proofs that their certificate is registered, along with the certificate itself. Clients check these proofs and domain owners monitor the logs.”. I would add only that anyone can check the logs: the certificate infrastructure would be fully transparent.

We now have an outline of the basic idea and will be continuing to flesh it out in the coming months, hopefully in conjunction with other browser vendors.

But I thought that, at the outset, it would be helpful to describe some of the limitations to the design space, as I see them:

No side-channels

As I've previously described, side-channels occur when a browser needs to contact a server other than the immediate destination in order to verify a certificate. Revocation checking with OCSP is an example of a side-channel used today.

But in order to be effective, side-channels invariably need to block the certificate verification until they complete, and that's a big problem. The Internet isn't fully connected. Captive portals, proxies and firewalls all mean that the only thing you can really depend on talking to is the immediate destination server. Because of this, browsers have never been able to make OCSP lookups blocking, and therefore OCSP is basically useless for security.

And that's not to mention the privacy, performance and functionality issues that arise from needing side-channels. (What happens when the side-channel server goes down?)

So our design requires that the servers send us the information that we require. We can use side-channels to check up on the logs, but it's an asynchronous lookup.

It's not opt-in, it's all-in

SSL Stripping is a very easy and very effective attack. HSTS prevents it and is as easy to deploy as anything can be for HTTPS sites. But, despite all this, and despite a significant amount of evangelism, take up has been very limited, even by sites which are HTTPS only and the subject of attacks.

While HSTS really has to be opt-in, a solution to the certificate problem doesn't. Although our scheme is incrementally deployable, the eventual aim is that it's required for everybody. Thankfully, since certificates have to be renewed there's an obvious means to incrementally deploy it: require it for certificates issued after a certain date. Although an eventual hard requirement is still needed, it's a lot less of a problem.

It's easy on the server operator

Since the aim is to make it a requirement for all servers, we've sacrificed a lot in order to make it very easy on the server operator. For most server operators, their CA will probably take care of fetching the audit proofs, meaning there's no additional work at all.

Some initial designs included short-lived log signatures, which would have solved the revocation problem. (Revocation would simply be a matter of instructing the logs to stop signing a given certificate.) However, this would have required server operators to update their audit proofs on a near-daily basis. After discussions it became clear that such a requirement wouldn't be tenable for many and so we reluctantly dropped it.

We are also sacrificing decentralisation to make things easy on the server. As I've previously argued, decentralisation isn't all it's cracked up to be in most cases because 99.99% of people will never change any default settings, so we haven't given up much. Our design does imply a central set of trusted logs which is universally agreed. This saves the server from possibly having to fetch additional audit proofs at runtime, something which requires server code changes and possible network changes.

There are more valid certificates than the one that's currently serving

Cheap virtual hosting and EC2 have made multi-homed services common. Even small to medium scale sites have multiple servers these days. So any scheme that asserts that the currently serving certificate is the only valid certificate will run into problems when certificates change. Unless all the servers are updated at exactly the same time, then users will see errors during the switch. These schemes also make testing a certificate with a small number of users impossible.

In the end, the only real authority on whether a certificate is valid is the site itself. So we don't rely on external observations to decide on whether a certificate is valid, instead to seek to make the set of valid certificates for a site public knowledge (which it currently isn't), so that the site can determine whether it's correct.

It's not easy to do

We believe that this design will have a significant, positive impact on an important part of Internet security and that it's deployable. We also believe that any design that shares those two properties ends up looking a lot like it. (It's no coincidence that we share several ideas with the EFF's Sovereign Keys.)

None the less, deployment won't be easy and, hopefully, we won't be pushing it alone.

November 29, 2011 08:00 AM

November 23, 2011

RSC

_rsc: Road maps are more fun if you pretend they're Feynman diagrams.

_rsc: Road maps are more fun if you pretend they're Feynman diagrams.

November 23, 2011 06:37 PM

November 22, 2011

RSC

_rsc: @sdegutis If I remember correctly, lack of FFI is exactly why John McCarthy didn't use #golang to implement the first Lisp.

_rsc: @sdegutis If I remember correctly, lack of FFI is exactly why John McCarthy didn't use #golang to implement the first Lisp.

November 22, 2011 09:36 PM

Adam Langley

Forward secrecy for Google HTTPS

As announced on the Google Security Blog, Google HTTPS sites now support forward secrecy. What this means in practice is two things:

Firstly, the preferred cipher suite for most Google HTTPS servers is ECDHE-RSA-RC4-SHA. If you have a client that supports it, you'll be using that ciphersuite. Chrome and Firefox, at least, support it.

Previously we were using RSA-RC4-SHA, which means that the client (i.e. browser) picks a random key for the session, encrypts it with the server's public key and sends it to the server. Since only the holder of the private key can decrypt the session key, the connection is secure.

However, if an attacker obtains the private key in the future then they can decrypt recorded traffic. The encrypted session key can be decrypted just as well in ten years time as it can be decrypted today and, in ten years time, the attacker has much more computing power to break the server's public key. If an attacker obtains the private key, they can decrypt everything encrypted to it, which could be many months of traffic.

ECDHE-RSA-RC4-SHA means elliptic curve, ephemeral Diffie-Hellman, signed by an RSA key. You can see a previous post about elliptic curves for an introduction, but the use of elliptic curves is an implementation detail.

Ephemeral Diffie-Hellman means that the server generates a new Diffie-Hellman public key for each session and signs the public key. The client also generates a public key and, thanks to the magic of Diffie-Hellman they both generate a mutual key that no eavesdropper can know.

The important part here is that there's a different public key for each session. If the attacker breaks a single public key then they can decrypt only a single session. Also, the elliptic curve that we're using (P-256) is estimated to be as strong as a 3248-bit RSA key (by ECRYPT II), so it's unlikely that the attacker will ever be able to break a single instance of it without a large, quantum computer.

While working on this, Bodo Möller, Emilia Kasper and I wrote fast, constant-time implementations of P-224, P-256 and P-521 for OpenSSL. This work has been open-sourced and submitted upstream to OpenSSL. We also fixed several bugs in OpenSSL's ECDHE handling during deployment and those bug fixes are in OpenSSL 1.0.0e.

Session Tickets

The second part of forward secrecy is dealing with TLS session tickets.

Session tickets allow a client to resume a previous session without requiring that the server maintain any state. When a new session is established the server encrypts the state of the session and sends it back to the client, in a session ticket. Later, the client can echo that encrypted session ticket back to the server to resume the session.

Since the session ticket contains the state of the session, and thus keys that can decrypt the session, it too must be protected by ephemeral keys. But, in order for session resumption to be effective, the keys protecting the session ticket have to be kept around for a certain amount of time: the idea of session resumption is that you can resume the session in the future, and you can't do that if the server can't decrypt the ticket!

So the ephemeral, session ticket keys have to be distributed to all the frontend machines, without being written to any kind of persistent storage, and frequently rotated.

Result

We believe that forward secrecy provides a fairly significant benefit to our users and we've contributed our work back to OpenSSL in the hope that others will make use of it.

November 22, 2011 08:00 AM

November 12, 2011

Kyle Lemons

Throwing My Hat into the Ring

Generics in Go - A proposal for Generic Types in the Go language

I won’t bore you with the details here; read the PDF for those. Here are some examples to whet your appetite.

A somewhat comprehensive example:

// Package gen provides some example generic functionality.
package gen

// Generic types for this package
type Value generic
type Result generic
type ReduceFunc func(Result, Value) Result

// Tern is the ternary operator: Tern(cond,t,f) == (cond?t:f)
func Tern(cond bool, t, f Value) Value {
  if cond {
    return t
  }
  return f
}

// Reduce returns the result of running the ReduceFunc on each successive value
// in list along with the last result.
func (red ReduceFunc) Reduce(r0 Result, list ...Value) Result {
  for _, v := range list {
    r0 = red(r0, v)
  }
  return r0
}

// Check strips out the os.Error return from a function call for use inline.
func Check(val Value, err os.Error) Value {
  if err != nil {
    panic(err)
  }
  return val
}

Using that package:

package main

import (
  "fmt"
  "gen"
  "strconv"
)

func main() {
  add := gen.ReduceFunc(func(x0 int, x1 string) int {
    return x0 + gen.Check(strconv.Atoi(x1))
  })

	nums := os.Args[1:]
  fmt.Printf("Sum of your %s: %v\n",
    "number" + gen.Tern(len(nums)==1, "", "s"),
    add.Reduce(0, os.Args))
}

Everybody’s favorite generic interface:

type Value generic
type Equaler interface {
  Equals(other Value) bool
}

// Integer implements Equaler.
type Integer int
func (i Integer) Equals(j Integer) bool {
	return i == j
}

// Compile-time check.
var _ Equaler = Integer(0)

// Search returns the index of the first element for which list[idx].Equal(val)
// returns true.
func Search(list []Equaler, val Value) int {
  for i, v := range list {
    if v.Equal(val) {
      return i
    }
  }
  return -1
}

The proposal’s source can be found on github.

by Kyle Lemons at November 12, 2011 08:08 AM

November 11, 2011

RSC

_rsc: RT @sesamestreet: Today is definitely brought to you by the number 11.

_rsc: RT @sesamestreet: Today is definitely brought to you by the number 11.

November 11, 2011 05:06 PM

Go's official blog

The Go Programming Language turns two

Two years ago a small team at Google went public with their fledgling project - the Go Programming Language. They presented a language spec, two compilers, a modest standard library, some novel tools, and plenty of accurate (albeit succinct) documentation. They watched with excitement as programmers around the world began to play with Go. The team continued to iterate and improve on what they had built, and were gradually joined by dozens - and then hundreds - of programmers from the open source community.

The Go Authors went on to produce lots of libraries, new tools, and reams of documentation. They celebrated a successful year in the public eye with a blog post last November that concluded "Go is certainly ready for production use, but there is still room for improvement. Our focus for the immediate future is making Go programs faster and more efficient in the context of high performance systems."

Today is the second anniversary of Go's release, and Go is faster and more stable than ever. Careful tuning of Go's code generators, concurrency primitives, garbage collector, and core libraries have increased the performance of Go programs, and native support for profiling and debugging makes it easier to detect and remove performance issues in user code. Go is also now easier to learn with A Tour of Go, an interactive tutorial you can take from the comfort of your web browser.

This year we introduced the experimental Go runtime for Google's App Engine platform, and we have been steadily increasing the Go runtime's support for App Engine's APIs. Just this week we released version 1.6.0 of the Go App Engine SDK, which includes support for backends (long-running processes), finer control over datastore indexes, and various other improvements. Today, the Go runtime is near feature parity with - and is a viable alternative to - the Python and Java runtimes. In fact, we now serve golang.org by running a version of godoc on the App Engine service.

While 2010 was a year of discovery and experimentation, 2011 was a year of fine tuning and planning for the future. This year we issued several "release" versions of Go that were more reliable and better supported than weekly snapshots. We also introduced gofix to take the pain out of migrating to newer releases. Furthermore, last month we announced a plan for Go version 1 - a release that will be supported for years to come. Work toward Go 1 is already underway and you can observe our progress by the latest weekly snapshot at weekly.golang.org.

The plan is to launch Go 1 in early 2012. We hope to bring the Go App Engine runtime out of "experimental" status at the same time.

But that's not all. 2011 was an exciting year for the gopher, too. He has manifested himself as a plush toy (a highly prized gift at Google I/O and other Go talks) and in vinyl form (received by every attendee at OSCON and now available at the Google Store).

And, most surprisingly, at Halloween he made an appearance with his gopher girlfriend!


Photograph by Chris Nokleberg.

by Andrew Gerrand (noreply@blogger.com) at November 11, 2011 12:28 AM

November 10, 2011

Sonia Codes

Horse racing and ant colonies

This post might be about a worker synchronization idiom—whatever an idiom is.  I don’t know.  Is it a way to solve a common problem in a particular language?  I don’t even know if idioms are good or bad.

Anyway, suppose you have a data structure and you want to let multiple workers concurrently read from it and, each doing things slightly differently, compute independent results.  The workers all need to see the entire data structure, but that’s okay because the data isn’t changing during this read and compute phase.  The results need to be combined and reduced.  When all the results are in and reduced, the result is used to update the shared data structure.  Then it all needs to be repeated for some number of iterations.  Is this common?  Are there physical simulations or stochastic algorithms that are like this?  I would think so.

I know, it’s not sounding like idiomatic Go.  It’s communicating by sharing memory.  But still, if it’s a common thing and there’s a way to do it in the language, isn’t that an idiom?  (Maybe it’s a bad idiom.  Then, I’ve heard people say all idioms are bad.  Maybe it’s a good idiom for doing a bad thing…)  Sometimes though, you have an existing algorithm and you want to follow it, even if it does communicate by sharing memory.

The important feature of the algorithm seemed to be the checkpoints (or barriers or whatever) that separate the phases.

Initialization | processing | update | processing | update | …

  • Initialization is a single thread that sets up the shared data.
  • Processing involves multiple concurrent workers, and can only start after initialization is complete.
  • Update is a single thread again and can only start after all workers rendezvous.
  • The next iteration of processing can only start after the update is complete.

It’s not too hard, and surely, like exercise #69 (it seems to be #70 now) there must be lots of ways to do it.  Before showing my complete program though, I tried reducing it to a minimal program that would show the just synchronization without the clutter of everything else.  It was at that point that the problem struck me as analogous to a horse race.

Initialization is like getting the track groomed and everything all set up.  It has to happen without the horses running around.  There is just one track.  It is shared.  To keep the horses from starting, there is a gate that holds them.  They all wait at the gate until the gate opens and lets them run.  Then they all begin to run concurrently.  They finish at different times and some data is recorded.  At some point, the gates must close in preparation for the next race.

package main

import (
    "fmt"
    "math/rand"
    "sync"
    "time"
)

var horses = []string{"pie", "biscuit", "lap", "derpy"}

const nRaces =  4

var startSignal, gates sync.WaitGroup
var finish = make(chan string, len(horses))

func main() {
    startSignal.Add(1)
    for _, name := range horses {
        go horse(name)
    }

    places := make([]string, len(horses))

    for r := 1; r <= nRaces; r++ {
        gates.Add(len(horses))
        startSignal.Done()
        gates.Wait()
        startSignal.Add(1)

        for i := range horses {
            places[i] = <-finish
        }
        fmt.Println("race", r, places)
    }
}

func horse(horseName string) {
    rnd := rand.New(rand.NewSource(time.Nanoseconds()))
    for {
        // wait for start signal
        startSignal.Wait()
        gates.Done()

        // do something
        time.Sleep(9e7+rnd.Int63n(2e7))

        // return result
        finish <- horseName
    }
}

Example output:

race 1 [lap derpy biscuit pie]
race 2 [derpy pie biscuit lap]
race 3 [biscuit derpy lap pie]
race 4 [biscuit derpy pie lap]

It seems a little clunky and mousetrap-like, but I think that might just be the nature of communicating by sharing memory. Results are gathered with a channel in the usual way, and then I use two WaitGroups to implement the latch mechanism of the starting gate. startSignal is binary and is a 1 to N broadcast. All of the horses wait on it to fall to zero, implementing the starting gates opening. Then there is the problem of setting it back to 1 for the start of the next race. It needs to be done before the first horse finishes, or else the horse will find the gate open and begin to run again. It cannot be done immediately on the next line of code however, because that leads to the gate snapping shut before some of the horses have had a chance to leave. The solution was a a separate WaitGroup, this one used in the more common N to 1 mode indicating when each goroutine has completed the step of the horse leaving the gate.

Finally now, the fun program. It’s still just a toy problem, but I coded up an ant colony solution” of the knight’s tour problem as described by Philip Hingston and Graham Kendall. It was fun to reproduce their results and get the same number for cumulative production rate. (Although I couldn’t figure out what they were doing to get the .09 number for mean production rate.

package main

import (
    "fmt"
    "math/rand"
    "sync"
    "time"
)

const boardSize = 8
const nSquares = boardSize * boardSize
const completeTour = nSquares - 1
const cycles = 27000

// pheromone representation read by ants
var tNet = make([]float64, nSquares*8)

// row, col deltas of legal moves
var drc = [][]int{{1, 2}, {2, 1}, {2, -1}, {1, -2},
    {-1, -2}, {-2, -1}, {-2, 1}, {-1, 2}}

// get square reached by following edge k from square (r, c)
func dest(r, c, k int) (int, int, bool) {
    r += drc[k][0]
    c += drc[k][1]
    return r, c, r >= 0 && r < boardSize && c >= 0 && c < boardSize
}

// struct represents a pheromone amount associated with a move
type rckt struct {
    r, c, k int
    t       float64
}

func main() {
    // waitGroups for ant release clockwork
    var start, reset sync.WaitGroup
    start.Add(1)
    // channel for ants to return tours with pheromone updates
    tch := make(chan []rckt)

    // create an ant for each square
    for r := 0; r < boardSize; r++ {
        for c := 0; c < boardSize; c++ {
            go ant(r, c, &start, &reset, tch)
        }
    }

    // accumulator for new pheromone amounts
    tNew := make([]float64, nSquares*8)

    // map for collecting set of complete tours
    allUnique := make(map[string]int)
    tbuf := make([]byte, 2+completeTour) // for building map key

    // heading
    fmt.Println("Board size:", boardSize)
    fmt.Println("Cycles per repeat:", cycles)
    fmt.Println("          Unique                        Production   Cumm.")
    fmt.Println("        complete     Cumm.      Total   rate         prod.")
    fmt.Println("Repeat     tours    unique   attempts   this repeat  rate")

    // each iteration is a "repeat" as described in the paper
    for repeat := 1; ; repeat++ {
        unique := make(map[string]int) // complete tours this repeat

        // initialize board
        for r := 0; r < boardSize; r++ {
            for c := 0; c < boardSize; c++ {
                for k := 0; k < 8; k++ {
                    if _, _, ok := dest(r, c, k); ok {
                        tNet[(r*boardSize+c)*8+k] = 1e-6
                    }
                }
            }
        }

        // each iteration is a "cycle" as described in the paper
        for i := 0; i < cycles; i++ {
            // evaporate pheromones
            for i := range tNet {
                tNet[i] *= .75
            }

            reset.Add(nSquares) // number of ants to release
            start.Done()        // release them
            reset.Wait()        // wait for them to begin searching
            start.Add(1)        // reset start signal for next cycle

            // gather tours from ants
            for i := 0; i < nSquares; i++ {
                tour := <-tch
                // accumulate complete tours
                if len(tour) == completeTour {
                    tbuf[0] = byte(tour[0].r)
                    tbuf[1] = byte(tour[0].c)
                    for i, m := range tour {
                        tbuf[i+2] = byte(m.k)
                    }
                    key := string(tbuf)
                    unique[key] = 1
                    allUnique[key] = 1
                }
                // accumulate pheromone amounts from all ants
                for _, move := range tour {
                    tNew[(move.r*boardSize+move.c)*8+move.k] += move.t
                }
            }

            // update pheromone amounts on network, reset accumulator
            for i, tn := range tNew {
                tNet[i] += tn
                tNew[i] = 0
            }
        }

        // print statistics
        //  fmt.Println("          Unique                        Production   Cumm.")
        //  fmt.Println("        complete     Cumm.       Total   rate         prod.")
        //  fmt.Println("Repeat     tours    unique    attempts   this repeat  rate")
        fmt.Printf("%6d %9d %9d %10d   %6.4f       %6.4f\n",
            repeat, len(unique), len(allUnique), repeat*cycles*nSquares,
            float64(len(unique))/float64(cycles*nSquares),
            float64(len(allUnique))/float64(repeat*cycles*nSquares))
    }
}

func printTour(tour []rckt) {
    seq := make([]int, nSquares)
    for i, sq := range tour {
        seq[sq.r*boardSize+sq.c] = i + 1
    }
    last := tour[len(tour)-1]
    r, c, _ := dest(last.r, last.c, last.k)
    seq[r*boardSize+c] = nSquares
    fmt.Println("Move sequence:")
    for r := 0; r < boardSize; r++ {
        for c := 0; c < boardSize; c++ {
            m := seq[r*boardSize+c]
            if m > 0 {
                fmt.Printf(" %3d", seq[r*boardSize+c])
            } else {
                fmt.Print("    ")
            }
        }
        fmt.Println()
    }
}

type square struct {
    r, c int
}

func ant(r, c int, start, reset *sync.WaitGroup, tourCh chan []rckt) {
    rnd := rand.New(rand.NewSource(time.Nanoseconds()))
    tabu := make([]square, nSquares)
    moves := make([]rckt, nSquares)
    unexp := make([]rckt, 8)
    tabu[0].r = r
    tabu[0].c = c

    for {
        // cycle initialization
        moves = moves[:0]
        tabu = tabu[:1]
        r := tabu[0].r
        c := tabu[0].c

        // wait for start signal
        start.Wait()
        reset.Done()

        for {
            // choose next move
            unexp = unexp[:0]
            var tSum float64
        findU:
            for k := 0; k < 8; k++ {
                dr, dc, ok := dest(r, c, k)
                if !ok {
                    continue
                }
                for _, t := range tabu {
                    if t.r == dr && t.c == dc {
                        continue findU
                    }
                }
                tk := tNet[(r*boardSize+c)*8+k]
                tSum += tk
                // note:  dest r, c stored here
                unexp = append(unexp, rckt{dr, dc, k, tk})
            }
            if len(unexp) == 0 {
                break // no moves
            }
            rn := rnd.Float64() * tSum
            var move rckt
            for _, move = range unexp {
                if rn <= move.t {
                    break
                }
                rn -= move.t
            }

            // move to new square
            move.r, r = r, move.r
            move.c, c = c, move.c
            tabu = append(tabu, square{r, c})
            moves = append(moves, move)
        }

        // compute pheromone amount to leave
        for i := range moves {
            moves[i].t = float64(len(moves)-i) / float64(completeTour-i)
        }

        // return tour found for this cycle
        tourCh <- moves
    }
}

Output:

Board size: 8
Cycles per repeat: 27000
          Unique                        Production   Cumm.
        complete     Cumm.      Total   rate         prod.
Repeat     tours    unique   attempts   this repeat  rate
     1    176027    176027    1728000   0.1019       0.1019
     2    172491    348518    3456000   0.0998       0.1008
     3    201836    550354    5184000   0.1168       0.1062
     4    104574    654928    6912000   0.0605       0.0948
     5    117130    772058    8640000   0.0678       0.0894
...
    95    193387  12424890  164160000   0.1119       0.0757
    96     37647  12462537  165888000   0.0218       0.0751
    97    121887  12584424  167616000   0.0705       0.0751
    98    145072  12729496  169344000   0.0840       0.0752
    99    162658  12892154  171072000   0.0941       0.0754
   100    206599  13098753  172800000   0.1196       0.0758

by Sonia at November 10, 2011 01:07 AM

November 08, 2011

RSC

_rsc: RT @thehistoryguy: BBC reporter: 'This could be the worst crisis Greece has ever known'. There speaks a man without a history degree.

_rsc: RT @thehistoryguy: BBC reporter: 'This could be the worst crisis Greece has ever known'. There speaks a man without a history degree.

November 08, 2011 06:48 PM

November 07, 2011

Airs – Ian Lance Taylor

Anonymous

There is no chance that Edward de Vere, the Earl of Oxford, wrote the plays attributed to William Shakespeare.

That said, I found the movie Anonymous to be reasonably watchable, although I thought many of Vanessa Redgrave’s scenes as the older Queen Elizabeth were ridiculous. But since the movie claims (perhaps as a joke) to be seriously advocating the position that Oxford wrote the plays, I was surprised that they did such a poor job of supporting the theory.

Oxford was shown as being tutored at length on topics other than poetry. He traveled abroad, he intrigued at court. When would he have had time to write the plays and the sonnets? The movie essentially presents Oxford as being mysterious gifted by the ability to write; he speaks of continual voices in his head. That could happen to anybody, and perhaps describes the real Shakespeare–if anybody could have written Shakespeare’s plays, then why not Shakespeare himself?

Oxford is shown as using the plays to support his court intrigues. Is it possible to imagine Shakespeare, with his clear vision of humanity, thinking that he could achieve such ends through his plays? One of the strongest examples of that in the movie was the suggestion that it was odd that Shakespeare portrayed Richard III as a hunchback, but even I know that Richard III was popularly (and probably falsely) considered to be a hunchback long before Shakespeare’s time.

Of course it’s conceivable if unlikely that somebody else wrote Shakepeare’s plays. But the undercurrent of the Oxford theory has always been that a member of the nobility would be more likely as the playwright than a commoner. But this reverses reality. The nobility were highly trained from birth in their roles in society. They were busy people with lots to do. It was far less likely that an earl could write the plays than a member of the middle class. As far as I know only one member of the English nobility ever achieved any note as an author: Lord Dunsany, who lived much later.

The movie did have a couple of nice (non-Shakespearean) lines, one of which, by the Ben Jonson character, was simply the truth: the only reason future ages remember the people who lived then was because they were alive when Shakespeare was writing.


by Ian Lance Taylor at November 07, 2011 06:09 PM

November 03, 2011

RSC

_rsc: RT @Eris: When you think about it, the Bat Signal was probably the first cloud-based push notification.

_rsc: RT @Eris: When you think about it, the Bat Signal was probably the first cloud-based push notification.

November 03, 2011 03:21 AM

November 02, 2011

Go's official blog

Writing scalable App Engine applications

Back in May, we announced the Go runtime for App Engine. Since then, we've opened it up for everyone to use, added many new APIs, and improved performance. We have been thrilled by all the interesting ways that people are using Go on App Engine.

One of the key benefits of the Go runtime, apart from working in a fantastic language, is that it has high performance. Go applications compile to native code, with no interpreter or virtual machine getting between your program and the machine.

Making your web application fast is important because it is well known that a web site's latency has a measurable impact on user happiness, and Google web search uses it as a ranking factor. Also announced in May was that App Engine would be leaving its Preview status and transitioning to a new pricing model, providing another reason to write efficient App Engine applications.

To make it easier for Go developers using App Engine to write highly efficient, scalable applications, we recently updated some existing App Engine articles to include snippets of Go source code and to link to relevant Go documentation.

By David Symonds, November 2011

by Andrew Gerrand (noreply@blogger.com) at November 02, 2011 01:49 AM

October 31, 2011

Go's official blog

Debugging Go programs with the GNU Debugger

Last year we reported that Go's gc/ld toolchain produces DWARFv3 debugging information that can be read by the GNU Debugger (GDB). Since then, work has continued steadily on improving support for debugging Go code with GDB.

Among the improvements are the ability to inspect goroutines and to print native Go data types, including structs, slices, strings, maps, interfaces, and channels.

To learn more about Go and GDB, see the Debugging with GDB article.

by Andrew Gerrand (noreply@blogger.com) at October 31, 2011 02:06 AM

October 29, 2011

codegrunt.co.uk

Brain Thaw

After writing my last post, I again worked my arse off this week to study both the Stanford AI and ML classes in a less crunchy fashion than the week before. Unfortunately the crunch avoidance did not come to pass and I was up until 3am this morning (well, 2am if you take into account the clocks going back :-) cramming on AI.

Since I actually want to learn about AI (and apply it to weak) I am not finding this cramming aspect of the study particularly beneficial. In my experience, cramming simply wears you out and gets you ready for a given short-term task (e.g. homework, later exams) before the information you’ve learned largely plops out of your brain.

For that reason, and for the sake of keeping this doable, I’ve decided to drop the machine learning course and focus fully on AI. There is an irony in that - I have found the AI work to be considerably more involved and challenging than machine learning (that’s not a comment on the relative quality of one course vs. the other by the way), however a. AI is of more relevance to what I want to do, and b. focusing on one thing reduces the stressful feeling of distraction that maintaing another course which requires homework, etc. brings.

I am still very interested in machine learning, so I might very well go over the machine learning course material at a later date. Additionally, the AI course contains some cross-over material so I won’t do entirely without.

Another aspect is that I would like to maintain my notes to a better standard than I have (and which more time would allow me to achieve), rather than having to rush them out because of time constraints. There are almost certainly better notes for the course out there, however there is nothing quite like having a set of notes to refer to you which you’ve written in your own style and to your own tastes. Not invented here syndrome, perhaps!

Meta-Blog Tediousness

On an entirely different subject, you may have noticed I’ve deleted a number of posts. This is because I felt they were of little value and often quite negative. This blog is meant to be a diary of where I’m at in my tech life, and yes that involves both positive and negative, however there is nothing more tedious than wading through either rather mediocre technical posts, or moany personal ones. I’d like to maximise the chances of me (and to some degree others of course :-) actually enjoying reading this blog.

I can only apologise to those few whose comments have consequently been deleted from this site. Hopefully you can understand why I’ve done it.

October 29, 2011 11:00 PM

October 23, 2011

Journal

Two weeks with Sprint

The lure of Sprint was too strong to pass up, but ultimately ended in letdown and abandon.

Sprint's pitch was simple. Where else can you get an all you can eat data plan and ample minutes for $75.00 including the government’s taxation scheme that Karl Marx would be proud of? Done. Sign me up.

Choosing a phone for Sprint's network was not as easy. They offer three compelling choices.

First, you can speak random thoughts of consciousness in a Sprint store, and if a customer has pressed the Siri button on the display model iPhone 4s, you'll likely get verbal confirmation to choose it.

For those flirting with escape from Jobs’ utopia, the gorilla glass encased false god of Android is eager to entice, with a Samsung Galaxy S II. Like a hollywood celeb it's light weight and beautiful. 

But for some, age brings truth, hence the third option, a year old Samsung Nexus S anointed with the purity of plain Gingerbread. I chose this option.

Despite the sweetness of Gingerbread, there is nothing tasty about Samsung’s Nexus S. Extremely poor antennas for wifi, 3g and 4g? Check. A battery that can’t last ½ day with light to moderate use? Check. Screen jitter while scrolling through your twitter feed? Check.

Needless to say the phone went back to the Sprint store. This left two choices left. The iPhone 4s and the Galaxy S II. I opted with the Galaxy S II.

The Galaxy S II represents everything that is right and wrong about Android, the device manufacturers, and the carriers.

On the Galaxy S II, gone is the jerky scrolling of the Nexus S. The screen is vibrant and huge. Samsung retained its use of a plastic enclosure, yet improved its sturdiness, a move that makes the device feel better quality. The antennas are dramatically better, resulting in greater wifi availability and improved call quality.

Unfortunately, the battery still sucks. And Samsung managed to load the device up with crap ware that you cannot delete from the application menu.

To mitigate the battery life, I bought a few chargers to plant at strategic locations at home, in the car and at the office. And most of the crap ware can be stashed in a folder on the desktop. This uncluttered  things enough to pass inspection.

Just as I was getting used to the device, and on the last day of my free trial, Sprint dropped the mother of all bombs. They announced the ending of the unlimited data plan. Furthermore, current users would not be grandfathered in, and thus would be subject to huge data overage charges.

This triggered my immediate cancellation of the Sprint plan.

The data plan was the only reason why I went to Sprint in the first place. With Sprint customers faced a trade-off. You received unlimited data for a unreliable network that has poor coverage in rural areas.

With their latest decision, there is no tradeoff, and therefore no logical reason why anyone whould choose Sprint over another network.

I leveraged the "winback" program AT&T offers customers who made the transgression of choosing another carrier. They put you back on the program exactly as you left it at no charge. 

So here I am, back with AT&T using a feature phone with nothing but time to ponder my next move.

Do I wait three weeks for Samsung’s Galaxy Nexus that boasts Ice Cream Sandwich, Google’s new OS? Do l let lust get the best of me, and choose a Windows Phone 7, with the Mango update, knowing I'll likely be ultiamtely dissapointed with its feature incompleteness? Or do I return to utopia with an iPhone 4s?

The reality is that in this temporal existence, utopia doesn’t exist and there is no perfect phone. Therefore, I’m sticking with my wife’s old feature phone.

by Charles Thompson at October 23, 2011 07:40 PM

October 22, 2011

codegrunt.co.uk

AI/ML Brain Melt

Am currently attempting to do both the Stanford AI and Machine Learning courses at once. My brain is melting.

I’m keeping my ongoing rough notes on github, I’m writing them in markdown so they render relatively nicely there.

I have realised that, if I am actually going to see both courses through to the end, I am going to have to put everything else on hold until they’re done.

Luckily, they both pertain to greater or lesser degrees to weak so its not entirely a pause on other projects. Also, I might choose to hack on weak from time-to-time since I am chomping at the bit to get it moving.

October 22, 2011 11:00 PM

October 18, 2011

Airs – Ian Lance Taylor

Corporate Unions

In an ordinary employer-employee relationship with a large company, the employer has most of the power. When any individual employee seeks a higher wage, he or she has no leverage; for a large company to lose a single employee makes little difference. In the U.S., unions have been a way for employees to get more leverage. The large company can not ignore the effect of many employees working together.

However, many people dislike unions, because unions are only effective when the union members work together. Many people feel that this takes away individual rights, as indeed it does.

It recently occurred to me that there is a different way to look at the issue. Think of the union as a company itself, a special sort of company which operates as a monopsony. When you join the employer, you are actually joining two companies: the employer and the company which provides employees to the employer. The union company and the regular company have a tight relationship, but this is no different from an ordinary monopsony supplier situation, such as is widely found in, e.g., the automotive business. Union companies tend to be more democratic than most companies, but this is not a fundamental difference.

One can of course have multiple union companies providing labor to the parent company. However, it is perfectly reasonable for the parent company to negotiate only with union companies for labor, rather than with individuals. After all, only in exceptional situations would a company purchase non-labor supplies from an individual. Why should labor be any different? Thus the “closed shop” has a clear support: it’s a matter of efficiency for the parent company.

This perspective may remove some of the traditional complaints against unions. They are replaced by a different issue, which is that every employee has two loyalties. However, in reality we all have multiple loyalties in our lives—to our families, our sports teams, etc.

Try thinking of the matter this way the next time you feel angry about unions. They are just doing what regular companies do.


by Ian Lance Taylor at October 18, 2011 02:10 PM

October 17, 2011

Sonia Codes

Another version of #69

As Andrew said, there are many different ways of approaching this.  Following Rog’s comment to my last post, I tried a new version.  This one starts a goroutine for each URL fetched, but manages to get by with only a single channel communication per URL.  Is it better?  Hard to say.  For the dummied data set, of course none of this matters.  “Better” would make much more sense in the context of a real problem.

Anyway, one more way:

type request struct {
    url   string
    depth int
}

type result struct {
    req  *request
    body string
    urls []string
    err  os.Error
}

func Crawl(url string, depth int, f Fetcher, maxWorkers int) {
    // resCh is the only channel used.
    // one result will be sent for each url fetched,
    // and this is the only synchronization needed.
    resCh := make(chan *result)

    // fetch function literal fetches a single url and
    // returns the result on resCh.
    fetch := func(req *request) {
        body, urls, err := f.Fetch(req.url)
        resCh <- &result{req, body, urls, err}
    }

    // initial condition is that a fetch is started on the top url,
    // the url is noted as having been seen, the fetch is noted as
    // outstanding, and there is otherwise no backlog of requests.
    go fetch(&request{url, depth})
    seen := map[string]bool{url: true}
    outstanding := 1
    var backlog []*request

    for outstanding > 0 {
        // block and wait for a result.  print results when it arrives,
        // and then one less request is known to be outstanding.
        res := <-resCh
        if res.err != nil {
            fmt.Println(res.err)
        } else {
            fmt.Printf("found: %s %q\n", res.req.url, res.body)
        }
        outstanding--

        // check if any urls in the result need to be crawled.
        if res.req.depth <= 1 {
            continue // at depth limit
        }
        for _, u := range res.urls {
            if seen[u] {
                continue // don't fetch the same url twice
            }
            // at this point we know this is a new url we want
            // to crawl.  mark it as seen and prepare a request.
            seen[u] = true
            req := &request{u, res.req.depth - 1}

            // if we are under the concurrency limit, start a
            // fetch immediately.  otherwise backlog it.
            if outstanding < maxWorkers {
                go fetch(req)
                outstanding++
            } else {
                backlog = append(backlog, req)
            }
        }

        // after handling a result, it is possible that it
        // resulted in no new requests, but that there was
        // an existing backlog.  with that oustanding request
        // done, we can pick one request off the backlog.
        if len(backlog) > 0 && outstanding < maxWorkers {
            go fetch(backlog[len(backlog)-1])
            backlog = backlog[:len(backlog)-1]
            outstanding++
        }
    }
}

by Sonia at October 17, 2011 08:35 PM

Going Along

Almost renewed vim

I have been using Acme for many years and almost forgot how complex
the program editors could be. But last several months I have been
digging into headless embedded system, where only Vim is accessible
from serial line (ssh included). I used to be a man full of Vim, but
that days are long gone. Now I am a simple man who is contented with
simple things. So I cannot believe I have spent a whole week reading
'A Byte of Vim' while forcing myself using it for all my code works on
Windows/Linux/Macs, only because Plan9port stopped working after
upgrading to Mac OS X Lion. No. It is a mistake learnt the hard way.
Vim is gone away from me that no force can renew it back. Give up. I'm
a happy Acmer again, even that means I need to run Virtualbox ubuntu
on top of Lion, install Plan9port in order to get back my dear Acme.
Yes. Ubuntu is configured to log on directly into 'Recovery console',
where .profile runs rio & acme & google-chrome &, and xshove the
latter two to full screen, which I am used to alt-tab swapping them.

by Fango (noreply@blogger.com) at October 17, 2011 04:33 AM

October 15, 2011

Sonia Codes

Communication diagrams for Go

As long as I’ve been programming, I’ve often found it helpful to sketch little diagrams to help me puzzle out programs. I’ve been known to draw plain old flowcharts for example, sometimes to the amusement of others. In my object oriented days, I assembled a few very elaborate object hierarchy diagrams, because they seemed a crucial foundation for the elaborate programs based on them. Thankfully none of these are in the pile of scratch paper on my desk currently (or posted on my wall!)

Programming in Go, a type of diagram I have occasionally found useful though, is one showing communication between goroutines. I put a goroutine name in a box and draw a vertical line down from it, vaguely suggesting a sequential process. I represent channels as horizontal lines that go from one vertical line to another. Then I annotate the diagram with whatever I think is relevant. I’ve found pencil and paper best for doing this. Anytime I’ve tried using drawing or diagramming software I’ve wasted huge amounts of time and ultimately not been pleased with the result. For showing examples here, I’m resorting to ASCII art! For exhibit 1, here’s a diagram of Andrew Gerrand’s solution to exercise 64 in A Tour of Go.

                                         one per url to be fetched!
                                                 +---------------+
+------+ url                       (url string) +---------------+|
| main |--------------------------------------->| crawler.fetch |+
+------+                                        +---------------+
|                 n = workers                                   |
|                  +-------------+                              |
|                 +-------------+|                              |
|                 | crawler.run |+                              |
|                 +-------------+                               |
|                               | c.req      string      c.req  |
|                               |-range-----------------------<-|
|                               |                               |
| c.res     *result      c.res  |
|-range-----------------------<-|
|                               |

Note that while lines representing channels go from one vertical line to another, There is a line from the main box to the crawler.fetch box. This doesn’t represent a channel, but data passed as a parameter at the invocation of the goroutine. Without that, it’s not obvious where crawler.fectch gets its data. I put an annotation about this data in parentheses reminiscent of function call syntax.

When there are multiple instances of a goroutine, I use a shadowed box and put an annotation above the box saying something about how many instances are created or are running.

The main annotation for a channel is its type, which I always put above line near the middle. Channel communication generally goes in one direction, which is shown with an arrow on the channel line. If you can arrange goroutines so that communication goes from right to left on the diagram, then the arrows look like send and receive communication operations. I’ve found it useful to annotate both ends of the channel lines with the name of the channel in that goroutine. In this case both ends use the same variable name, so it might seem a little redundant, but I think that’s helpful information.

So, here’s another. This is Rog’s solution.

                                            one per url fetched!
                                                 +-----------+
+------+                           {url string} +-----------+|
| main |--------------------------------------->| "fetcher" |+
+------+                                        +-----------+
|                                                           |
| limiter <-         struct{}, 10                 <-limiter |
|------------------------>>>>>------------------------------|
|                                                           |
|                                                           |
| rc                         result                      r  |
|-range---------------------------------------------------<-|

The fetcher goroutine here happens to be an anonymous function literal. I put “fetcher” in quotes to show that fetcher isn’t really the name of the function in the source code, but is just kind of a descriptive name used in the diagram. Also, the data supplied from the main goroutine is not passed as a parameter but as a free variable to the closure so I used brace brackets, kind of suggestive of the literal.

The limiter channel poses a problem for my diagramming scheme because data goes from left to right. Arrows on the channel line cutely suggestive of channel syntax don’t work because they would go the wrong way. In fact I used to draw them the wrong way, but as I got more used to reading Go code, I found this disturbing. Here I’m experimenting with just putting the channel operators in their correct relation to the channel names and then putting a bold sort of arrow under the channel type. (I’m making this all up as I go along, you see…)

So how does Rog’s approach compare to Andrew’s from this perspective? At a glance it seems nicer because it uses fewer goroutines. Rate limiting is done by putting tokens in a buffered channel and Andrew’s “worker” goroutines are not needed. If you look at the amount of channel communication going on however, it’s about the same. In each case there are two channel communications per url fetched. Really I’m not sure we can do better for a rate limited algorithm.

Can we do worse? Always! For a great example, I offer my previous blog post. Diagrams aren’t even needed to notice the difference in the amount of channel communication going on. I’m having all my concurrent goroutines do a bunch of concurrency stuff that can be avoided with a different algorithm.

A shocking recommendation appeared on Go Nuts recently to “avoid concurrency as much as possible.” This heresy was immediately challenged. The clarification is that of course you use concurrency when you have to, but only when you have to. Synchronization is expensive. If you don’t have to share something, don’t! If there’s a way to avoid sharing something, do it.

Anyway, back to the two diagrams presented above.  There is one thing that bothers me.  There is a separate goroutine created for each individual url.  Is that really necessary?  Looking at all the solutions presented in the Go Nuts thread, they all do this.  My sad solution of the previous post does this.  Goroutines are pretty cheap, true, but still I understand there’s a 4k stack, and who knows what else it takes to get one started.  It seems a lot of churn.

Is there a solution with a diagram like this? It would still have two channel communications per url, but no separate goroutine per url, just main and a small constant number of worker goroutines.

+------+                                         n = workers
| main |                                          +----------+
+------+                                         +----------+|
|                                                | "worker" |
|                                                +----------+
|                                                           |
| reqCh <-              *request                    <-reqCh |
|------------------------->>>>>-----------------------------|
|                                                           |
|                                                           |
|  resCh               *result                       resCh  |
|<--------------------------------------------------------<-|
|                                                           |

Well yes. Here is one example:

type request struct {
    url   string
    depth int
}

type result struct {
    req  *request
    body string
    urls []string
    err  os.Error
}

func Crawl(url string, depth int, f Fetcher, workers int) {
    reqCh := make(chan *request)
    resCh := make(chan *result)
    for i := 0; i < workers; i++ {
        go func() {
            for r := range reqCh {
                body, urls, err := f.Fetch(r.url)
                resCh <- &result{r, body, urls, err}
            }
        }()
    }

    seen := map[string]bool{url: true}
    backlog := []*request{&request{url, depth}}
    outstanding := 1
    for outstanding > 0 {
        var res *result
        for len(backlog) > 0 {
            // feed backlog to reqCh until a result arrives.
            select {
            case reqCh <- backlog[len(backlog)-1]:
                backlog = backlog[:len(backlog)-1]
            case res = <-resCh:
                goto gotResult
            }
        }
        res = <-resCh // no backlog.  block until result arrives.
    gotResult:
        outstanding--
        if res.err != nil {
            fmt.Println(res.err)
        } else {
            fmt.Printf("found: %s %q\n", res.req.url, res.body)
        }
        if res.req.depth > 1 {
            for _, u := range res.urls {
                if !seen[u] {
                    seen[u] = true
                    outstanding++
                    backlog = append(backlog,
                        &request{u, res.req.depth - 1})
                }
            }
        }
    }
}

The magic is all in using a select statement. We need main to be handling data in both directions depending on what data is available. That’s exactly what select does.

These communication diagrams don’t describe algorithms. They don’t even suggest them. They do however give you a synopsis of goroutines and channel communication, and this may prompt you to consider alternatives. Is everything in the diagram needed? Can you solve the problem with less?


by Sonia at October 15, 2011 03:56 AM

October 12, 2011

Go's official blog

Go App Engine SDK 1.5.5 released

Today we released version 1.5.5 the Go App Engine SDK. You can download it from the App Engine downloads page.

This release includes changes and improvements to the App Engine APIs and brings the supporting Go tool chain to release.r60.2 (the current stable release). Also included in this release are the godoc, gofmt, and gofix tools from the Go tool chain. They can be found in the root directory of the SDK.

Some changes made in this release are backwards-incompatible, so we have incremented the SDK api_version to 3. Existing apps will require code changes when migrating to api_version 3.

The gofix tool that ships with the SDK has been customized with App Engine-specific modules. It can be used to automatically update Go apps to work with the latest appengine packages and the updated Go standard library. To update your apps, run:


/path/to/sdk/gofix /path/to/your/app

The SDK now includes the appengine package source code, so you can use the local godoc to read App Engine API documentation:


/path/to/sdk/godoc appengine/datastore Get

Important note: We have deprecated api_version 2. Go apps that use api_version 2 will stop working after 16 December 2011. Please update your apps to use api_version 3 before then.

See the release notes for a full list of changes. Please direct any questions about the new SDK to the Go App Engine discussion group.

by Andrew Gerrand (noreply@blogger.com) at October 12, 2011 04:32 AM

A preview of Go version 1

We want to be able to provide a stable base for people using Go. People should be able to write Go programs and expect that they will continue to compile and run without change, on a timescale of years. Similarly, people should be able to write books about Go, be able to say which version of Go the book is describing, and have that version number still be meaningful much later. None of these properties is true for Go today.

We propose to issue a Go release early next year that will be called “Go version 1”, Go 1 for short, that will be the first Go release to be stable in this way. Code that compiles in Go version 1 should, with few exceptions, continue to compile throughout the lifetime of that version, as we issue updates and bug fixes such as Go version 1.1, 1.2, and so on. It will also be maintained with fixes for bugs and security flaws even as other versions may evolve. Also, production environments such as Google App Engine will support it for an extended time.

Go version 1 will be a stable language with stable libraries. Other than critical fixes, changes made to the library and packages for versions 1.1, 1.2 and so on may add functionality but will not break existing Go version 1 programs.

Our goal is for Go 1 to be a stable version of today’s Go, not a wholesale rethinking of the language. In particular, we are explicitly resisting any efforts to design new language features “by committee.”

However, there are various changes to the Go language and packages that we have intended for some time and prototyped but have not deployed yet, primarily because they are significant and backwards-incompatible. If Go 1 is to be long-lasting, it is important that we plan, announce, implement, and test these changes as part of the preparation of Go 1, rather than delay them until after it is released and thereby introduce divergence that contradicts our goals.

Today, we are publishing our preliminary plan for Go 1 for feedback from the Go community. If you have feedback, please reply to the thread on the golang-nuts mailing list.

by rsc (noreply@blogger.com) at October 12, 2011 04:17 AM

October 10, 2011

RSC

_rsc: RT @bmarkovic79: #golang is most fun I've had with a compiled PL since I've discovered Turbo Pascal as a kid.

_rsc: RT @bmarkovic79: #golang is most fun I've had with a compiled PL since I've discovered Turbo Pascal as a kid.

October 10, 2011 10:21 PM

Sonia Codes

A Tour of Go #69 Exercise: Web Crawler

I can’t resist. The difficulty level of the exercise is similar to much of what I’ve posted on this blog and I just want to talk about it.

For any of you who don’t regularly follow the Go Blog or Go Nuts, I’m talking about the final exercise, #69, of the recently published A Tour of Go. This is a perfect little introduction to the language that starts with the most basic elements of the language and progresses through some of the best and most interesting elements of the language. There are exercises along the way. The first exercises are easy, then they become more challenging. I believe most people new to Go will find the final exercise in particular to be a satisfying challenge. If you haven’t taken the tour yet, I encourage you to do so and to attempt the exercises, especially #69, the subject of my post here.

Done? Good. :) Of the two TODO items, “Don’t fetch the same URL twice” is easy to add.  One quick and dirty solution is to replace the Crawl function with the following,

func Crawl(url string, depth int, fetcher Fetcher) {
    c2(url, depth, fetcher, map[string]bool{url: true})
}

func c2(url string, depth int, fetcher Fetcher, m map[string]bool) {
    // TODO: Fetch URLs in parallel.
    if depth <= 0 {
        return
    }
    body, urls, err := fetcher.Fetch(url)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Printf("found: %s %q\n", url, body)
    for _, u := range urls {
        if !m[u] {
            m[u] = true
            c2(u, depth-1, fetcher, m)
        }
    }
    return
}

This works, but some people might not like a couple of things here. It introduces a new function, c2, and c2 has a fourth parameter. Do you agonize about the clutter of another function or the overhead of pushing another parameter on the stack? There are other ways to do it. You could make the map a package variable. Bad idea. I won’t even show it. An excellent and popular technique is a recursive closure:

func Crawl(url string, depth int, fetcher Fetcher) {
    m := map[string]bool{url: true}
    var c2 func(string, int)
    c2 = func(url string, depth int) {
        // TODO: Fetch URLs in parallel.
        if depth <= 0 {
            return
        }
        body, urls, err := fetcher.Fetch(url)
        if err != nil {
            fmt.Println(err)
            return
        }
        fmt.Printf("found: %s %q\n", url, body)
        for _, u := range urls {
            if !m[u] {
                m[u] = true
                c2(u, depth-1)
            }
        }
        return
    }
    c2(url, depth)
}

Alternatively, you could use a struct and a method:

func Crawl(url string, depth int, fetcher Fetcher) {
    c := &crawlHistory{fetcher, map[string]bool{url: true}}
    c.c2(url, depth)
}

type crawlHistory struct {
    fetcher Fetcher
    m       map[string]bool
}

func (c *crawlHistory) c2(url string, depth int) {
    // TODO: Fetch URLs in parallel.
    if depth <= 0 {
        return
    }
    body, urls, err := c.fetcher.Fetch(url)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Printf("found: %s %q\n", url, body)
    for _, u := range urls {
        if !c.m[u] {
            c.m[u] = true
            c.c2(u, depth-1)
        }
    }
    return
}

Which of these forms appeal to you is likely to depend on what other languages you know. If you know a language with closures, you probably like the first one. If your experience is object oriented, the second probably looks good to you. It really doesn’t matter.

One elegant little change that can be made to the second version is to embed Fetcher in crawlHistory. Remove the field name from Fetcher so that the struct definition reads simply

type crawlHistory struct {
    Fetcher
    m map[string]bool
}

The call to Fetch can now be written

    body, urls, err := c.Fetch(url)

Embedding wasn’t covered in the tour, but that’s okay because we’re not going to complete this exercise without a couple of other things that weren’t covered in the tour.

Next on the TODO list is fetching URLs in parallel. We’re going to start multiple goroutines and let them crawl different urls found on the page. A pretty big thing not covered in the tour is that concurrent map access is not safe without synchronization. That means these multiple goroutines need to access to the map one at a time. If we don’t serialize access to the map, we risk wrong answers or even corrupt memory and a crash.

Also not covered is that fmt.Println should be synchronized as well. It turns out that we have no guarantee from the operating system even that output from multiple threads won’t get interleaved.

Finally, covered so subtly that you probably missed it is that a Go program terminates when main terminates, without waiting for other goroutines. (Take another look at the output of example 61.) We will start goroutines to crawl urls found on the page, but then we need to do something to wait for them to complete.

So we’re going to need lots of synchronization to do this exercise! The tour did mention the sync package, and there is stuff there to do the job, but we can do the exercise easily without the sync package so I won’t go into it just yet. Go channels, as shown in the tour, represent a very general purpose mechanism that easily handle all of the synchronization needs for this exercise.

The pattern I use for serializing access to the shared resources—the map and fmt.Println—uses channels with capacity=1. One channel is created for a resource that is to be shared and this one channel is passed to all goroutines that want to access the resource. When a goroutine wants to access the resource, it must take (some reference to) the resource from the channel, use the resource, and then return the resource to the channel. It’s like the salt shaker on the table. Only one person uses it at a time, and otherwise it sits in a place where everyone can reach it.

The pattern I use to wait for goroutine completion is that if a function launches goroutines, it must also create a channel for them to report completion. It counts the number of goroutines it launches, then waits for exactly that many completion reports.

Simple enough? Here’s the code:

// struct renamed crawlShared to reflect that it provides access to
// things that are shared across goroutines (the goroutines being
// instances of c2, specifically.)
type crawlShared struct {
    Fetcher     // embedded for Fetch method.

    // the "salt shaker" pattern:  a channel holds the shared map
    mapAccess   chan map[string]bool

    // about the same pattern, except that there is nothing obvious
    // to put in the channel.  instead, a boolean value is used as
    // a token.  the value is ignored.  all that matters is the
    // presence or absence of the token in the channel.
    printAccess chan bool
}

func Crawl(url string, depth int, fetcher Fetcher) {
    c := &crawlShared{
        fetcher,
        make(chan map[string]bool, 1),
        make(chan bool, 1),
    }

    // put the salt shaker on the table.  that is, put the map
    // in the channel, making it available to goroutines.
    c.mapAccess <- map[string]bool{url: true}

    // same with the token to serialize printing
    c.printAccess <- true

    // run goroutine to crawl top level url.
    // since we are starting exactly one goroutine here, we wait
    // for a single completion report.  receipt means that all
    // lower levels have also completed and it is safe to return
    // --and allow the caller to return, in this case, main().
    done := make(chan bool)
    go c.c2(url, depth, done)
    <-done
}

func (c *crawlShared) c2(url string, depth int, pageDone chan bool) {
    // the function has multiple return points.  all of them must
    // report goroutine completion by sending a value on pageDone.
    if depth <= 0 {
        pageDone <- true
        return
    }

    body, urls, err := c.Fetch(url)
    if err != nil {
        // here's how to print:
        // take the token (waiting for it if it's not there.)
        <-c.printAccess
        // do whatever you need to do while other goroutines are
        // excluded from printing.
        fmt.Println(err)
        // put the token back, allowing others to print again.
        c.printAccess <- true

        pageDone <- true
        return
    }

    // same sequence of steps to print found message
    <-c.printAccess
    fmt.Printf("found: %s %q\n", url, body)
    c.printAccess <- true

    // "found" means the url was fetched without error and that urls
    // on the fetched page are collected in the slice "urls."
    // synchronization to crawl these urls in parallel is implemeted
    // with the uDone channel.  create the channel, count the number of
    // goroutines started, then wait for exactly that many completions.
    uDone := make(chan bool)
    uCount := 0

    // salt shaker pattern for map access:  get the map from
    // the channel, and then hold it while iterating over urls.
    // this works with the assumption that all of the operations here
    // take trivial time compared to the relatively lengthy time
    // to fetch a url.  other than map access (which is what we need
    // exclusive access for!) the only operations are iterating over
    // a string slice, incrementing an integer, and starting
    // a goroutine.  these all run very fast so it is reasonable and
    // best to hold "the lock" that is, exclusive map access, while
    // running through this loop.
    m := <-c.mapAccess
    for _, u := range urls {
        if !m[u] {
            m[u] = true
            uCount++
            go c.c2(u, depth-1, uDone)
        }
    }
    c.mapAccess <- m

    // wait for the number of goroutines started just above.
    for ; uCount > 0; uCount-- {
        <-uDone
    }

    // and finally, report completion of this level
    pageDone <- true
}

So that’s kind of the safety scissors version. I think it shows a correct solution while introducing a minimum of concepts that were not covered in the tour.

I’ll leave you with this alternative that uses a few more tricks. The tricks require greater knowledge of the language and libraries, but make for code that is both more concise and faster. This version dispenses with the struct by going back to the recursive closure, trades printAccess for a little trick with the log package, trades mapAccess for a sync.Mutex, and replaces all the done channels with a single sync.WaitGroup. With the waitGroup there is no longer any need to run the first call to c2 as a goroutine, mm, and there’s a defer statement in there too.

import (
    "log"
    "os"
    "sync"
)

var fmt = log.New(os.Stdout, "", 0)

func Crawl(url string, depth int, fetcher Fetcher) {
    m := map[string]bool{url: true}
    var mx sync.Mutex
    var wg sync.WaitGroup
    var c2 func(string, int)
    c2 = func(url string, depth int) {
        defer wg.Done()
        if depth <= 0 {
            return
        }
        body, urls, err := fetcher.Fetch(url)
        if err != nil {
            fmt.Println(err)
            return
        }
        fmt.Printf("found: %s %q\n", url, body)
        mx.Lock()
        for _, u := range urls {
            if !m[u] {
                m[u] = true
                wg.Add(1)
                go c2(u, depth-1)
            }
        }
        mx.Unlock()
    }
    wg.Add(1)
    c2(url, depth)
    wg.Wait()
}

Oh, and without the fmt package, there’s a line in fakeFetcher.Fetch that now has to read

    return "", nil, os.NewError("not found: " + url)

by Sonia at October 10, 2011 01:56 AM

October 08, 2011

codegrunt.co.uk

Bitboards

My open source chess engine project, Weak, is progressing well as I build up the absolute fundamentals.

As discussed in the readme, the current approach is to get to the point where the engine can play legal (against a subset of the rules of chess), random, moves. Once this is implemented then I will slowly improve the engine until it gets to the point where it can actually play competitive chess.

In pursuit of this, I have been taking full advantage of the amazing power of the internet to provide information on any subject you can possibly think of, no matter how niche, and the best resource I have found so far is the rather excellent chess programming wiki.

As a guide to how to proceed, I have been working through the getting started section of the wiki, starting with the board representation, which is arguably the most fundamental choice in the design of a chess engine.

I have chosen to use a bitboard representation. Bitboards work by assigning 64-bit values to each piece type, where each bit of each value indicates whether a piece of the type in question is present on a certain square of the board. Representing the board this way permits the use of bitwise logic to interact with different board positions + due to the ease with which processors can perform these operations, analysis can be performed efficiently (in theory, at least).

Here is the actual board data structure:-

struct board {
  uint64_t pawns, rooks, knights, bishops, queen, king;
};

The engine stores separate instances of this for white and black.

I have chosen to map board positions to bit positions as follows:-

bit = rank * 8 + file

E.g.:-

Index of E1 = 0 * 8 + 4 = 4

Index of H3 = 2 * 8 + 7 = 23

Over the coming week I hope to actually bring the engine to the point where it can play a game :)

Forgive the sparseness of this post, I would have liked to put some more graphics + effort into it, however I am so ridiculously busy at the moment with this + my other projects that I simply do not have the time!

October 08, 2011 11:00 PM

Adam Langley

Classifying solutions to the certificate problem

This is something that I wrote up internally, but which Chris Palmer suggested would be useful to post publicly for reference. It presents some, somewhat artificial, axis on which I believe that all proposed solutions to addressing weaknesses in the current certificate ecosystem fall. By dividing the problem into those decisions, I hope to make the better solutions clearer.

Axis 1: Private vs public signing

At the moment we have private signing. A CA can sign a certificate and tell nobody about it and the certificate is still valid. This is the reason that we have to go crawl the Internet in order to figure out how many intermediate CA certs there are.

In public signing, certificates aren't valid unless they're public.

There are degrees of how public schemes are. Convergence is a public scheme: certificates have to be visible to the notaries, but it's a lot less public than a scheme where all certificates have to be published. And published where? Highly public schemes imply some centralisation.

Private schemes don't protect us from CAs acting in bad faith or CAs which have been compromised. Public schemes help a lot in these cases, increasingly so the more public they are. Although a certificate might be valid for a short time, evidence of misbehavior is recorded. Public schemes also allow each domain to monitor all the certificates for their domain. Fundamentally, the only entity that can answer the question of whether a certificate is legitimate is the subject of the certificate itself. (See this tale of a Facebook certificate.)

Private schemes have the advantage of protecting the details of internal networks (i.e. not leaking the name www.corp.example.com).

Axis 2: Side channels or not

Revocation checking which calls back to the CA is a side channel. Convergence notaries are too. OCSP stapling is not, because the server provides the client with everything that it needs (assuming that OCSP stapling worked).

Side channels which need to be a hard fail are a problem: it's why revocation checking doesn't actually work. Private networks, hotel networks and server downtime are the issues. Side-channels are also a privacy and performance concern. But they're easier on the server operator and so more likely to be deployed.

In the middle are soft-fail side-channels. These offer limited protection because the connection proceeds even when the side-channel fails. They often queue the certificate up for later reporting.

Axis 3: Clocks or not

OCSP with nonces doesn't need clock sync. OCSP with time stamps does.

Keeping clocks in sync is a problem in itself, but it allows for short lived statements to be cached. It can also be a useful security advantage: Nonces require that a signing key be online because it has to sign a constant stream of requests. With clocks, a single response can be served up repeatedly and the key kept largely off-line. That moves the online key problem to the clock servers, but that's a smaller problem. A compromised clock server key can be handled by querying several concurrently and picking the largest cluster of values.

Examples

OCSP today is {private,side-channel,clock}. The 'let's fix OCSP' solutions are typically {private,side-channel,no-clock} (with an option for no-side-channel). Convergence is {mostly-public,side-channel,no-clock}.

I think the answer lies with {public,no-side-channel,clock}, but it's a trek to get there. Maybe something for a future post.

October 08, 2011 07:00 AM

October 06, 2011

RSC

_rsc: A preview of Go version 1. http://t.co/TEmIwVX9 #golang @go_nuts

_rsc: A preview of Go version 1. http://t.co/TEmIwVX9 #golang @go_nuts

October 06, 2011 01:23 PM

October 04, 2011

Go's official blog

Learn Go from your browser

We are excited to announce A Tour of Go, a guided tour of the Go programming language you can run from your browser.

The tour is hands-on, demonstrating the language through code samples that you can modify, compile, and run from the tour itself. (The technology behind the Go Playground does the work.)

The tour has three sections. The first section covers basic syntax and data structures; the second discusses methods and interfaces; and the third introduces Go's concurrency primitives. Each section concludes with a few exercises so you can practice what you've learned.

So, what are you waiting for? Get started now!

by Andrew Gerrand (noreply@blogger.com) at October 04, 2011 11:18 PM

October 03, 2011

Adam Langley

False Start: Brocade broken again

I wrote previously that Brocade had released a firmware update for their ServerIron SSL terminators which fixed an incompatibility with False Start. However, it now appears that they didn't fix the underlying issue, rather they special cased Chrome's current behaviour.

Sadly, due to Chrome implementing a workaround for the BEAST attack, their special casing doesn't work anymore and breaks Chrome 15.

So, if you run a Brocade ServerIron you should contact me ASAP. I'll be adding sites running this hardware to the False Start blacklist for Chrome 15 to allow Brocade to release another firmware update.

October 03, 2011 07:00 AM

October 01, 2011

Sonia Codes

Dining Savages

“Dining Savages” is another toy problem from The Little Book of Semaphores.  Quoting from the PDF,

A tribe of savages eats communal dinners from a large pot that
can hold M servings of stewed missionary1. When a savage wants to
eat, he helps himself from the pot, unless it is empty. If the pot is
empty, the savage wakes up the cook and then waits until the cook
has refilled the pot.

So…the pot is a shared integer.  Sure you could make one special place in memory and do synchronization stuff to control access to it, but that’s not the Go way.  In Go, we share by communicating—in this case, that means we pass the integer around.  We pass it around by passing it through channels.  One channel I call potHolder. It’s a buffered channel with capacity=1. It’s a place to put the pot. Let all of the savages access the pot holder and the result is that any of them can pick up the pot, take from it, (decrement the int) and then return the pot to the pot holder. If a savage finds it empty, he uses another channel to give it to the cook.

package main

import (
    "log"
    "os"
    "rand"
    "sync"
    "time"
)

var fmt = log.New(os.Stdout, "", log.Lmicroseconds)

const (
    potCap             = 5
    nSavages           = 3
    nServingsPerSavage = 4
    cookTime           = 2e8
    avgEatTime         = 1e8
)

type pot int

func main() {
    rand.Seed(time.Nanoseconds())

    fillReq := make(chan pot)
    go cook(fillReq)

    potHolder := make(chan pot, 1)
    potHolder <- pot(0)
    var s sync.WaitGroup
    s.Add(nSavages)
    for i := 1; i <= nSavages; i++ {
        // savages wander into camp at random intervals
        time.Sleep(rand.Int63n(cookTime) / nSavages)
        go savage(i, potHolder, fillReq, &s)
    }
    s.Wait()
}

func savage(i int, potHolder, fillReq chan pot, s *sync.WaitGroup) {
    // some savages eat faster than others
    eatTime := avgEatTime/2 + rand.Int63n(avgEatTime)

    for s := 0; s < nServingsPerSavage; s++ {
        fmt.Println("savage", i, "hungry!")
        pot := <-potHolder
        if pot == 0 {
            fmt.Println("savage", i, "finds empty pot and wakes cook")
            fillReq <- pot
            pot = <-fillReq
        }
        fmt.Println("savage", i, "eating")
        potHolder <- pot - 1
        // time passes while eating
        time.Sleep(eatTime)
    }
    fmt.Println("savage", i, "happy")
    s.Done()
}

func cook(fillReq chan pot) {
    for {
        fmt.Println("cook sleeping")
        <-fillReq
        fmt.Println(`cook grumbles "i'm cooking"`)
        time.Sleep(cookTime) // time passes while cooking
        fmt.Println(`cook mutters "here, ya ungrateful savages"`)
        fillReq <- potCap
    }
}

The algorithm here is almost exactly the same as Downey’s, and yet Downey’s explanation includes a mutex, semaphores, rendezvous, and a “scoreboard pattern.” Is it really that hard? I think mostly the wording is hard. In general, I find the wording of Go easier.

Go also helps by holding related things together. A mutex is a thing that synchronizes access to some data object. They are separate and the declaration of the mutex generally has no dependence on the declaration of the data object. You’re on your own to use some coding convention to hold them together. A Go channel on the other hand is typed. A channel can fulfill the synchronization role of a mutex, but is typed consistent with the data object.

This simple pattern I use when I translate a mutex-based algorithm into Go is to create a buffered channel of capacity=1 to hold the data object.

mutex.wait() (with no reference to the data object being controlled) in Downey’s pseudocode becomes pot := <-potHolder in my code. It’s so nice to not have to worry about where the data object is, what it is called, or who else might be messing with it.  The synchronization operation (channel receive) serves up the data object and hands it to you!  It’s synchronization and communication.

The channel savages use for communicating with the cook is not buffered and is also not in a select statement on either end. Both send and receive are therefore blocking, which makes this an example of a rendezvous. The term is used to describe synchronous communication between threads. Synchronous means that a savage goroutine will be at the line fillReq <- pot at the same time that the cook goroutine is at the line <-fillReq. Which ever goroutine arrives at its line first will block and wait for the other goroutine to arrive at its line. Data is then exchanged through the channel and both goroutines can proceed.

Why do we even care? Well, we don’t strictly need to know the term rendezvous, but in this case it is nice to know that the communication operation is blocking. It lets us use the same channel for communication in both ways. Once the savage has handed over the pot to the cook, he stands there ready to take the pot back with the same hand, so to speak. This only works because the pot is guaranteed to be in complete possession of the cook before the savage can attempt to take it back again.

This guarantee comes from the Go memory model specification which defines the concept “happens before” which provides guarantees such as this about the order of events in Go’s concurrent environment. The document says for example, “A send on a channel happens before the corresponding receive from that channel completes.” This is comforting, but then very interestingly it says, “A receive from an unbuffered channel happens before the send on that channel completes.” Here is the guarantee of synchronous communication. It’s saying that once the savage starts handing the pot over, that the cook getting the pot out of the channel happens before the the savage is free to do anything else. That is, before the next line of savage code attempts to take the pot back.


by Sonia at October 01, 2011 12:17 AM

September 29, 2011

Airs – Ian Lance Taylor

Nuclear Irrationality

I was recently thinking about my college studies of nuclear warfare. At the time it seemed like a relevant topic, and I took two courses on it. Like everything, the more you look into it the more complex it gets. The depth of the thinking in nuclear warfare planning was both impressive and appalling.

One of the more interesting cases was driven by the fear of a Soviet invasion of Western Europe. In retrospect we know there was never a danger of that, but at the time it was a real concern. The western strategists feared that in a conventional war, the Soviet tanks would rapidly rout the smaller European armies. The use of nuclear weapons, or at least their potential use, was an obvious way to counter this threat.

However, most of the nuclear weapons were in the U.S. It was clear that no U.S. president would launch nuclear weapons at the Soviet Union in order to forestall an invasion of Europe. The U.S. promised to support Europe, but if the war actually started, a nuclear attack on the U.S.S.R. could only end in a nuclear counter-attack on the U.S. That would never happen. England and France had a few nuclear weapons, but would their leaders really launch them, knowing that they would face certain death in the overwhelming nuclear counter-attack? A bold and calculating leader of the Soviet Union might be willing to risk that nobody would take the nuclear option, and be willing to gamble that they would win a conventional war (again, this was the fear of the U.S. and Europe, the Soviet Union knew perfectly well that they could not win such a war). How could the U.S. and Europe use nuclear weapons as a credible deterrent to a conventional invasion?

The answer was, as I said, both impressive and appalling. NATO distributed low-yield nuclear weapons throughout Europe (they even had nuclear landmines). In the event of an invasion, complete control over the weapons was handed over to local commanders. The decision to use nuclear weapons would not be in the hands of an elected leader far from the war zone. It would be in the hands of a local colonel facing the immediate loss of his command. The Soviet Union might gamble (so the thinking went) on the reactions of a few political leaders they could study closely. They would never gamble on the reactions of several hundred local military commanders. Although the weapons were relatively low-yield, the expectation was that once a war went nuclear, the only thing that would stop it from escalating would be a quick complete cessation of hostilities.

This is a nice example of achieving your goal by explicitly giving up your ability to act rationally.


by Ian Lance Taylor at September 29, 2011 04:27 AM

September 27, 2011

Sonia Codes

Barber Shop

In a Go-nuts discussion a while back, Dmitry Vyukov mentions in passing,

Btw, it’s possible to implement Barber Shop with only channels in a
quite idiomatic way (IMHO):

seats := make(chan *Customer, 4) // 4 seats

func (self *Customer) EnterShop() bool {
select {
case seats <- self:
default: return false
}

}

The Barber Shop problem to which he refers has a Wikipedia page and is also covered in “The Little Book of Semaphores.”  If you’re not familiar with the problem, I encourage you to go read the WP entry at least, then look at Dmitry’s code snippet.  He’s using a buffered channel as a data structure that conveniently has safe concurrent access already built in.  The elements of the channel represent the waiting room seats in the barber shop.  Each one can hold one customer.  Customers can contend for the seats, but the language will see to it that there is never more than one customer per seat.  The barber can attend to them in order, and more customers can seat themselves only as waiting room seats become available.  This solution has no mutexes or semaphores, just a single Go channel.

The technique is nice and is really just that simple.  The rest of this post takes a closer (if pedantic) look.

So it’s nice, but it hasn’t been mentioned yet what real-world problems this might apply to. The buffered channel represents a thread-safe FIFO queue. That should certainly have wide applicability. The opening paragraph of the WP article says it’s “inter-process communication and synchronization problem between multiple operating system processes.” Well wahoo, that covers a lot of territory. Thankfully, the problem as usually stated is much narrower. The specifics are usually start something like,

  • There are a number of “customer” processes which can run concurrently.
  • There is one “barber” process which runs concurrently with customer processes.
  • The barber process can do some unit of useful work “haircut” for customer processes.
  • There is a fixed capacity FIFO queue that customer processes must use to get the barber process to perform the haircut.

So in other words, it’s a job queuing system. Now we’re getting somewhere. Additional details are usually specified or implied:

  • The customer process “gets the barber to perform the haircut” by enqueueing some data object. The data object represents a command for the barber process to perform the haircut work unit for that customer.
  • The barber process performs the action of executing the haircut command; that is, it does the work.
  • The barber executes only one command at a time and processes it to completion before accepting the next command.
  • If the queue is empty and the barber is not executing a command, the barber sleeps. That is, the barber process enters some sort of idle state.
  • If a customer process enqueues a haircut command when the barber is sleeping, the barber wakes.
  • In the awake state, and while there are haircut commands enqueued, the barber sequentially takes a command and executes it.
  • If a customer process attempts to enqueue a haircut command when the queue is already full, the attempt fails. The customer process handles this failure in some graceful way, but does not wait for a space in the queue.

This describes a mechanism—a concurrent algorithm—enabling concurrent processes to ask a single, shared, sequential worker process to perform a specified work unit for them, presumably something they can’t do for themselves.  This is much more specific, and yet there are still loose ends unspecified.  Notice most problem descriptions say nothing about a haircut “command” and yet certainly this is the meaning of a customer sitting in a chair.  Notice also most problem descriptions gloss over any distinction between the customer process, a customer data object, and the haircut command.  What are these things, what creates or instantiates them, what is their lifetime?  These kinds of issues are important in the real world.  Often you don’t get to pick the answers, but rather they are fixed for your application.  A toy program that makes one set of assumptions may not be easily adapted to a different set of constraints.

Without thinking about these things too hard just yet, here is a complete program written around Dimitry’s code snippet.

package main

import (
    "fmt"
    "sync"
)

const (
    nWaitingRoomChairs = 2
    nCustomers         = 10
)

type customer int

var seats = make(chan customer, nWaitingRoomChairs)

func (c customer) enterShop() bool {
    select {
    case seats <- c:
    default:
        fmt.Println(c, "no cut")
        return false
    }
    return true
}

var wg sync.WaitGroup

func main() {
    go barber()
    wg.Add(nCustomers)
    for i := customer(1); i <= nCustomers; i++ {
        go customerGr(i)
    }
    wg.Wait()
}

func barber() {
    for {
        c := <-seats
        fmt.Println(c, "cut")
        wg.Done()
    }
}

func customerGr(c customer) {
    if !c.enterShop() {
        wg.Done()
    }
}

You can see Dmitry’s code in lines 15-25; everything else there is just to complete a working program. I’ll explore specifics of what creates what in an expanded program, but first I want to simplify this one a bit. Barber Shop problem statements often specify the “enterShop” method, but in the simple program above, it looks rather pointless. It is only called from the customerGr function, so all the code from enterShop could just be included in customerGr. The customer type then is left with no methods, and it was just an int anyway, so I think this type can be dispensed with altogether. Here’s the simplified version:

package main

import (
    "fmt"
    "sync"
)

const (
    nWaitingRoomChairs = 2
    nCustomers         = 10
)

var wg sync.WaitGroup
var wr = make(chan int, nWaitingRoomChairs)

func main() {
    go barber()
    wg.Add(nCustomers)
    for i := 1; i <= nCustomers; i++ {
        go customer(i)
    }
    wg.Wait()
}

func barber() {
    for {
        c := <-wr
        fmt.Println(c, "cut")
        wg.Done()
    }
}

func customer(i int) {
    select {
    case wr <- i:
    default:
        fmt.Println(i, "no cut")
        wg.Done()
        return
    }
}

That version may or may not be enough to get credit on a homework assignment, but it certainly doesn’t answer all the questions you might have.  I’ll present an expanded version now that is instrumented with lots of print statements to better show the goroutine interactions.  To make things clear regardless of how the scheduler schedules goroutines, I’ll add some time.Sleeps to simulate events at random times and to simulate work getting done.

package main

import (
    "log"
    "os"
    "rand"
    "sort"
    "sync"
    "time"
)

var fmt = log.New(os.Stdout, "", log.Lmicroseconds)

const (
    nWaitingRoomChairs = 2
    nCustomers         = 10
    avgCutTime         = 1e8
    shopOpenTime       = 10e8
)

type haircutCommand struct {
    customerId int
    cutDone    chan bool
}

func main() {
    rand.Seed(time.Nanoseconds())

    fmt.Println(nWaitingRoomChairs, "chairs in the waiting room")
    wr := make(chan *haircutCommand, nWaitingRoomChairs)

    go barberGr(wr)

    fmt.Println(nCustomers, "customers will arrive")
    arrivals := make([]float64, nCustomers)
    for i := range arrivals {
        arrivals[i] = rand.Float64()
    }
    sort.Float64s(arrivals)

    var wg sync.WaitGroup // wait for each customer goroutine to finish
    wg.Add(nCustomers)

    shopT0 := time.Nanoseconds()
    for i, arrivalTime := range arrivals {
        delay := int64(arrivalTime*shopOpenTime) -
            (time.Nanoseconds() - shopT0)
        if delay > 0 {
            time.Sleep(delay)
        }
        go customerGr(i+1, wr, &wg)
    }

    wg.Wait()
}

func barberGr(wr chan *haircutCommand) {
    var napStart int64
    for {
        if len(wr) == 0 {
            napStart = time.Nanoseconds()
            fmt.Println("no customers.  barber sleeps")
        }
        cmd := <-wr
        if napStart > 0 {
            fmt.Println("barber wakes.  nap:",
                time.Nanoseconds()-napStart)
            napStart = 0
        }
        fmt.Printf("barber begins cutting customer %d's hair\n",
            cmd.customerId)
        time.Sleep(avgCutTime/2 + rand.Int63n(avgCutTime))
        fmt.Printf("barber finishes customer %d\n", cmd.customerId)
        cmd.cutDone <- true
    }
}

func customerGr(i int, wr chan *haircutCommand, wg *sync.WaitGroup) {
    fmt.Println("customer", i, "arrives looking shaggy")
    defer wg.Done()
    cutDone := make(chan bool)
    select {
    case wr <- &haircutCommand{i, cutDone}:
    default:
        fmt.Println("customer", i, "sees full shop and goes away")
        return
    }
    fmt.Println("customer", i, "takes a seat")
    <-cutDone
    fmt.Println("customer", i, "leaves looking neat")
}

A couple of changes are in the general interest of code clean up. I serialize output, just to be safe, with the log package. Also main() now declares wr and wg, which were formerly package variables, and passes them to functions as needed.

I add avgCutTime and shopOpenTime to the package level const list. These values are in nanoseconds rather than simulated barber shop minutes or hours. This is convenient for passing to time.Sleep of course, and really it’s just the ratios of the these numbers in the const list that affect the output. (It’s interesting to play with them.)

I define haircutCommand as a struct type. This change illustrates the distinction I mentioned earlier between the customer object and the request for a haircut. I still represent the customer object simply as an int, although it’s easy to see that it could be a reference to some other object, potentially with fields and methods and such. The haircutCommand contains the customer object and also the bookkeeping needed to execute the command. In this case it is a channel for signaling completion of the haircut.

Within main(), one significant change is construction of the slice arrivals. I want to simulate customers arriving at random independent times, so I have main fill a slice with uniformly distributed values and then sort them to get the times at which to simulate customers arriving. main() then sequences customers by starting goroutines as indicated by the arrivals array. Doing it this way, the goroutnes are not started all at once but are staged. There will never be a time when nCustomers instances of customerGr will all be running at once.

The barber goroutine now prints a message when it sleeps. Before, this wasn’t really clear. We could read the code and see that the barber would block on the channel read, but there was no indication of this in the output. We can also now see where we could add code that might do something associated with sleeping, like maybe spinning down a disk drive and starting it back up again.

The customer goroutine creates a new cutDone channel and handles the interaction between this channel and the WaitGroup.

Within a toy program like this, it’s hard to maintain a distinction between what you are trying to demonstrate and the mechanism you are using to demonstrate it. The WaitGroup, for example, is there to keep the program from terminating before all the goroutines have completed. This seems pretty clearly part of the demonstration mechanism so I’d rather not have it integrated with either the customer object (which can otherwise be demonstrated as just an int) or the haircut command object. Still, the barber, as part of the job queuing system being demonstrated, needs to signal when the cut is complete. This is more properly done with a separate mechanism then, the cutDone channel.

Sadly, I’m leaving the distinction between the demonstrator and the demonstrated a bit muddled in the the case of the barber and the customer goroutines. Originally, we had the enterShop method, which was clearly something being demonstrated. But really, it’s just the select statement. I think it’s enough to just observe that that’s where the job queuing happens. The other thing being demonstrated there is waiting for work unit completion. Again, it’s just a single statement. Other than those two statements, customerGr is concerned with the simulation, printing messages and doing stuff with the WaitGroup.

How about the barber goroutine, where is the distinction between demonstrator and demonstrated there? Interestingly, everything there is something being demonstrated. Even the print statements can be considered placeholders for more practical functions, perhaps named enterSleepState, restoreCapabilitesAfterSleeping, and doUnitOfMeaningfulWork.

Breaking apart customerGr and barberGr into these pieces is way too much work to do for this blog post, but it should be clear by now how to do it, should you need to for some real job queuing problem, or some real homework problem.


by Sonia at September 27, 2011 02:02 AM

September 25, 2011

codegrunt.co.uk

An Update and Introducing Weak

Phew. Having had a break I have got over my mini-crisis/burnout and feel ready to get back into the wonderful world of coding.

I haven’t been keeping this blog wonderfully updated, nor have I been making great progress on my projects. So, to address this, I have refocused and committed to working on 2 projects in particular (as well as study, see below) - go, an excellent systems programming language from google, which I humbly hope to contribute to further, and weak, a chess engine I am building from scratch.

An aside - yes, lorix is being put on the sidelines. I do intend to come back to it, however it is just far too much work for me to be able to reasonably work on it at the moment. I have deleted its github page for now; however I will restore it when I get back to working on it. There is a certain irony in that I talked about my track record on promises in the lorix post, however I did say that I was not making any promises. You were warned! :-) Astute readers will note that I am in fact promising things here, however I do very much intend to keep these promises as I am very focused on these projects. Ahem!

I have also committed to following the Stanford AI and Machine Learning courses, both of which I am studying on the advanced track (i.e. voluntarily doing homework + exams). I am also studying (principally algorithmic/data structure) fundamentals with the high bar of being able to pass a google interview at some point in the future. Note this is a theoretical bar - this is no comment on whether I do or do not actually intend to attempt to execute that in practice, or whether I am in fact at all capable of mashing a keyboard let alone writing an efficient program :-)

So a busy, busy boy. I also intend to update this blog far more frequently. Translation - I intend to actually update this blog from time-to-time :-)

Weak

Weak is a chess engine, i.e. a program which plays chess. I intend to start with a very naive approach, then gradually reduce the naivety throughout until it is as efficient as I can make it. The guiding principles of weak are - a. strong play (as strong possible) and b. an obsessive focus on optimisation at all points in the code. As a result of point b, I am writing weak in C (and perhaps assembly where necessary).

Yes, I know, in many ways this seems a perfect fit for go; however, I intend weak to be as much an exercise in learning C and low-level optimal programming as just a chess engine project. As I want to absolutely control performance throughout, I want to use a language which is as close to the metal as possible. Go is an absolutely brilliant language (y’know, so much so that I’m actually trying to contribute to it), however it is still young and it takes away some control.

In general, I don’t intend to defend my programming choices on practicality grounds; this is as much a learning project as it is just a straight up coding project. I intend to, at some point, take a look at GPGPU programming with an eye to expanding weak’s capabilities. For now, however, that is merely conjecture.

I suspect that an eye towards optimisation from day 1 will have an overall positive impact on performance, as all the little optimisations add up. The endlessly paraded ‘premature optimisation is the root of all evil’ Knuth quote is somewhat misleading I think - algorithmic optimisation matters throughout, and it’s difficult to go back on poor performance choices if they are littered throughout your code and underlie everything. Having said that, I intend to steer clear of silly micro-optimisations, and also intend to profile ruthlessly to avoid guessing where performance issues arise from.

Looking Forward

I will be writing a series of blog posts as I progress with the various projects, both as a diary for myself and somewhere I can point interested people at. Turning 30 has given me a real focus on what I want to pursue, and I am very much committed to following it. What makes me considerably more confident about these goals compared to previous ones is that I’ve established a ‘head fake’ - I only permit myself to change my mind about what I pursue once a year at my birthday; in between I focus on the projects I have set for myself. This reduces procrastination and uncertainty and ensures I work hard on projects without the inevitable self-doubt and worry affecting things.

September 25, 2011 11:00 PM

September 23, 2011

Adam Langley

Chrome and the BEAST

Thai Duong and Juliano Rizzo today demoed an attack against TLS 1.0's use of cipher block chaining (CBC) in a browser environment. The authors contacted browser vendors several months ago about this and so, in order not to preempt their demo, I haven't discussed any details until now.

Contrary to several press reports, Duong and Rizzo have not found, nor do they claim, any new flaws in TLS. They have shown a concrete proof of concept for a flaw in CBC that, sadly, has a long history. Early reports of the problem date back nearly ten years ago and Bard published two papers detailing the problem.

The problem has been fixed in TLS 1.1 and a workaround for SSL 3.0 and TLS 1.0 is known, so why is this still an issue?

The workaround (prepending empty application data records) is perfectly valid according to the protocol but several buggy implementations of SSL/TLS misbehaved when it was enabled. After Duong and Rizzo notified us, we put the same workaround back into Chrome to see if the state of the Internet had improved in the years since the last attempt. Sadly it was still infeasible to implement this workaround and the change had to be reverted.

Use of TLS 1.1 would also have solved the issue but, despite it being published in 2006, common SSL/TLS libraries still don't implement it. But even if there was widespread deployment of TLS 1.1, it wouldn't have helped avoid problems like this. Due to a different, common bug in SSL 3.0 implementations (nearly 12 years after SSL 3.0 was obsoleted by TLS 1.0), browsers still have to perform SSL 3.0 downgrades to support buggy servers. So even with a TLS 1.1 capable browser and server, an attacker can trigger a downgrade to SSL 3.0 and bypass the protections of TLS 1.1.

Finally, the CBC attacks were believed to be largely theoretical but, as Duong and Rizzo have pointed out today, that's no longer the case.

Initially the authors identified HTML5 WebSockets as a viable method of exploiting the CBC weakness but, due to unrelated reasons, the WebSockets protocol was already in the process of changing in such a way that stopped it. The new WebSockets protocol shipped with Chrome 14 but several plugins have been found to offer features that might allow the attack to be performed.

Duong and Rizzo confirmed that the Java plugin can be used, but Chrome already blocks the execution of Java by default. Other plugins, if installed, can be disabled on the about:plugins page if the user wishes.

The attack is still a difficult one; the attacker has to have high-bandwidth MITM access to the victim. This is typically achieved by being on the same wireless network as the victim. None the less, it's a much less serious issue than a problem which can be exploited by having the victim merely visit a webpage. (Incidentally, we pushed out a fix to all Chrome users for such a Flash bug only a few days ago.)

Also, an attacker with MITM abilities doesn't need to implement this complex attack. SSL stripping and mixed-scripting issues are much easier to exploit and will take continued, sustained effort to address. Duong and Rizzo have highlighted this fact by choosing to attack one of the few HSTS sites.

Thanks to an idea suggested by Xuelei Fan, we have another workaround for the problem which will, hopefully, cause fewer incompatibility problems. This workaround is currently being tested on the Chrome dev and beta channels but we haven't pushed it on the stable channel yet. Since we don't really know if the fix will cause problems it's not something that we want to drop on people without testing. The benefit of a fix to Chrome's TLS stack is also limited as Chrome already uses the newer WebSockets protocol and it doesn't fix problems in plugins.

If it turns out that we've misjudged something we can quickly react, thanks to Chrome's auto-update mechanism.

It's also worth noting that Google's servers aren't vulnerable to this problem. In part due to CBC's history, Google servers have long preferred RC4, a cipher that doesn't involve CBC mode. Mention has also been made of Chrome's False Start feature but, since we don't believe that there are any vectors using Chrome's stack, that's immaterial.

September 23, 2011 07:00 AM

September 22, 2011

Sonia Codes

Algorithms are code, not types

Russ Cox wrote a very popular post on the Go-Nuts list recently in a thread titled “How can Go solve a problem that is well served by multiple inheritance?”  From a complex discussion of Dijkstra’s shortest path algorithm, multiple inheritance, constrained genericity, and generic types, Russ cut away nonsense to show how “generic” algorithms can be written with clarity in Go using interfaces.  I put generic in quotes there because Russ wrote this long post without ever using the word generic once.  The word is loaded, of course, with preconceptions from other languages which is a good reason to avoid the word in the context of Go, but just as a word in the English language, I think it describes well this style of programming that Go interfaces enable.  It’s a style that separates code from data, allowing the same piece of code to work with a whole class (English language definition) of different types of data.

Of special interest to me, the original post was prompted by a Rosetta Code task, Maze Solving.  I’ll come back to this task later, but first I’ll point out a few other RC tasks that I think are relevant.  One that popped in my mind as I was reading Russ’s post is Parametric Polymorphism.  This is a fancy computer science term and so to complete the RC task in Go I did a bit of homework first.  For a little insight into the task author’s thinking, I checked the original implementation languages.  Haskell, OCaml, and C++.  Uh huh.  Then I followed the Wikipedia links in search of some consensus on the meaning of the term and how I might interpret the concepts within Go.

Wading through all that, my conclusion seemed simple.  A parameter is an input to a function.  Parameter polymorphism is when a parameter can be of different types.  That makes it an interface type in Go.  You can pass objects of different concrete types to the function, and the function will access them generically through a common interface.  We can do that.

The task description suggests implementing a container type, a tree specifically, and a map function that traverses the tree.  Most language examples on the page managed this much, but the task also says to “write … a short bit of code that uses [the parametric type].”  This I found lacking or at least not obvious in most of the examples.  Further, it seemed to me that to really illustrate polymorphism, you should show that this “bit of code” working on multiple types, and thus that you need to actually implement more than one type.  “Poly” as a word prefix, anyone?  So, as I’ve done often on RC, I wrote more than other people wrote.  My example goes a bit farther than others, perhaps farther than the task author was thinking, but as far as I felt was necessary to fully demonstrate the task.

package main

import "fmt"

func average(c intCollection) float64 {
    var sum, count int
    c.mapElements(func(n int) {
        sum += n
        count++
    })
    return float64(sum) / float64(count)
}

func main() {
    t1 := new(binaryTree)
    t2 := new(bTree)
    a1 := average(t1)
    a2 := average(t2)
    fmt.Println("binary tree average:", a1)
    fmt.Println("b-tree average:", a2)
}

type intCollection interface {
    mapElements(func(int))
}

type binaryTree struct {
    // dummy representation details
    left, right bool
}

func (t *binaryTree) mapElements(visit func(int)) {
    // dummy implementation
    if t.left == t.right {
        visit(3)
        visit(1)
        visit(4)
    }
}

type bTree struct {
    // dummy representation details
    buckets int
}

func (t *bTree) mapElements(visit func(int)) {
    // dummy implementation
    if t.buckets >= 0 {
        visit(1)
        visit(5)
        visit(9)
    }
}

I wanted to offer “average” as an example of a generic algorithm. It is my “bit of code” for this task that is parameterized. Everyone knows the algorithm: add up all all the numbers and divide by how many there are. The generic part is that it doesn’t matter where the numbers are stored or how they are organized. All that matters is that you can get them.

Reviewing this RC task inspired me to update another, Knuth Shuffle.  The minimal task requirement is to shuffle an integer array, and so that’s what my initial implementation did.  At the time (January 2011) I didn’t bother with the “if possible, an array of any type” because hey, Go doesn’t do generics, right?  Oh, but this algorithm is so easy to write generically.

Unlike the algorithm for computing averages, this one does have some constraints about the way data is organized.  Specifically, the shuffle doesn’t really make sense unless data is organized in some kind of sequence.  It’s enough to assume that data can be indexed with an integer.  What else is needed?  The number of elements is handy; also the algorithm needs to swap data elements.  The easy way to specify this is by index.  It turns out that’s enough!  Here is what’s needed of a collection:

type shuffler interface {
    Len() int      // number of things in the collection
    Swap(i, j int) // swap the two things indexed by i and j
}

And here’s the algorithm, written generically, parametrically polymorphized, or jargon free–as a simple Go function that uses an interface.

func shuffle(s shuffler) {
    for i := s.Len() - 1; i >= 1; i-- {
        j := rand.Intn(i + 1)
        s.Swap(i, j)
    }
}

As a little aside here, note that shuffler is a subset of sort.Interface. I didn’t have to carefully craft that, or even think about it as I wrote my code, but it kind of makes sense that shuffling and sorting might have similar requirements. Really sorting just has one more, the Less method, which pays attention to the values of the elements. It kind of makes sense that shuffling doesn’t care about the values. A consequence of this is that any type you might happen to have made sortable by ensuring that it implements sort.Interface is automatically shufflable with the shuffle function and interface above. The author of Go’s sort package didn’t have to do anything special to make this possible. You with your sortable type didn’t have to do anything beyond implementing the sort interface, and yet just by including the code above for shuffle and shuffler, you can shuffle anything that you can sort. That’s reusable code.

A number of RC tasks are like Parametric Polymorphism in that they cite a computer science term and ask for examples of it. Constrained Genericity was one I enjoyed finding. I didn’t know the term, but it was plain that Go interfaces do exactly what the task asks for. Abstract type is another one. After puzzling out all the text of the task description and the WP article on the term you can finally say, “huh. So it’s just an interface.”

Returning to the Maze Solving task on RC and the “how multiple inheritance” thread on Go-Nuts, Dijkstra’s shortest path algorithm was held up as a solution and the discussion followed. One comment I liked was the observation that Dijkstra’s algorithm is overkill for the problem—it is designed for weighted graphs, and the maze problem on RC is an equal-weight problem.  Simple breadth-first search would be a fine choice.  (I might code it up soon, as after all the attention from Go-Nuts, no one has bothered to submit a solution to RC.)

Another comment I liked was that even for Dijkstra’s algorithm, a heap-based version is likely overkill.  The observation was that the set of candidate end-points under consideration at any time is likely far smaller than the number of vertices, and that a simple linear search of the candidates is likely sufficient.  Indeed I found this to be true.

I was sure I had coded up Dijkstra’s algorithm fairly recently but when I searched the RC site, I couldn’t find my code.  I finally realized I had coded it not for RC, but for Project Euler.  I located my code then, and sure enough, it used linear search.  The graph for that problem was an 80×80 grid and my program gave the answer (the minimal path from corner to corner) in 13ms.  My comments included a note that I wanted to use container/heap but had problems.  Now with a higher Go-Fu belt, I went back and added the heap optimization.  New run time?  13ms.  In the Go-Nuts thread, a 10k x 10k grid was cited.  Maybe then it would matter.  Not for 80×80 though, and certainly not for 8×11 or whatever one cares to show for the RC task.

Um, so, speaking of Project Euler, sorry for spamming people with password protected blog posts.  No one complained, but someone probably should have.  Anyway, I moved them to a separate wordpress.com blog, linked to at the top of this one.  My Dijkstra code was done for problem 83, now at (still password protected) http://gopeuler.wordpress.com/2011/09/20/pe-83/


by Sonia at September 22, 2011 11:24 PM

September 19, 2011

Adam Langley

DNSSEC Certificates now in Chrome Stable

A few months back I described DNSSEC authenticated HTTPS in Chrome. This allows sites to use DNSSEC, rather than traditional, certificates and is aimed at sites which currently use no HTTPS, or self-signed certificates. Since Chrome 14 is now stable, all Chrome users now have this experimental feature.

(Also, the serialisation format has been documented.)

September 19, 2011 07:00 AM

September 18, 2011

Command Center

User experience

[We open in a well-lit corporate conference room. A meeting has been running for a while. Lots has been accomplished but time is running out.]

[The door opens and a tall, tow-headed twenty-something guy in glasses walks in, carrying a Mac Air and a folder.]

Manager:
Oh, here he is. This is Richard. I asked him to join us today. Glad he could make it. He's got some great user experience ideas.

Richard:
Call me Dick.

Manager:
Dick's done a lot of seminal UX work for us.

Engineer:
Hey, aren't you the guy who's arguing we shouldn't have search in e-books?

Dick:
Absolutely. It's a lousy idea.

Engineer:
What?

Dick:
Books are the best UI ever created. They've been perfected over more than 500 years of development. We shouldn't mess with success.

Product manager:
Well, this is a new age. We should be allowed to ...

Dick:
Books have never had search. If we add search, we'll just confuse the user.

Product manager:
Oh, you're right. We don't want to do that.

Engineer:
But e-books aren't physical books. They're not words on paper. They're just bits, information.

Dick:
Our users don't know that.

Engineer:
Yes they do! They don't want simple books, they want the possibilities that electronic books can bring. Do you know about information theory? Have you even heard of Claude Shannon?

Dick:
Isn't he the chef at that new biodynamic tofu restaurant in North Beach?

Engineer:
Uhh, yeah, OK. But look, you're treating books as a metaphor for your user interface. That's as lame as using a trash can to throw away files and folders. We can do so much more!

Dick:
You misunderstand. Our goal is to make computers easier to use, not to make them more useful.

Product manager:
Wow, that's good.

Engineer:
Wow.

Manager:
Let's get back on track. Dick, you had some suggestions for us?

Dick:
Yeah. I was thinking about the work we did with the Notes iPhone app. Using a font that looked like a felt marker was a big help for users.

Engineer:
Seriously?

Dick:
Yes, it made users feel more comfortable about keeping notes on their phone. Having a font that looks like handwriting helps them forget there's a computer underneath.

Engineer:
I see....

Dick:
Yes, so... I was thinking for the Address Book app for Lion, we should change the look to be like a...

Manager:
Can you show us?

Dick:
Yeah, sure. I have a mock-up here.
[Opens laptop, turns it to face the room.]

Product manager:
An address book! That's fantastic. Look at the detail! Leather, seams at the corners, a visible spine. This is awesome!

Engineer:
It's just a book. It's a throwback. What are you doing? Why does it need to look like a physical address book?

Dick:
Because it is an address book!

Engineer:
No it's not, it's an app!

Dick:
It's a book.

Engineer:
You've made it one. This time it's not even a metaphor - it's literally a book. You're giving up on the possibility of doing more.

Dick:
As I said, users don't care about functionality. They want comfort and familiarity. An Address Book app that looks like an address book will be welcome. Soothing.

Engineer:
If they want a paper address book, they can buy one.

Dick:
Why would they do that if they have one on their desktop?

Engineer:
Can they at least change the appearance? Is there a setting somewhere?

Dick:
Oh, no. We know better than the user - otherwise why are we here? Settings are just confusing.

Engineer:
I ... I really don't understand what's going on.

Manager:
That's OK, you don't have to, but I'd like to give you the action item to build it. End of the quarter OK?

Engineer:
Uhhh, sure.

Manager.
Dick, do you have the requirements doc there?

Dick:
Right here.
[Pushes the folder across the desk.]

Engineer:
Can't you just mail it to me?

Dick:
It's right there.

Engineer:
I know, but... OK.

Manager:
That's a great start, Dick. What else do you have?

Dick:
Well, actually, maybe this is the time to announce that I'm moving on. Today is my last day here.

Manager, Product manager:
[Unison] Oh no!

Dick:
Yeah, sorry about that. I've had an amazing time here changing the world but it's tiem for me to seek new challenges.

Manager:
Do you have something in mind?

Dick:
Yes, I'm moving north. Microsoft has asked me to head a group there. They've got some amazing new ideas around paper clips.

FADE

by rob (noreply@blogger.com) at September 18, 2011 10:27 PM

September 17, 2011

Airs – Ian Lance Taylor

Sudoku

I’ve been playing Sudoku on Google+. i’ve more or less mastered the easy and medium levels, but it takes me about 30 minutes to do a hard level, and I haven’t tried expert yet. Sudoku is a fairly dumb game in some ways; as a colleague of mine pointed out, it’s trivial to write a computer program which will win every time. But I find the game somewhat interesting because it mirrors, in reverse, the way I think about programming.

You can write a computer program more or less any way you like. So I tend to think of a program in terms of constraints. Typical constraints are: the desired behaviour; the available runtime; the algorithmic complexity; the available libraries; the language; maintainability; who is going to review the code and what they will accept. Write a program is a matter of finding the simplest solution which meets the constraints. Difficult programming problems are ones where the constraints come into conflict, and it’s hard to see your way through.

Sudoku works the same way, only in reverse. In programming you are allowed to write any code that meets the constraints. In Sudoku you know that there is only one solution, so you have to look for moves that are forced by the constraints. Solving a Sudoku puzzle is a matter of looking deeper and deeper into the problem until you have eliminated all moves but one.

My hope is that practice in this area will subconsciously encourage me to look deeper for constraints when writing code, which will save time in the long run because I will have to throw away less code. I doubt this will actually work, but it seems worth a try.

Also Sudoku is a good way to exercise short term memory, as I’m avoiding writing anything down while solving the puzzle. I used to play cards regularly (bridge, whist) and I was able to remember the location of many of the cards in other people’s hands. I noticed that I lost that facility as I’ve failed to practice it. As i write this I realize that short term memory is not too important in today’s world, but at least it makes me feel smarter.


by Ian Lance Taylor at September 17, 2011 01:27 AM

September 15, 2011

jra's thoughts

Testing Go’s HTTP server for CVE-2011-3192 vulnerability

The recent DoS attack on Apache is caused by sending in a malformed Range header. I decided to send the same header into Go’s range header parser and see what happened. It passed with flying colors, giving the “invalid range” error, which would result in the Go webserver sending back HTTP response code 416 to the HTTP client.

I didn’t test this under load (which is part of what the DoS was doing), but my quick reading of parseRange leads me to believe that the only effect of sending Range headers in like this is that garbage is created under control of the attacker (for example, due to strings.Split(s[len(b):], “,”)). Of course, that’s bad and should be limited. However, this risk is no greater than other places in the server. For example an attacker could send an unlimited number of headers, or headers of unlimited length. This is already mentioned in the net/textproto package’s reader.go.

I did notice something strange while looking into this, which is that there’s a constant named maxHeaderLines (1024) that is never referenced. This is probably because the (incorrectly non-plurally-named) textproto.ReadMIMEHeader is now in charge of reading all the headers, but it does not accept a max headers parameter.

The fact that this particular constructed header causes no problem is no great surprise, because this attack was highly targeted at Apache. But it is nice to see that Go’s webserver is already (somewhat) hardened against this type of attack.

PS: Here’s a diff showing how I tested this. It might be interesting for beginner Go folks to see how to generate test data at test time.

diff --git a/src/pkg/http/range_test.go b/src/pkg/http/range_test.go
--- a/src/pkg/http/range_test.go
+++ b/src/pkg/http/range_test.go
@@ -6,13 +6,16 @@

 import (
 	"testing"
+	"fmt"
 )

-var ParseRangeTests = []struct {
+type testDef struct {
 	s      string
 	length int64
 	r      []httpRange
-}{
+}
+
+var ParseRangeTests = []testDef{
 	{"", 0, nil},
 	{"foo", 0, nil},
 	{"bytes=", 0, nil},
@@ -34,6 +37,16 @@
 	{"bytes=500-700,601-999", 10000, []httpRange{{500, 201}, {601, 399}}},
 }

+func init() {
+  var p string
+  for k:=0 ; k<1300 ; k++ {
+	p += ",5-"
+	p += fmt.Sprintf("%d", k)
+  }
+  x := "bytes=0-" + p
+  ParseRangeTests = append(ParseRangeTests, testDef{ x, 10, []httpRange{} })
+}
+
 func TestParseRange(t *testing.T) {
 	for _, test := range ParseRangeTests {
 		r := test.r

As set up right now, it won’t pass. This is because I wanted to see the exact error it was returning. If you change the []httpRange{} to nil, it will pass.

PPS: Looks like someone else has been thinking about this as well.

by jra at September 15, 2011 07:53 AM

September 07, 2011

golang.jp

翻訳更新のお知らせ

いくつか日本語訳を更新しました。

by noboru at September 07, 2011 08:59 AM

Adam Langley

Why not Convergence?

In light of recent events, I've had several requests to implement Convergence in Chrome. For those who don't know and, frankly, for anyone interested in SSL, I highly recommend watching Moxie's talk on the subject from this year's Black Hat. You can also check out the project website.

Moxie, having actually thought about the issue and coded something up, has already done a thousand times more to address the problem than almost anyone else. But I don't think that Convergence is something we would add in Chrome:

Although the idea of trust agility is great, 99.99% of Chrome users would never change the default settings. (The percentage is not an exaggeration.) Indeed, I don't believe that an option for setting custom notaries would even meet the standards for inclusion in the preferences UI.

Given that essentially the whole population of Chrome users would use the default notary settings, those notaries will get a large amount of traffic. Also, we have a very strong interest for the notaries to function, otherwise Chrome stops working. Combined, that means that Google would end up running the notaries. So the design boils down to Chrome phoning home for certificate validation. That has both unacceptable privacy implications and very high uptime requirements on the notary service.

It also doesn't address the two problems that Moxie highlights: internal servers and captive portals. It's not clear how either would work in this design, at least without giving up on security and asking the user. (These two problems, captive portals esp, are the bane of many an idea in this area.)

None of the above argues against allowing Convergence as an extension for those who wish to run it. We don't currently have an extension API for controlling certificate decisions and I'm not inherently opposed to one. It would be additional complexity and something that we would have to support in the future, so it's not without costs, but mostly it's not there because nobody has written it and I'm afraid that I don't have any plans to do so.

September 07, 2011 07:00 AM

September 06, 2011

Go's official blog

Go for App Engine is now generally available

The Go and App Engine teams are excited to announce that the Go runtime for App Engine is now generally available. This means you can take that Go app you've been working on (or meaning to work on) and deploy it to App Engine right now with the new 1.5.2 SDK.

Since we announced the Go runtime at Google I/O we have continued to improve and extend Go support for the App Engine APIs and have added the Channels API. The Go Datastore API now supports transactions and ancestor queries, too. See the Go App Engine documentation for all the details.

For those who have been using the Go SDK already, please note that the 1.5.2 release introduces api_version 2. This is because the new SDK is based on Go release.r58.1 (the current stable version of Go) and is not backwards compatible with the previous release. Existing apps may require changes as per the r58 release notes. Once you've updated your code, you should redeploy your app with the line 'api_version: 2' in its app.yaml file. Apps written against api_version 1 will stop working after the 18th of August.

Finally, we owe a huge thanks to our trusted testers and their many bug reports. Their help was invaluable in reaching this important milestone.

The fastest way to get started with Go on App Engine is with the Getting Started guide.

Note that the Go runtime is still considered experimental; it is not as well-supported as the Python and Java runtimes.

by Andrew Gerrand (noreply@blogger.com) at September 06, 2011 11:53 PM

"First Class Functions in Go" and new Go course notes

We would like to announce some new and revised Go learning materials.

Programmers new to Go are often surprised by its support for function types, functions as values, and closures. The First Class Functions in Go code walk demonstrates these features with a simulation of the dice game Pig. It is a pretty program that uses the language to great effect, and a fun read for Go beginners and veterans alike.

The Go course is a three part series that describes the language in detail, including the basic syntax, type system, and concurrency primitives. These notes were available at launch in 2009, but since then the language has changed a bit and the course notes had become an outdated and unreliable resource. We recently revised all three slide decks in their entirety, updating them to match contemporary Go syntax and semantics. The course is ideal for those who want to get the full picture and a great resource for teaching the language to others.

These resources and many more are available at golang.org.

by Andrew Gerrand (noreply@blogger.com) at September 06, 2011 11:42 PM

Profiling Go Programs

At Scala Days 2011 a few weeks ago, Robert Hundt presented a paper titled “Loop Recognition in C++/Java/Go/Scala.” The paper implemented a specific loop finding algorithm, such as you might use in a flow analysis pass of a compiler, in C++, Go, Java, Scala, and then used those programs to draw conclusions about typical performance concerns in these languages. The Go program presented in that paper runs quite slowly, making it an excellent opportunity to demonstrate how to use Go's profiling tools to take a slow program and make it faster.

By using Go's profiling tools to identify and correct specific bottlenecks, we can make the Go loop finding program run an order of magnitude faster and use 6x less memory.

Hundt's paper does not specify which versions of the C++, Go, Java, and Scala tools he used. In this blog post, we will be using the most recent weekly snapshot of the 6g Go compiler and the version of g++ that ships with the Ubuntu Natty distribution. (We will not be using Java or Scala, because we are not skilled at writing efficient programs in either of those languages, so the comparison would be unfair. Since C++ was the fastest language in the paper, the comparisons here with C++ should suffice.)

$ 6g -V
6g version weekly.2011-06-16 8787
$ g++ --version
g++ (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2
...
$

The programs are run on a Lenovo X201s with a 2.13 GHz Core i7-based CPU and 4 GB of RAM running Ubuntu Natty's Linux 2.6.38-8-generic kernel. The machine is running with CPU frequency scaling disabled via

$ sudo bash
# for i in /sys/devices/system/cpu/cpu[0-9]
do
echo performance > $i/cpufreq/scaling_governor
done
#

We've taken Hundt's benchmark programs in C++ and Go, combined each into a single source file, and removed all but one line of output. We'll time the program using Linux's time utility with a format that shows user time, system time, real time, and maximum memory usage:

$ cat xtime
#!/bin/sh
/usr/bin/time -f '%Uu %Ss %er %MkB %C' "$@"
$

$ make havlak1cc
g++ -O3 -o havlak1cc havlak1.cc
$ xtime havlak1cc
# of loops: 76002 (total 3800100)
loop-0, nest: 0, depth: 0
27.37u 0.08s 27.47r 716864kB havlak1cc
$

$ make havlak1
6g havlak1.go
6l -o havlak1 havlak1.6
$ xtime havlak1
# of loops: 76000 (including 1 artificial root node)
56.63u 0.26s 56.92r 1642640kB havlak1
$

The C++ program runs in 27.47 seconds and uses 700 MB of memory. The Go program runs in 56.92 seconds and uses 1604 MB of memory. (These measurements are difficult to reconcile with the ones in the paper, but the point of this post is to explore how to use gopprof, not to reproduce the results from the paper.)

To start tuning the Go program, we have to enable profiling. If the code used the Go testing package's benchmarking support, we could use gotest's standard -cpuprofile and -memprofile flags. In a standalone program like this one, we have to import runtime/pprof and add a few lines of code:

var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")

func main() {
flag.Parse()
if *cpuprofile != "" {
f, err := os.Create(*cpuprofile)
if err != nil {
log.Fatal(err)
}
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
}
...

The new code defines a flag named cpuprofile, calls the Go flag library to parse the command line flags, and then, if the cpuprofile flag has been set on the command line, starts CPU profiling redirected to that file. The profiler requires a final call to StopCPUProfile to flush any pending writes to the file before the program exits; we use defer to make sure this happens as main returns.

After adding that code, we can run the program with the new -cpuprofile flag and then run gopprof to interpret the profile.

$ make havlak1.prof
havlak1 -cpuprofile=havlak1.prof
# of loops: 76000 (including 1 artificial root node)
$ gopprof havlak1 havlak1.prof
Welcome to pprof! For help, type 'help'.
(pprof)

The gopprof program is a slight variant of Google's pprof C++ profiler. The most important command is topN, which shows the top N samples in the profile:

(pprof) top10
Total: 5758 samples
1028 17.9% 17.9% 1161 20.2% hash_lookup
696 12.1% 29.9% 697 12.1% scanblock
565 9.8% 39.8% 1042 18.1% hash_insert_internal
420 7.3% 47.0% 4278 74.3% main.FindLoops
225 3.9% 51.0% 1149 20.0% main.DFS
225 3.9% 54.9% 226 3.9% memhash
198 3.4% 58.3% 437 7.6% sweep
172 3.0% 61.3% 1902 33.0% runtime.mallocgc
102 1.8% 63.1% 500 8.7% runtime.MCache_Alloc
102 1.8% 64.8% 102 1.8% runtime.memmove
(pprof)

When CPU profiling is enabled, the Go program stops about 100 times per second and records a sample consisting of the program counters on the currently executing goroutine's stack. The profile has 5758 samples, so it was running for a bit over 57 seconds. In the gopprof output, there is a row for each function that appeared in a sample. The first two columns show the number of samples in which the function was running (as opposed to waiting for a called function to return), as a raw count and as a percentage of total samples. The hash_lookup function was running during 1028 samples, or 17.9%. The top10 output is sorted by this sample count. The third column shows the running total during the listing: the first three rows account for 39.8% of the samples. The fourth and fifth columns show the number of samples in which the function appeared (either running or waiting for a called function to return). The main.FindLoops function was running in 7.3% of the samples, but it was on the call stack (it or functions it called were running) in 74.3% of the samples.

To sort by the fourth and fifth columns, use the -cum (for cumulative) flag:

(pprof) top5 -cum
Total: 5758 samples
0 0.0% 0.0% 4301 74.7% main.main
0 0.0% 0.0% 4301 74.7% runtime.initdone
0 0.0% 0.0% 4301 74.7% runtime.mainstart
0 0.0% 0.0% 4278 74.3% main.FindHavlakLoops
420 7.3% 7.3% 4278 74.3% main.FindLoops
(pprof)

In fact the total for main.FindLoops and main.main should have been 100%, but each stack sample only includes the bottom 100 stack frames; during about a quarter of the samples, the recursive main.DFS function was more than 100 frames deeper than main.main so the complete trace was truncated.

The stack trace samples contain more interesting data about function call relationships than the text listings can show. The web command writes a graph of the profile data in SVG format and opens it in a web browser. (There is also a gv command that writes PostScript and opens it in Ghostview. For either command, you need graphviz installed.)

(pprof) web

A small fragment of the full graph looks like:



Each box in the graph corresponds to a single function, and the boxes are sized according to the number of samples in which the function was running. An edge from box X to box Y indicates that X calls Y; the number along the edge is the number of times that call appears in a sample. If a call appears multiple times in a single sample, such as during recursive function calls, each appearance counts toward the edge weight. That explains the 69206 on the self-edge from main.DFS to itself.

Just at a glance, we can see that the program spends much of its time in hash operations, which correspond to use of Go's map values. We can tell web to use only samples that include a specific function, such as hash_lookup, which clears some of the noise from the graph:

(pprof) web hash_lookup



If we squint, we can see that the calls to runtime.mapaccess1 are being made by main.FindLoops and main.DFS.

Now that we have a rough idea of the big picture, it's time to zoom in on a particular function. Let's look at main.DFS first, just because it is a shorter function:

(pprof) list DFS
Total: 5758 samples
ROUTINE ====================== main.DFS in /home/rsc/g/benchgraffiti/havlak/havlak1.go
samples 225 Total 2296 (flat / cumulative)
3 3 240: func DFS(currentNode *BasicBlock, nodes []*UnionFindNode, number map[*BasicBlock]int, last []int, current int) int {
18 19 241: nodes[current].Init(currentNode, current)
. 166 242: number[currentNode] = current
. . 243:
2 2 244: lastid := current
167 167 245: for _, target := range currentNode.OutEdges {
17 508 246: if number[target] == unvisited {
10 1157 247: lastid = DFS(target, nodes, number, last, lastid+1)
. . 248: }
. . 249: }
7 273 250: last[number[currentNode]] = lastid
1 1 251: return lastid
. . 252: }
(pprof)

The listing shows the source code for the DFS function (really, for every function matching the regular expression DFS). The first three columns are the number of samples taken while running that line, the number of samples taken while running that line or in code called from that line, and the line number in the file. The related command disasm shows a disassembly of the function instead of a source listing; when there are enough samples this can help you see which instructions are expensive. The weblist command mixes the two modes: it shows a source listing in which clicking a line shows the disassembly.

Since we already know that the time is going into map lookups implemented by the hash runtime functions, we care most about the second column. A large fraction of time is spent in recursive calls to DFS (line 247), as would be expected from a recursive traversal. Excluding the recursion, it looks like the time is going into the accesses to the number map on lines 242, 246, and 250. For that particular lookup, a map is not the most efficient choice. Just as they would be in a compiler, the basic block structures have unique sequence numbers assigned to them. Instead of using a map[*BasicBlock]int we can use a []int, a slice indexed by the block number. There's no reason to use a map when an array or slice will do.

Changing number from a map to a slice requires editing seven lines in the program and cut its run time by nearly a factor of two:

$ make havlak2
6g havlak2.go
6l -o havlak2 havlak2.6
rm havlak2.6
$ xtime havlak2 # diff from havlak1
# of loops: 76000 (including 1 artificial root node)
30.88u 0.24s 31.14r 1564608kB havlak2
$

We can run the profiler again to confirm that main.DFS is no longer a significant part of the run time:

$ make havlak2.prof
havlak2 -cpuprofile=havlak2.prof
# of loops: 76000 (including 1 artificial root node)
$ gopprof havlak2 havlak2.prof
Welcome to pprof! For help, type 'help'.
(pprof) top5
Total: 3099 samples
626 20.2% 20.2% 626 20.2% scanblock
309 10.0% 30.2% 2839 91.6% main.FindLoops
176 5.7% 35.9% 1732 55.9% runtime.mallocgc
173 5.6% 41.4% 397 12.8% sweep
101 3.3% 44.7% 111 3.6% main.DFS
(pprof)

main.DFS still appears in the profile, but its total time has dropped from 20.0% to 3.6%. The rest of the program runtime has dropped too. Now the program is spending most of its time allocating memory and garbage collecting (runtime.mallocgc, which both allocates and runs periodic garbage collections, accounts for 55.9% of the time). To find out why the garbage collector is running so much, we have to find out what is allocating memory. One way is to add memory profiling to the program. We'll arrange that if the -memprofile flag is supplied, the program stops after one iteration of the loop finding, writes a memory profile, and exits:

var memprofile = flag.String("memprofile", "", "write memory profile to this file")
...

FindHavlakLoops(cfgraph, lsgraph)
if *memprofile != "" {
f, err := os.Create(*memprofile)
if err != nil {
log.Fatal(err)
}
pprof.WriteHeapProfile(f)
f.Close()
return
}


We invoke the program with -memprofile flag to write a profile:

$ make havlak3.mprof # diff from havlak2
havlak3 -memprofile=havlak3.mprof
$

We use gopprof exactly the same way. Now the samples we are examining are memory allocations, not clock ticks.

$ gopprof havlak3 havlak3.mprof
Adjusting heap profiles for 1-in-524288 sampling rate
Welcome to pprof! For help, type 'help'.
(pprof) top5
Total: 118.3 MB
66.1 55.8% 55.8% 103.7 87.7% main.FindLoops
30.5 25.8% 81.6% 30.5 25.8% main.*LSG·NewLoop
10.0 8.5% 90.1% 10.0 8.5% main.NewBasicBlock
6.5 5.5% 95.6% 6.5 5.5% main.*SimpleLoop·AddNode
2.1 1.7% 97.3% 12.1 10.2% main.*CFG·CreateNode
(pprof)

Gopprof reports that FindLoops has allocated approximately 66.1 of the 118.3 MB in use; NewLoop accounts for another 30.5 MB. To reduce overhead, the memory profiler only records information for approximately one block per half megabyte allocated (the “1-in-524288 sampling rate”), so these are approximations to the actual counts.

To find the memory allocations, we can list those functions.

(pprof) list FindLoops
Total: 118.3 MB
ROUTINE ====================== main.FindLoops in /home/rsc/g/benchgraffiti/havlak/havlak3.go
MB 66.1 Total 103.7 (flat / cumulative)
...
. . 267:
1.9 1.9 268: nonBackPreds := make([]map[int]bool, size)
3.8 3.8 269: backPreds := make([][]int, size)
. . 270:
1.0 1.0 271: number := make([]int, size)
1.0 1.0 272: header := make([]int, size, size)
1.0 1.0 273: types := make([]int, size, size)
1.0 1.0 274: last := make([]int, size, size)
1.9 1.9 275: nodes := make([]*UnionFindNode, size, size)
. . 276:
. . 277: for i := 0; i < size; i++ {
5.5 5.5 278: nodes[i] = new(UnionFindNode)
. . 279: }
...
. . 286: for i, bb := range cfgraph.Blocks {
. . 287: number[bb.Name] = unvisited
48.0 48.0 288: nonBackPreds[i] = make(map[int]bool)
. . 289: }
...
(pprof) list NewLoop
Total: 118.3 MB
ROUTINE ====================== main.*LSG·NewLoop in /home/rsc/g/benchgraffiti/havlak/havlak3.go
. . 578: func (lsg *LSG) NewLoop() *SimpleLoop {
2.5 2.5 579: loop := new(SimpleLoop)
7.5 7.5 580: loop.basicBlocks = make(map[*BasicBlock]bool)
20.5 20.5 581: loop.Children = make(map[*SimpleLoop]bool)
...
. . 588: }
(pprof)

It looks like the current bottleneck is the same as the last one: using maps where simpler data structures suffice. FindLoops is allocating about 48 MB of maps, and NewLoop is allocating another 20 MB.

As an aside, if we run gopprof with the --inuse_objects flag, it will report allocation counts instead of sizes:


$ gopprof --inuse_objects havlak3 havlak3.mprof
Adjusting heap profiles for 1-in-524288 sampling rate
Welcome to pprof! For help, type 'help'.
(pprof) list NewLoop
Total: 1604080 objects
ROUTINE ====================== main.*LSG·NewLoop in /home/rsc/g/benchgraffiti/havlak/havlak3.go
. . 578: func (lsg *LSG) NewLoop() *SimpleLoop {
54613 54613 579: loop := new(SimpleLoop)
75678 75678 580: loop.basicBlocks = make(map[*BasicBlock]bool)
207530 207530 581: loop.Children = make(map[*SimpleLoop]bool)
...
. . 588: }
(pprof)

Since the 200,000 maps account for 20 MB, it looks like the initial map allocation takes about 100 bytes. That's reasonable when a map is being used to hold key-value pairs, but not when a map is being used as a stand-in for a simple set, as it is here.

Instead of using a map, we can use a simple slice to list the elements. In all but one of the cases where maps are being used, it is impossible for the algorithm to insert a duplicate element. In the one remaining case, we can write a simple variant of the append built-in function:

func appendUnique(a []int, x int) []int {
for _, y := range a {
if x == y {
return a
}
}
return append(a, x)
}

In addition to writing that function, changing the Go program to use slices instead of maps requires changing just a few lines of code.


$ xtime havlak4 # diff from havlak3
# of loops: 76000 (including 1 artificial root node)
18.35u 0.11s 18.48r 575792kB havlak4
$

We're now at 3x faster than when we started. Let's look at a CPU profile again.


$ gopprof havlak4 havlak4.prof
Welcome to pprof! For help, type 'help'.
(pprof) top10
Total: 1851 samples
283 15.3% 15.3% 283 15.3% scanblock
233 12.6% 27.9% 1622 87.6% main.FindLoops
142 7.7% 35.5% 1054 56.9% runtime.mallocgc
112 6.1% 41.6% 276 14.9% sweep
111 6.0% 47.6% 115 6.2% main.DFS
85 4.6% 52.2% 661 35.7% runtime.growslice
84 4.5% 56.7% 84 4.5% runtime.memmove
69 3.7% 60.5% 281 15.2% runtime.MCache_Alloc
67 3.6% 64.1% 84 4.5% MCentral_Alloc
67 3.6% 67.7% 93 5.0% MCentral_Free
(pprof)

Now memory allocation and the consequent garbage collection (runtime.mallocgc) accounts for 56.9% of our run time. Another way to look at why the system is garbage collecting is to look at the allocations that are causing the collections, the ones that spend most of the time in mallocgc:


(pprof) web mallocgc



It's hard to tell what's going on in that graph, because there are many nodes with small sample numbers obscuring the big ones. We can tell gopprof to ignore nodes that don't account for at least 10% of the samples:


$ gopprof --nodefraction=0.1 6.out prof
Welcome to pprof! For help, type 'help'.
(pprof) web mallocgc



We can follow the thick arrows easily now, to see that FindLoops is triggering most of the garbage collection. If we list FindLoops we can see that much of it is right at the beginning:


(pprof) list FindLoops
. . 270: func FindLoops(cfgraph *CFG, lsgraph *LSG) {
. . 271: if cfgraph.Start == nil {
. . 272: return
. . 273: }
. . 274:
. . 275: size := cfgraph.NumNodes()
. . 276:
. 17 277: nonBackPreds := make([][]int, size)
. 82 278: backPreds := make([][]int, size)
. . 279:
. 2 280: number := make([]int, size)
. 1 281: header := make([]int, size, size)
. 61 282: types := make([]int, size, size)
. . 283: last := make([]int, size, size)
. 58 284: nodes := make([]*UnionFindNode, size, size)
. . 285:
2 2 286: for i := 0; i < size; i++ {
. 261 287: nodes[i] = new(UnionFindNode)
. . 288: }
...
(pprof)

Every time FindLoops is called, it allocates some sizable bookkeeping structures. Since the benchmark calls FindLoops 50 times, these add up to a significant amount of garbage, so a significant amount of work for the garbage collector.

Having a garbage-collected language doesn't mean you can ignore memory allocation issues. In this case, a simple solution is to introduce a cache so that each call to FindLoops reuses the previous call's storage when possible. (In fact, in Hundt's paper, he explains that the Java program needed just this change to get anything like reasonable performance, but he did not make the same change in the other garbage-collected implementations.)

We'll add a global cache structure:

var cache struct {
size int
nonBackPreds [][]int
backPreds [][]int
number []int
header []int
types []int
last []int
nodes []*UnionFindNode
}

and then have FindLoops consult it as a replacement for allocation:



if cache.size < size {
cache.size = size
cache.nonBackPreds = make([][]int, size)
cache.backPreds = make([][]int, size)
cache.number = make([]int, size)
cache.header = make([]int, size)
cache.types = make([]int, size)
cache.last = make([]int, size)
cache.nodes = make([]*UnionFindNode, size)
for i := range cache.nodes {
cache.nodes[i] = new(UnionFindNode)
}
}

nonBackPreds := cache.nonBackPreds[:size]
for i := range nonBackPreds {
nonBackPreds[i] = nonBackPreds[i][:0]
}
backPreds := cache.backPreds[:size]
for i := range nonBackPreds {
backPreds[i] = backPreds[i][:0]
}
number := cache.number[:size]
header := cache.header[:size]
types := cache.types[:size]
last := cache.last[:size]
nodes := cache.nodes[:size]

Such a global variable is bad engineering practice, of course: it means that concurrent calls to FindLoops are now unsafe. For now, we are making the minimal possible changes in order to understand what is important for the performance of our program; this change is simple and mirrors the code in the Java implementation. The final version of the Go program will use a separate LoopFinder instance to track this memory, restoring the possibility of concurrent use.

$ xtime havlak5 # diff from havlak4
# of loops: 76000 (including 1 artificial root node)
12.59u 0.07s 12.67r 584496kB havlak5
$

There's more we can do to clean up the program and make it faster, but none of it requires profiling techniques that we haven't already shown. The work list used in the inner loop can be reused across iterations and across calls to FindLoops, and it can be combined with the separate “node pool” generated during that pass. Similarly, the loop graph storage can be reused on each iteration instead of reallocated. In addition to these performance changes, the final version is written using idiomatic Go style, using data structures and methods. The stylistic changes have only a minor effect on the run time: the algorithm and constraints are unchanged.

The final version runs in 3.84 seconds and uses 257 MB of memory:

$ xtime havlak6
# of loops: 76000 (including 1 artificial root node)
3.79u 0.04s 3.84r 263472kB havlak6
$

That's nearly 15 times faster than the program we started with. Even if we disable reuse of the generated loop graph, so that the only cached memory is the loop finding bookeeping, the program still runs 10x faster than the original and uses 2.5x less memory.

$ xtime havlak6 -reuseloopgraph=false
# of loops: 76000 (including 1 artificial root node)
5.74u 0.10s 5.84r 617040kB havlak6 -reuseloopgraph=false
$

Of course, it's no longer fair to compare this Go program to the original C++ program, which used inefficient data structures like sets where vectors would be more appropriate. As a sanity check, we translated the final Go program into equivalent C++ code. Its execution time is similar to the Go program's:

$ xtime havlak6cc
# of loops: 76000 (including 1 artificial root node)
4.04u 0.38s 4.42r 387744kB havlak6cc
$

The Go program runs slightly faster because the C++ program is using automatic deletes and allocation instead of an explicit cache. That makes the C++ program a bit shorter and easier to write, but not dramatically so:

$ wc havlak6.cc; wc havlak6.go
401 1220 9040 havlak6.cc
461 1441 9467 havlak6.go
$

Benchmarks are only as good as the programs they measure. We used gopprof to study an inefficient Go program and then to improve its performance by an order of magnitude and to reduce its memory usage by a factor of six. A subsequent comparison with an equivalently optimized C++ program shows that Go can be competitive with C++ when programmers are careful about how much garbage is generated by inner loops.

The program sources, Linux x86-64 binaries, and profiles used to write this post are available in the benchgraffiti project on Google Code.

As mentioned above, gotest includes these profiling flags already: define a benchmark function and you're all set. There is also a standard HTTP interface to profiling data. In an HTTP server, adding

import _ "http/pprof"

will install handlers for a few URLs under /debug/pprof/. Then you can run gopprof with a single argument—the URL to your server's profiling data—and it will download and examine a live profile.

gopprof http://localhost:6060/debug/pprof/profile # 30-second CPU profile
gopprof http://localhost:6060/debug/pprof/heap # heap profile

- Russ Cox

by rsc (noreply@blogger.com) at September 06, 2011 11:42 PM

Spotlight on external Go libraries

While the Go authors have been working hard at improving Go's standard library, the greater community has created a growing ecosystem of external libraries. In this post we look at some popular Go libraries and how they can be used.

Mgo (pronounced "mango") is a MongoDB database driver. MongoDB is a document-oriented database with a long list of features suitable for a broad range of uses. The mgo package provides a rich, idiomatic Go API for working with MongoDB, from basic operations such as inserting and updating records to the more advanced MapReduce and GridFS features. Mgo has a bunch of cool features including automated cluster discovery and result pre-fetching - see the mgo homepage for details and example code. For working with large data sets Go, MongoDB, and mgo are a powerful combination.

Authcookie is a web library for generating and verifying user authentication cookies. It allows web servers to hand out cryptographically secure tokens tied to a specific user that will expire after a specified time period. It has a simple API that makes it straightforward to add authentication to existing web applications. See the README file for details and example code.

Go-charset provides support for converting between Go's standard UTF-8 encoding and a variety of character sets. The go-charset package implements a translating io.Reader and io.Writer so you can wrap existing Readers and Writers (such as network connections or file descriptors), making it easy to communicate with systems that use other character encodings.

Go-socket.io is a Go implementation of Socket.IO, a client/server API that allows web servers to push messages to web browsers. Depending on the capabilities of the user's browser, Socket.IO uses the best transport for the connection, be it modern websockets, AJAX long polling, or some other mechanism. Go-socket.io bridges the gap between Go servers and rich JavaScript clients for a wide range of browsers. To get a feel for go-socket.io see the chat server example.

It's worth mentioning that these packages are goinstallable. With an up-to-date Go installation you can install them all with a single command:
 
goinstall launchpad.net/mgo \
github.com/dchest/authcookie \
go-charset.googlecode.com/hg/charset \
github.com/madari/go-socket.io

Once goinstalled, the packages can be imported using those same paths:
 
import (
"launchpad.net/mgo"
"github.com/dchest/authcookie"
"go-charset.googlecode.com/hg/charset"
"github.com/madari/go-socket.io"
)

Also, as they are now a part of the local Go system, we can inspect their documentation with godoc:
 
godoc launchpad.net/mgo Database # get docs for the Database type

Of course, this is just the tip of the iceberg; there are more great Go libraries listed on the package dashboard and many more to come.

by Andrew Gerrand (noreply@blogger.com) at September 06, 2011 11:42 PM

Two Go Talks: "Lexical Scanning in Go" and "Cuddle: an App Engine Demo"

On Tuesday night Rob Pike and Andrew Gerrand each presented at the Sydney Google Technology User Group.

Rob's talk, "Lexical Scanning in Go", discusses the design of a particularly interesting and idiomatic piece of Go code, the lexer component of the new template package.

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="345" src="http://www.youtube.com/embed/HxaD_trXwRE" width="560"></iframe>

The slides are available here. The new template package is available as exp/template in Go release r59. In a future release it will replace the old template package.

Andrew's talk, "Cuddle: an App Engine Demo", describes the construction of a simple real-time chat application that uses App Engine's Datastore, Channel, and Memcache APIs. It also includes a question and answer session that covers Go for App Engine and Go more generally.

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="345" src="http://www.youtube.com/embed/HQtLRqqB-Kk" width="560"></iframe>

The slides are available here. The code is available at the cuddle Google Code project.

by Andrew Gerrand (noreply@blogger.com) at September 06, 2011 11:41 PM

September 05, 2011

Sonia Codes

Protected: PE 60

This post is password protected. You must visit the website and enter the password to continue reading.


by Sonia at September 05, 2011 12:33 AM

September 04, 2011

Sonia Codes

Protected: PE 42

This post is password protected. You must visit the website and enter the password to continue reading.


by Sonia at September 04, 2011 10:20 PM

September 01, 2011

RSC

_rsc: @kurrik See also goinstall goauth2.googlecode.com/hg/oauth

_rsc: @kurrik See also goinstall goauth2.googlecode.com/hg/oauth

September 01, 2011 03:23 PM

August 31, 2011

codegrunt.co.uk

Turning 30

I’ve not updated this for an age. I have been going through something of a mini-crisis/case of burnout, somewhat related to the fact I’m turning 30 tomorrow. Scary times!

August 31, 2011 11:00 PM

Adam Langley

False Start: past time to fix your servers

A year ago I wrote about False Start in Chrome. In short: Chrome cuts the TLS handshake short to save a round trip in a full handshake. Since then we've posted results that show a 30% drop in SSL handshake latency.

When we enabled False Start by default in Chrome, we also included a list of the very small number of incompatible sites. This list was built into the browser in order to avoid breaking these sites. (See the original post for the reasoning.)

For some time I've been randomly eliminating chunks of that list. Mostly it's been the case that sites have already upgraded. I don't think that they did so specifically with False Start in mind, but that it was just a regular maintainance.

But it's now time that all sites are updated because the list is fading away fast:

  • If you run A10 SSL terminators, ensure that you have firmware >= 2.4.3-p4
  • If you run Brocade SSL terminators, ensure that you have firmware >= 10.2.01y
  • If you run F5 SSL terminators, you need to be running the native SSL stack (which is the default, as opposed to the `compat' stack)
  • If you run FTMG SSL terminators, you need Service Pack 2

August 31, 2011 07:00 AM

August 28, 2011

Miek Gieben

Learning Go for E-readers

Thanks to a patch from Thomas Kappler I can now offer two types of PDFs, one for A4 pages and one for E-readers, like the kindle.

The E-reader variant is suffixed with -kindle:

by Miek Gieben at August 28, 2011 07:45 PM

August 26, 2011

Airs – Ian Lance Taylor

Pay Voting

New plan: let’s let people pay to vote. Everybody gets one vote free, just like today. You can also pay, say, $1000 for another vote, then $2000 for the next one, $3000 for the one after that, etc. Also, you can sell your vote, so a cheaper way to get more votes is to pay a bunch of people $500.

Advantage: it’s no longer necessary to give candidates money so that they can advertise for votes. Currently politicians spend at least half their time asking for money. This would let them spend all their time on their actual job.

Advantage: money paid for votes goes straight to the treasury, rather than to television stations.

Advantage: Many fewer horrible political ads.

Disadvantage: politicians do what rich people want them to do. But wait, that is already the case. So this isn’t a disadvantage at all.

The U.S. is already a plutocracy. Making it explicit is more efficient all around.


by Ian Lance Taylor at August 26, 2011 05:12 AM

August 25, 2011

Going Along

公路惊魂

昨晚睡的还好, 起的是有点早, 忙了整天, 开在高速上很顺, 就有些恍惚. 满脑袋胡思乱想, 就这样突然一大片不知什么东西, 从前面的卡车上掉下来, 擦过一辆摩托, 在路上三翻五滚就冲了过来. 脑子一片空白, 下意识的做了个规避动作, 让那个不知什么的东西从两个前轮间钻过不见了. 车咣当了一下, 看看后视镜, 找找好像没有什么东西甩出去. 正纳闷到底是什么, 前面的摩托骑士频频回头, 才感觉是那什么东西挂在了车下. 赶紧打灯急忙靠路肩停下. 看着侧镜等着一辆辆车飞驰过去了, 才敢下来查看. 一个巨大的沙发靠背, 就这样紧紧的夹在车底, 被拖着磨破了套, 棉絮四溢. 夹的那个紧那怎么也拽不出, 只好动用千斤顶, 汗流浃背满手油污的把车撑起. 好大的一个棉靠背.

突然. 这才刚回过神. 刚才是多么凶险的几秒钟. 如果我不是迎头撞上去, 而是紧急刹车, 或闪到旁边车道, 可能就是连环车祸. 如果不是正好夹在两轮中间, 而是被车轮碾过, 时速100的车很可能会翻. 如果不是棉垫子而是个硬家伙, 如果是砸在前面的摩托上, 如果是其他的如果...... 现在的结果可是意外中的最佳结果, 不幸中的万幸了! 旦夕祸福, 惊魂卜定, 阿弥陀佛.

人说眼一闭不睁一辈子过去了. 那还死得其所睡的安详. 我这可是差点双眼睁睁的就送了命. 如果, 意外, 经历过的, 更珍惜生命了.

by Fango (noreply@blogger.com) at August 25, 2011 02:08 PM

August 23, 2011

Command Center

Regular expressions in lexing and parsing

Comments extracted from a code review. I've been asked to disseminate them more widely.

I should say something about regular expressions in lexing and
parsing. Regular expressions are hard to write, hard to write well,
and can be expensive relative to other technologies. (Even when they
are implemented correctly in N*M time, they have significant
overheads, especially if they must capture the output.)

Lexers, on the other hand, are fairly easy to write correctly (if not
as compactly), and very easy to test. Consider finding alphanumeric
identifiers. It's not too hard to write the regexp (something like
"[a-ZA-Z_][a-ZA-Z_0-9]*"), but really not much harder to write as a
simple loop. The performance of the loop, though, will be much higher
and will involve much less code under the covers. A regular expression
library is a big thing. Using one to parse identifiers is like using a
Ferrari to go to the store for milk.

And when we want to adjust our lexer to admit other character types,
such as Unicode identifiers, and handle normalization, and so on, the
hand-written loop can cope easily but the regexp approach will break
down.

A similar argument applies to parsing. Using regular expressions to
explore the parse state to find the way forward is expensive,
overkill, and error-prone. Standard lexing and parsing techniques are
so easy to write, so general, and so adaptable there's no reason to
use regular expressions. They also result in much faster, safer, and
compact implementations.

Another way to look at it is that lexers and parsing are matching
statically-defined patterns, but regular expressions' strength is that
they provide a way to express patterns dynamically. They're great in
text editors and search tools, but when you know at compile time what
all the things are you're looking for, regular expressions bring far
more generality and flexibility than you need.

Finally, on the point about writing well. Regular expressions are, in
my experience, widely misunderstood and abused. When I do code reviews
involving regular expressions, I fix up a far higher fraction of the
regular expressions in the code than I do regular statements. This is
a sign of misuse: most programmers (no finger pointing here, just
observing a generality) simply don't know what they are or how to use
them correctly.

Encouraging regular expressions as a panacea for all text processing
problems is not only lazy and poor engineering, it also reinforces
their use by people who shouldn't be using them at all.

So don't write lexers and parsers with regular expressions as the
starting point. Your code will be faster, cleaner, and much easier to
understand and to maintain.

by rob (noreply@blogger.com) at August 23, 2011 02:38 AM

August 22, 2011

Andrew Gerrand

PyconAU, Go, and a bit of l'esprit de l'escalier

Yesterday I went to Pycon Australia in Sydney. It was a great conference; well-organized, great speakers, and a fun crowd. I used to write a lot of Python code professionally, so it was both interesting and rewarding for me to get back in touch with the Python community.

I signed up for one of the lightning talk slots at the end of the day, with the contentious title “Love Python? Try Go!” When I asked a friend if it was inappropriate to give a talk about Go at a Python conference, he replied “Giving your talk without pants on is inappropriate. Talking about Go is just obscene!” Undeterred, I prepared and delivered my talk anyway (see the slides).

The talk was surprisingly well-received (I didn’t get booed off the stage). There was the requisite heckling from my friends and colleagues in the front row, but when they judged each of the talks by applause I got a reasonable showing (I expected stony silence).

My talk sparked a number of conversations at the pub afterwards. Were I to do the talk again there are some things I would have done differently:

  • I wouldn’t make such a big deal about static typing.

It turns out that Python programmers like dynamic typing. A lot. Python’s run time typing errors just don’t seem to be a big deal to most Python programmers.

This surprised me, because my number one peeve with dynamic languages is how fragile the code feels. In Go, I can fearlessly refactor code with the confidence that most silly mistakes will be caught by the compiler. I have never had the same confidence when writing Python code.

One counter-argument is that good tests will catch those same kinds of errors. This is true to some extent, but I contend that static type checking saves time during develpoment, too. Unless you write your tests up front (I don’t) you won’t get that important benefit in a dynamic language.

But I digress. The “static vs dynamic typing” discussion is deep and subtle, which makes it a poor choice for a 5-minute lightning talk. I should have left it out.

  • I would have somebody thoroughly proofread my slides.

On the slide about fast compilation I stated that “Typical programs build in <1 second,” except I used a greater-than sign by mistake. That got a laugh, at least, even if I didn’t know why at the time.

  • I would make the point that programming languages are not a religion and that language choice is not a zero-sum game.

Learning a new programming language does not mean you forget the other ones; it just makes you a better programmer by giving you more options and experience.

The intent of my talk was not to coax programmers away from Python to Go. I wanted to tell people about Go and show that it offers some real benefits over other languages for some tasks. While I personally prefer to use Go over other languages for pretty much anything, I certainly don’t expect that everyone should feel the same. I’m not a Go zealot (or a troll), and I hope I didn’t come across that way. :–)

Software systems are mostly heterogeneous, particularly in the web world. For example, Python programs consist of a lot of C code, and most Python web apps are deployed behind a web server written in C. Were I giving the talk again, I would focus on the benefits of adding Go to your software development toolset, and give some real examples of systems that use both Python and Go.

So, in conclusion, if you’re a Pythonista with the need for speed and/or concurrency – or you’re just interested in learning something quite different and new – I (once more) encourage you to try Go. It may not replace Python in your day-to-day life but – like any new tool – it might just make your life easier.

Good starting points are my Real World Go talk and the Go documentation. And, if you’re in Sydney, come along to the Sydney GTUG on Tuesday the 30th of August where Rob Pike and I will be giving a couple of Go presentations.

Permalink | Leave a comment  »

August 22, 2011 12:54 AM

August 19, 2011

RSC

_rsc: RT @dylanbeattie: The 11 in C++11 refers to the number of legs that have now been nailed onto the dog whilst attempting to build a bette ...

_rsc: RT @dylanbeattie: The 11 in C++11 refers to the number of legs that have now been nailed onto the dog whilst attempting to build a bette ...

August 19, 2011 02:49 AM

_rsc: @__nil works great with sshfs. On a mac see macfuse

_rsc: @__nil works great with sshfs. On a mac see macfuse

August 19, 2011 02:47 AM

August 15, 2011

Journal

How to parse command line arguments in Go

Your Go program can easily grab command line arguments. 

Let's say your program prints a person's name that gets passed into the program as a command line argument.

<script src="https://gist.github.com/1145626.js?file=gistfile1.go"></script>

To make this happen, you need to import the "flag" package. Next you need to declare a variable that you will store the flag's value in.

I chose to declare a string variable called "value" for this purpose.

With a variable set, use the flag.StringVar(...) function to set the value (assuming the value you wish to parse is a string). Your other option is to use the flag.IntVar(...) function to bind an integer variable with an integer command line argument.

Note that the flag.StringVar function accepts a reference to a string variable, not a pointer. This reference is used internally by the flag package. Also, not that if you don't specify a command line flag, this function sets one up for you with the default name "The Dude".

Finally, execute flag's Parse() function, and either the flag passed in from the command line, or a default flag will be ready for use.

by Charles Thompson at August 15, 2011 02:59 AM

August 13, 2011

golang.jp

「Goプログラミング言語仕様」翻訳更新のお知らせ

Goプログラミング言語仕様」の翻訳を更新しました。
バージョンは、June 17, 2011です。

あまり大きな変更はありませんんが、変更点です。

  • gotoの制約が変更され、ブロック外からブロック内へのジャンプができなくなった
  • nilチャネルからの送受信信は、永久にブロックされるようになった。
    ただし、コンパイラはまだ未対応で、ブロックされずにパニックが発生
  • nilマップは、要素が追加できない以外は空のマップと同じ扱いになった。
    これもコンパイラはまだ未対応。

by noboru at August 13, 2011 01:20 AM

August 12, 2011

Miek Gieben

VIM setup

After several years I decided to use a different color scheme for VIM. Also I'm going for force myself to use VIM's folding abilities and use make from within VIM.

For good measure I also want to use Omni-completion when writing Go code:

omni completion screenshot

Btw, this screenshots also shows the solarized (dark) colorscheme.

Coloring

Google for solarized. In my .vimrc:

let g:solarized_termcolors=256
colorscheme solarized

Make from VIM

Use :make inside the editor and jump through the errors with:

:cn         // next compile error
:cp         // previous compile error

There are more options, but I want to be able to remember them...

Folding

Settings in .vimrc:

" folding settings
set foldmethod=indent
set foldnestmax=10
set nofoldenable
set foldlevel=0

And the commands that I will probably use most often:

zM          // close all folds
zR          // open all folds

za          // toggle fold under cursor
zA          // toggle fold under cursor recursively

Other important ones:

zo          // open fold under cursor
zO          // open all under cursor recursively

zc          // close fold under cursor
zC          // close all under cursor recursively

Spell checking

Setting in .vimrc:

" toggle spelling control-E -> en, control-N -> dutch (nederlands)                   
map     <C-E>    :setlocal spell! spelllang=en<CR>
imap    <C-E>    <ESC>:setlocal spell! spelllang=en<CR>i
map     <C-N>    :setlocal spell! spelllang=nl<CR>
imap    <C-N>    <ESC>:setlocal spell! spelllang=nl<CR>i

Commands to use (this is the only one I use)

z=          // Show corrections for a word

Toggle switches

Switches for paste-mode, cursorline, numbering disable search highlighting.

set pastetoggle=<F7>

" search hilight
map     <F8>   :nohlsearch<CR>
imap    <F8>   <ESC>:nohlsearch<CR>a
vmap    <F8>   <ESC>:nohlsearch<CR>gv

" numbering
map     <F10>   :set nu!<CR>
imap    <F10>   <ESC>:set nu!<CR>i
vmap    <F10>   <ESC>:set nu!<CR>gv

" toggle cursorline
map     <F9>   :set cursorline!<CR>
imap    <F9>   <ESC>:set cursorline!<CR>

Omni completion (Go specific)

See https://github.com/nsf/gocode. After you've installed that, you can use control-X control-O to bring up the omni completion window. With the VIM files in go/misc/vim you also have the following commands:

    :Fmt                // Gofmt your code
    :Import strings     // add package 'strings' to the import list
    :Drop strings       // drop package 'strings' from the import list

by Miek Gieben at August 12, 2011 08:04 AM

Going Along

Windows with coLinux for Go App Engine SDK


  1. Download coLinux from http://www.colinux.org
  2. Download Ubuntu 9.04 1GB RootFS
  3. Download 7-zip and uncompress Ubuntu-9.04-1gb.7z
  4. Create colinux.bat as "colinux-daemon kernel=vmlinux initrd=initrd.gz root=/dev/cobd0 ro cobd0=Ubuntu-9.04.ext3.1gb.fs eth0=tuptap, run it
  5. Windows should have a Local Area Connection with Device Name (TAP-Win32), this is the tuptap network interface. Now we need to double click the one for Ethernet Adaptor, click 'Properties', then 'Advanced'. Under Internet Connection Sharing (if you have), select the TAP-Win32 above for sharing.
  6. Login: root, Password: root
  7. apt-get update
  8. apt-get install curl unzip
  9. adduser go
  10. sudo - go
  11. curl -o gosdk.zip http://googleappengine.googlecode.com/files/go_appengine_sdk_linux_386-1.5.2.zip
  12. unzip gosdk.zip
  13. cd google_appengine
  14. /sbin/ifconfig eth0, notice inet addr, mine is 192.168.0.88 
  15. ./dev_appserver.py -a 192.168.0.88 demos/go-helloworld/
  16. From windows, browse URL http://192.168.0.88:8080
  17. Optionally, add -d after colinux-daemon in colinux.bat to put it to daemon mode, and use Putty.exe to remote login via SSH




by Fango (noreply@blogger.com) at August 12, 2011 06:01 AM

August 10, 2011

Sonia Codes

Readers Writers

My attention was drawn to the Producer-consumer problem last week reading Allen B. Downey’s The Little Book of Semaphores.  It contains descriptions and solutions of a number of interesting concurrency problems in the form of exercises or what I call “toy” problems.  The second problem posed in the book is the Readers-writers problem.  Like Producer-consumer, it is trivially solved in Go, as Go has a nice RWMutex object in the sync package.  Downey and Wikipedia both describe in detail various solutions with different problems of writer starvation or reader starvation.  I can spare you the pain of working through the examples by just saying that the current Go RWMutex avoids both writer and reader starvation, and better, is wait-free for readers.  It was updated recently by Dmitry Vyukov, who has been making some great contributions to Go recently.  His 1024 cores website and corresponding blog are packed with amazing insights into concurrency.

Here is a little demo program showing the RWMutex in action:

package main

import (
    "log"
    "os"
    "rand"
    "sync"
    "time"
)

// thread safe output
var fmt = log.New(os.Stdout, "", log.Lmicroseconds)

// type representing shared resource.  contents could be anything
type resource struct {
    string
}

// struct wraps pointer to resource with embedded RWMutex, thus
// acquiring RWMutex methods
type access struct {
    sync.RWMutex
    res  *resource
}

func main() {
    acc := &access{res: &resource{"zero"}}
    fmt.Println("Initial value:", acc.res.string)

    gr := new(sync.WaitGroup)
    gr.Add(5) // three readers and two writers
    go reader("A", acc, gr)
    go reader("B", acc, gr)
    go reader("C", acc, gr)
    go writer("X", acc, gr)
    go writer("Y", acc, gr)
    gr.Wait()
    fmt.Println("Final value:", acc.res.string)
}

// reader reads three times at about .1 second intervals, taking
// .02 second to perform the read
func reader(name string, acc *access, gr *sync.WaitGroup) {
    rn := rand.New(rand.NewSource(time.Nanoseconds()))
    for i := 0; i < 3; i++ {
        time.Sleep(8e7 + rn.Int63n(4e7))
        fmt.Println("reader", name, "ready to read")
        acc.RLock()
        fmt.Println("reader", name, "reading")
        time.Sleep(2e7)
        msg := acc.res.string
        acc.RUnlock()
        fmt.Println("reader", name, "read:", msg)
    }
    gr.Done()
}

// writer writes twice
func writer(name string, acc *access, gr *sync.WaitGroup) {
    rn := rand.New(rand.NewSource(time.Nanoseconds()))
    claim := []string{"once", "again"}
    for i := 0; i < 2; i++ {
        time.Sleep(8e7 + rn.Int63n(4e7))
        msg := name + " was here " + claim[i]
        fmt.Println("writer", name, "ready to write")
        acc.Lock()
        fmt.Println("writer", name, "writing:", msg)
        time.Sleep(2e7)
        acc.res.string = msg
        acc.Unlock()
        fmt.Println("writer", name, "done")
    }
    gr.Done()
}

Sample output:

15:48:39.518475 Initial value: zero
15:48:39.610595 reader B ready to read
15:48:39.610617 reader B reading
15:48:39.629587 writer X ready to write
15:48:39.629616 reader C ready to read
15:48:39.630584 reader A ready to read
15:48:39.631582 reader B read: zero
15:48:39.631601 writer X writing: X was here once
15:48:39.639580 writer Y ready to write
15:48:39.652591 writer X done
15:48:39.652609 reader C reading
15:48:39.652618 reader A reading
15:48:39.673577 reader C read: X was here once
15:48:39.673601 writer Y writing: Y was here once
15:48:39.673614 reader A read: X was here once
15:48:39.694576 writer Y done
15:48:39.749585 reader B ready to read
15:48:39.749606 reader B reading
15:48:39.764576 reader A ready to read
15:48:39.764602 reader A reading
15:48:39.767576 writer X ready to write
15:48:39.770575 reader B read: Y was here once
15:48:39.785577 reader A read: Y was here once
15:48:39.785597 writer X writing: X was here again
15:48:39.790576 reader C ready to read
15:48:39.806576 writer X done
15:48:39.806595 reader C reading
15:48:39.809575 writer Y ready to write
15:48:39.827575 reader C read: X was here again
15:48:39.827596 writer Y writing: Y was here again
15:48:39.848572 writer Y done
15:48:39.864573 reader B ready to read
15:48:39.864587 reader B reading
15:48:39.885572 reader B read: Y was here again
15:48:39.887572 reader A ready to read
15:48:39.887588 reader A reading
15:48:39.908572 reader A read: Y was here again
15:48:39.911572 reader C ready to read
15:48:39.911586 reader C reading
15:48:39.932572 reader C read: Y was here again
15:48:39.932593 Final value: Y was here again

by Sonia at August 10, 2011 08:48 PM

August 01, 2011

Miek Gieben

Chaining proxies

Online signing is cool, but slow. Caching queries in a reverse proxy is nice, but useless for something like NSD. But what if you want to do online signing in a fast way?

Enter: proxy chaining.

I already showed FunkenSign (example code is quite old though) and yesterday FunkenShield.

What if you combine the two? That gives the best of both worlds:

  • Online signing;
  • Caching;
  • And it adheres to the true Unix philosophy: do one thing, and do one thing well.

So lets get some figures again.

Nameserver

First start the nameserver:

cd _examples/ns && make
GOMAXPROCS=10 ./ns      # listens on port 8053

Online signing proxy

Next we start our online signing proxy. This proxy only signs answers to questions for c.miek.nl., and leaves other questions alone.

We listen on port 8054 and use the nameserver we started on port 8053:

cd examples/funkensturm && make -f Makefile_sign
# save the exe
cp funkensturm funkensturm_sign
# start it
GOMAXPROCS=10 ./funkensturm_sign -rserver=127.0.0.1:8053 -sserver=127.0.0.1:8054

Reverse proxy

And lastly the reverse proxy. It listens on port 8055 and forwards queries to 8054.

make -f Makefile_rproxy
cp funkensturm funkensturm_rproxy
GOMAXPROCS=10 ./funkensturm_rproxy -rserver=127.0.0.1:8054 -sserver=127.0.0.1:8055

Numbers

So we have:

caching proxy -> signing proxy -> nameserver

And for queryperf we create a data file with three queries:

  1. a.miek.nl A
  2. a.miek.nl AAAA
  3. c.miek.nl A

Where the answer to 3 will include a generated signature.

So lets query the nameserver on port 8053:

./queryperf -d data -s 127.0.0.1 -p 8053 -l 2 
Queries per second:   7298.194728 qps

7000+ qps; a normal number. Next directly query the online signing proxy on port 8054:

./queryperf -d data -s 127.0.0.1 -p 8054 -l 2
Queries per second:   205.991306 qps

205 qps... that's onine signing for you: S L O W.

Next we use the caching proxy which caches the answers, we query on port 8055:

./queryperf -d data -s 127.0.0.1 -p 8055 -l 2
Queries per second:   28521.826761 qps

Thats again more like it.

So we have fast online signing in a clean way.

Note: (excluding godns) the combined line count is 197 lines for ns and 450 for funkensturm.

by Miek Gieben at August 01, 2011 07:38 PM

July 31, 2011

Miek Gieben

Reverse DNS proxy

Have a slow nameserver and want to spice things up? How about a reverse DNS proxy? For lack of a cool name I chose the name FunkenShield. It's (of course) in the early stages, but it works quite nicely already.

This is done with the framework of FunkenSturm. Which is part of GoDNS.

How it works:

You place FunkenShield in front of your nameserver and it will cache the binary packets coming from your server in a local cache.

It is written in Go, and the beauty of it is that Go compiles to static executables, so I can give you (or you can compile it yourself) the exe and you can experiment with it yourself.

Some numbers

GoDNS is a library that helps you create DNS software. In this library some example programs are included, among other, a simple nameserver. Currently this nameserver works with 1 zone, namely "miek.nl". If you run it, it defaults to listening on port 8053:

% ./ns      # start the nameserver

<other terminal>

% dig @127.0.0.1 -p 8053 mx miek.nl
<snip>
;; QUESTION SECTION:
;miek.nl.                       IN      MX

;; ANSWER SECTION:
miek.nl.                345600  IN      MX      20 mail.atoom.net.
miek.nl.                345600  IN      MX      40 mx-ext.tjeb.nl.

;; AUTHORITY SECTION:
<snip>

;; ADDITIONAL SECTION:
miek.nl.                0       IN      TXT     "Proudly served by Go: http://www.golang.org"

So that works. But how fast is it? This queryperf asks two questions: "A a.miek.nl" and "AAAA a.miek.nl":

% ./queryperf -d data -s 127.0.0.1 -p 8053 -l 10
<snip>
Queries per second:   3079.260741 qps

Hmmm, only about 3000. Lets spice things up a bit and utilize Go's multicore features:

% GOMAXPROCS=20 ./ns 
% ./queryperf -d data -s 127.0.0.1 -p 8053 -l 10
Queries per second:   7124.942077 qps

More than doubled. Nice, but still nothing to make NSD afraid.

Enter FunkenShield

We run FunkenShield on port 8054, and allow it to have a multitude of goroutines. Note: "./ns" is still running. If FunkenShield has a cache miss it still needs to ask the nameserver.

% cd _examples/funkensturm && make -f Makefile_rproxy
% GOMAXPROCS=20 ./funkensturm -rserver 127.0.0.1:8053 -sserver 127.0.0.1:8054
% ./queryperf -d data -s 127.0.0.1 -p 8054 -l 10        # port = 8054!
Queries per second:   27506.219188 qps

W00t!

27506 qps.

27000+ qps is not bad for a nameserver.

by Miek Gieben at July 31, 2011 03:09 PM

RSC

_rsc: When open source matters, it really matters. http://t.co/6tDeV0a

_rsc: When open source matters, it really matters. http://t.co/6tDeV0a

July 31, 2011 03:34 AM

July 29, 2011

Airs – Ian Lance Taylor

Voluntary Foreclosure

The otherwise completely forgettable movie Larry Crowne had one scene I found quite interesting. The eponymous protagonist, played by Tom Hanks in his blandest mode, is presented as an all-around good guy. He is gentlemanly, helpful, considerate, and in fact has no flaws except for the rather minor one which starts the little action there is in the movie: he did not go to college. In college he studies, among other things, economics, in a class taught by Lt. Sulu.

Studying economics leads Larry Crowne to the one interesting scene: he abandons his mortgage and returns his house to the bank. The bank representative warns him that this will hurt his credit, but he assures her that it is the right thing for him to do, and that he has the right to do it, provided he vacates the house in 30 days.

The U.S. is a country which famously agreed to pay all its debts when it was founded—the newly created federal government assumed the debts that the various states had accumulated during and before the War of Independence. In general American culture assumes that you are required to pay all your debts. Declaring bankruptcy is a sign of personal failure.

Apparently the financial crisis, and the stagnation of middle class income compared with the increasing price of housing, has now made it acceptable for a mainstream movie character to renege on his debt. This is of course a calculation that businesses make routinely, but not individuals. Admittedly voluntary foreclosure is not quite as bad as bankruptcy. After all, the bank does get the house, which is worth something although it is clearly understood that the bank does not want it.

Given the current main news story, I just have to hope that this acceptance of foreclosure does not carry over to thinking it is OK for the entire country to go into default.


by Ian Lance Taylor at July 29, 2011 02:03 PM

July 19, 2011

Going Along

按下葫芦起了瓢

当老婆怀上小三老四准备请四个月产假时, 她民营企业家老板甩下这么一句:"你老公是做什么的?" 意思是他有三个孩子已经是钱和地位的炫耀了, 一个小小的打工仔凭什么能生这么多?

生则生矣. 天主教反对避孕, 认为生命是上天的恩赐. 我非教友, 也不反对避孕, 认为生命是可控的小概率意外. 一旦发生, 就应该顺其自然, 终止这个过程是非道德的谋杀. 所以, 尽管在经历了第一个孩子的辛苦后感慨 "One is more than enough", 还是满心欢喜的迎接第二个. 但接踵而至的双胞胎确实是意料之外的措手不及.

如今, 每晚每三个小时被某位的哭声唤醒, 迷瞪着喂奶一起挣扎一个小时. 这种日子已经两个星期了. 我还很敬佩自己能白天继续上班, 现在还能继续抽空补充一下Blog 的空白.

去睡了. 太阳明天还依旧要升起.


by Fango (noreply@blogger.com) at July 19, 2011 02:15 PM

Airs – Ian Lance Taylor

CVS SSH

Sorry for the long posting hiatus. I have enough readers now that it’s hard to write the usual random nonsense.

I was recently reminded of an old problem using CVS over SSH, which was an interesting example of various different instances of reasonable behaviour adding up to a bug. It’s possible that this bug has been fixed, but I’ll assume that it hasn’t. The bug is that “cvs diff 2>&1 | less” will sometimes drop data, leaving you looking at an incomplete diff.

When CVS invokes SSH, it sets up file descriptors 0 (standard input) and 1 (standard output), but not 2 (standard error). Thus SSH inherits file descriptor 2 from CVS. This means that any SSH errors get reported to the standard error passed to CVS, which is what you want to have happen. However, when using 2>&1, this means that SSH’s file descriptor 2 will be the same as CVS’s file descriptors 1 and 2.

SSH puts its file descriptors 0, 1, and 2 into nonblocking mode, so that it can use select to send data back and forth without blocking. This means that SSH puts CVS’s file descriptor 2 into nonblocking mode. When using 2>&1, file descriptors 1 and 2 are the same, so this puts CVS’s file descriptor 1 into nonblocking mode.

CVS uses stdio to output data to standard output. When writing to a pipe, the buffer can fill up. CVS naturally never puts the descriptor into nonblocking mode, but when SSH has done it indirectly, and the buffer fills, the data being written will be discarded. This is what causes the bug: the discarded data is never seen by the user.

So what’s the fix? It’s reasonable for SSH to put its descriptors into nonblocking mode. It’s reasonable for CVS to pass its file descriptor 2 to SSH. It’s reasonable for CVS to use stdio to output data. It’s reasonable for stdio to not specially handle a nonblocking file descriptor—any program which wants to use a nonblocking descriptor needs to handle I/O retries itself. It’s reasonable for 2>&1 to mean that file descriptors 1 and 2 refer to the same underlying pipe. It’s reasonable for the user to use 2>&1 when piping cvs diff output to less.

I think the only remaining link in the sequence leading to the bug is that when SSH sets its file descriptor 2 to nonblocking mode, this affects the file in CVS. This is a consequence of the Unix file model, in which file descriptors refer to underlying files. A file descriptor has only one flag: whether it is closed if the exec system cal is run. All the other information is attached to the underlying file. Using 2>&1 means that two file descriptors point to the same file. Forking and execing SSH does not change this–in fact, it adds two more file descriptors, in the SSH process, which point to the same file. Any change in the flags associated with that file is seen by all the associated file descriptors.

This separation of file descriptor and file is what makes 2>&1 work. It’s also what makes >> work; >> opens a file in append mode, and the append flag is inherited by other processes which refer to that file. In any case, what really counts here is not the exec, but the fork; forking a process should not change the flags associated with a file. Further, I’m sure there programs which depend on the fact that changing the flags on a file after a fork affects the file as seen by the parent process.

It’s possible to imagine that file descriptors point to a new shared structure which then points to the underlying file. The file position and some flags would stay with the underlying flie. The new shared structure would just hold some flags which need not always be shared: O_NONBLOCK, O_ASYNC, etc. Calling fork would not create a new shared structure, but calling exec would, copying the existing structure. That would let some flags not be copied across exec process boundaries.

However, that would be a significant change to the Unix file model, a model which has lasted for decades and is not clearly broken. Absent that change, we are left with a complex bug, in which all choices are reasonable.

The workaround for the problem is to invoke SSH with 2>/dev/null, and assume that SSH never writes anything useful to standard error. The 2>/dev/null disassociates SSH file descriptor 2 from CVS file descriptor 2, so CVS file descriptor 1 is not accidentally set into nonblocking mode.


by Ian Lance Taylor at July 19, 2011 06:14 AM

July 18, 2011

Miek Gieben

On programming languages and programmers

Very well written email message from Geoff Teale on the golang mailing list on programmers and progamming languages (thread).

To summarise a long presentation I gave to non-programmers:

  • There are 12 million programmers in the world
  • The majority of those programmers are scarcely qualified
  • Most technology decisions are made by a combination of following the crowd and a false understanding of risk.
  • The high cost and failure rate in software development is no coincidence.

Remember the Stevie Wonder rule - "When you believe in something you don't understand then you suffer". In this case that means "Perhaps making programming language decisions based on what 12 million powerless idiots are doing isn't the golden road to glory and great hacks."

Go is a genuine attempt to improve the state of systems programing language beyond the point they reached in the early 1970s. As a result the sort of people using it are mostly that small community of people who understand and care about the concerns that drive such a development.

You're not going to catch those 12 million people unless you can market heavily enough the idea that their future income depend on jobs/contacts built around go, but that goal just draws resources and energy away from making the language better.

Arguably Java also suffers from it's large community of corporate drones. The slavish tendency to build baroque, mausoleums of intricate classes, dense with state and dripping with verbose XML is a reflection of the unthinking insanity of the 12 million.

I'd rather a tiny community use the language well, built successful applications and organically grew the user base whilst establishing a clean, sane library base that might later be used to improve the lives of a wider population of programmers.

I've said more than enough, I'll trundle back to the twelve million and take my punishment now.

by Miek Gieben at July 18, 2011 12:02 PM

July 07, 2011

Journal

How to find out which Active Directory security group you belong to

This took a while to figure out how to do, so I thought I'd post how to identify which security groups a given user belongs to within a Microsoft Active Directory system.

Assuming you still haven't bought a mac, here are the steps:

  1. Start --> Run -- CMD

First, find out your user info by issuing this command.

C:\Documents and Settings\cthomps> dsquery user -name Charles*

This will emit:

"CN=Charles Thompson,OU=Bellevue,OU=User Accounts,DC=OFFDECK,DC=local"

Last, use the above output string as an input argument for the final command we'll run.

 

C:\Documents and Settings\cthomps>dsget user "CN=Charles Thompson,OU=Bellevue,OU=User Accounts,DC=OFFDECK,DC=local" -memberof -expand
This will emit:
"CN=Foobar,OU=Group Accounts,DC=OFFDECK,DC=local"
"CN=Domain Users,CN=Users,DC=OFFDECK,DC=local"
"CN=Users,CN=Builtin,DC=OFFDECK,DC=local"

 

Now you know that I am part of the Foobar group. 

Happy trails,

Charles

 

by Charles Thompson at July 07, 2011 08:30 PM

July 06, 2011

Miek Gieben

Go DNS (update)

I'm finally back to coding Go DNS and making it work with the latest Go releases. Also the API has changed quite significantly since the last time I blogged about it.

So this I will detail key2ds which is small utility that queries a zone and print any DNSKEY records as DS records on the fly, to show the new API and some sample usage.

% ./key2ds sidn.nl
sidn.nl.    0   IN  DS  42033 8 1 343F74674D36C9B5BE2CEB2C401AC4EDEB2A05B2
sidn.nl.    0   IN  DS  42033 8 2 BF985EC0738FACC89EE0B12FBD9261827C59191D9EA6A9BDFF55F9BDF3DBBFF3
sidn.nl.    0   IN  DS  39274 8 1 E79E031DFDE8E68EF1E2C6CA0943C2CC0DED1889
sidn.nl.    0   IN  DS  39274 8 2 8E8A8CFB40FD0C30BFA82E53752E1C257DAFB7B6206D12B9EDA43AF3EAB2157D

This util uses synchronous queries. I will explain the main-function:

func main() {
        conf, err := dns.ClientConfigFromFile("/etc/resolv.conf")
        if len(os.Args) != 2 || err != nil {
                fmt.Printf("%s DOMAIN\n", os.Args[0])
                os.Exit(1)
        }

Read the resolver config from /etc/resolv.conf and check if enough parameters have been given.

    m := new(dns.Msg)
    m.SetQuestion(os.Args[1], dns.TypeDNSKEY)

Prepare a new dns message to send to the other side. I'm interested in the DNSKEYs for the name given on the command line.

    // Set EDNS0's Do bit
    e := new(dns.RR_OPT)
    e.Hdr.Name = "."
    e.Hdr.Rrtype = dns.TypeOPT
    e.SetUDPSize(2048)
    e.SetDo()
    m.Extra = append(m.Extra, e)

This is DNSSEC so I must prepare an EDNS0 section, which is nothing more than adding an OPT RR to the additional section. I'm pondering making EDNS0 easier and provide a few helper functions (ideas welcome!). For now the whole OPT RR must be defined from scratch.

    c := dns.NewClient()
    r := c.Exchange(m, conf.Servers[0])
    if r == nil {
            fmt.Printf("*** no answer received for %s\n", os.Args[1])
            os.Exit(1)
    }

Create a new client and use Exchange() to perform send the query and wait for the reply. Note that we only use the first server defined in /etc/resolv.conf. (There is room for some improvements :-) )

    if r.Rcode != dns.RcodeSuccess {
            fmt.Printf(" *** invalid answer name %s after DNSKEY query for %s\n", os.Args[1], os.Args[1])
            os.Exit(1)
    }

If anything is wrong with the answer I bail out here.

    for _, k := range r.Answer {
            if key, ok := k.(*dns.RR_DNSKEY); ok {

Loop through the answer section and check each RR to see if it is a DNSKEY record with a type check.

                    ds := key.ToDS(dns.HashSHA1)
                    ds.Hdr.Ttl = 0
                    fmt.Printf("%v\n", ds)

For each DNSKEY convert it to a SHA1 DS records with ToDS()

                        ds = key.ToDS(dns.HashSHA256)
                        ds.Hdr.Ttl = 0
                        fmt.Printf("%v\n", ds)
                }
        }
}

And do the same for SHA256 and print that too.

by Miek Gieben at July 06, 2011 07:41 AM

July 05, 2011

Miek Gieben

Go DNS (update)

I'm finally back to coding Go DNS and making it work with the latest Go releases. Also the API has changed quite significantly since the last time I blogged about it.

I will detail key2ds which is small utility that queries a zone and print any DNSKEY records as DS records on the fly.

% ./key2ds sidn.nl
sidn.nl.    0   IN  DS  42033 8 1 343F74674D36C9B5BE2CEB2C401AC4EDEB2A05B2
sidn.nl.    0   IN  DS  42033 8 2 BF985EC0738FACC89EE0B12FBD9261827C59191D9EA6A9BDFF55F9BDF3DBBFF3
sidn.nl.    0   IN  DS  39274 8 1 E79E031DFDE8E68EF1E2C6CA0943C2CC0DED1889
sidn.nl.    0   IN  DS  39274 8 2 8E8A8CFB40FD0C30BFA82E53752E1C257DAFB7B6206D12B9EDA43AF3EAB2157D

This util uses synchronous queries. I will detail the main-function:

func main() {
        conf, err := dns.ClientConfigFromFile("/etc/resolv.conf")
        if len(os.Args) != 2 || err != nil {
                fmt.Printf("%s DOMAIN\n", os.Args[0])
                os.Exit(1)
        }

Read the resolver config from /etc/resolv.conf and check if enough parameters have been given.

    m := new(dns.Msg)
    m.SetQuestion(os.Args[1], dns.TypeDNSKEY)

Prepare a new dns message to send to the other side. I'm interested in the DNSKEYs for name given on the command line.

    // Set EDNS0's Do bit
    e := new(dns.RR_OPT)
    e.Hdr.Name = "."
    e.Hdr.Rrtype = dns.TypeOPT
    e.SetUDPSize(2048)
    e.SetDo()
    m.Extra = append(m.Extra, e)

This is DNSSEC so I must prepare an EDNS0 section, which is nothing more than adding an OPT RR to the Additional section. I'm pondering making EDNS0 easier and provide a few helper functions. For now the whole OPT RR must be defined from scratch.

    c := dns.NewClient()
    r := c.Exchange(m, conf.Servers[0])
    if r == nil {
            fmt.Printf("*** no answer received for %s\n", os.Args[1])
            os.Exit(1)
    }

Create a new client and use Exchange() to perform send the query and wait for the reply. Note that we only use the first server defined in /etc/resolv.conf. (There is room for some improvements :) )

    if r.Rcode != dns.RcodeSuccess {
            fmt.Printf(" *** invalid answer name %s after DNSKEY query for %s\n", os.Args[1], os.Args[1])
            os.Exit(1)
    }

If anything is wrong with the answer I bail out here.

    for _, k := range r.Answer {
            if key, ok := k.(*dns.RR_DNSKEY); ok {

Loop through the answer section and check each RR to see if it is a DNSKEY record with a type check.

                    ds := key.ToDS(dns.HashSHA1)
                    ds.Hdr.Ttl = 0
                    fmt.Printf("%v\n", ds)

For each DNSKEY convert it to a SHA1 DS records with ToDS()

                        ds = key.ToDS(dns.HashSHA256)
                        ds.Hdr.Ttl = 0
                        fmt.Printf("%v\n", ds)
                }
        }
}

And do the same for SHA256 and print that too.

by Miek Gieben at July 05, 2011 08:45 PM

July 04, 2011

Going Along

left, right, left


英文最无聊的是拿left,<wbr></wbr>right找乐,对应翻译,是最头疼不过的事了。

Should I go to the left, where nothing's right? Or to the right, where nothing's left. 
我该左转面对错误,还是右转寻找失去?
My left brain has nothing right; while my right brain has nothing left.
我的左脑没点儿正题,右脑没点儿残余。
War does not determine who is right - only who is left.  (Bertrand Russell)
战争决定的不是对错,只是死活。

我也这样教孩子:
“Use your right hand to write!"

by Fango (noreply@blogger.com) at July 04, 2011 02:09 PM

July 03, 2011

catena

Credo example: from lex and c source to cygwin executable, across directories

This article walks through building a trivial example of lex source
code into C, and then compiling the generated C source code into
object files and an executable in a different directory. The point is
to demonstrate using dodep to generate and customize build scripts
and list dependencies, and credo to execute the build process.

Lines which start with ; are shell commands; lines without are output.
Key commands are displayed in red text.

Starting state

We start with the files lorem, src/dcr.l, src/header.c, src/lex.h,
and an empty obj directory. Each line of lorem ends with a
carriage return (not usually printed), which we want to strip.
header.c is an ordinary C source file to compile and link.
lex.h gives us a local header to look for.

Generate source code

; cd src
; echo flex > dcr.c.lex.env

We first go into the src directory, and set the lex shell variable to flex,
to specify which lexer to use. To demonstrate an unusual feature,
that would be valid across ports to different operating systems,¹
we’ll capture it with this command.
¹ Inferno and Plan 9 store variables by name in the directory /env,
different for each process. This gives it a definite advantage in
capturing dependencies on variables, since we can just list the name
of the shell-variable file as a dependency.

src/dcr.c.lex.env:1: flex

This setting applies (is transformed into a shell variable) when credo
processes the target dcr.c, if dcr.c depends on /env/lex.

; dodep (c lex l c) dcr.c
credo dcr.c

We ask dodep to generate a shell script and list of dependencies with
this command. The content of these files comes from a library,
indexed by the four parameters given before the name of the file we
want to build. In this case, we want to look in the “c” namespace,
at the command “lex”, to translate an “l” file to a “c” file.

The generated dependency list includes the name of the lex source file,
and references to the variables lex and lflags.

src/dcr.c.dep:1: 0 dcr.l
src/dcr.c.dep:2: 0 /env/lex
src/dcr.c.dep:3: 0 /env/lflags

Credo passes the name of its target, the C source file, to the shell script,
which prints the name of the C source file if it was able to create it.

src/dcr.c.do:1: #!/dis/sh
src/dcr.c.do:2: c = $1
src/dcr.c.do:3: (sum l) = `{grep '\.l$' $c^.dep}
src/dcr.c.do:4:
src/dcr.c.do:5: if {no $lex} {lex = lex}
src/dcr.c.do:6:
src/dcr.c.do:7: if {
src/dcr.c.do:8: flag x +
src/dcr.c.do:9: os -T $lex $lflags $l
src/dcr.c.do:10: mv lex.yy.c $c
src/dcr.c.do:11: } {
src/dcr.c.do:12: echo $c
src/dcr.c.do:13: }

The hosted-Inferno command os calls host-OS commands. Under Cygwin,
it calls Cygwin or Windows commands.

Dodep finally prints a credo command to build the requested target.

; credo dcr.c
credo dcr.l
credo dcr.c
os -T flex dcr.l
mv lex.yy.c dcr.c
dcr.c

Credo builds all its non-/env dependencies in parallel. Once these
are complete, it determines whether the checksum of each file on which
it depends is different than the checksum stored for that file the
last time credo built this target.

This credo command creates a build-avoidance marker file dcr.l.redont,
which tells further runs of credo that the file dcr.l does not need
any processing, so exit early. It calls the host’s flex program,
on the path set when the Inferno environment started, to create the
target file dcr.c.

It updates the check sums in the file dcr.c.dep, to reflect content at
the time of compilation. This means that each target has its own view
of its dependencies, and any change to any file on which it depends,
or a change to the list of files on which it depends, prompts the
target to rebuild.

src/dcr.c.dep:1: 79f9925952d9cfb5a58270c0e2b67691 dcr.l
src/dcr.c.dep:2: 897a779351421523cadbafccdce22efe /env/lex
src/dcr.c.dep:3: 0 /env/lflags

It creates these checksum files to detect any changes to the target’s
dependencies or build script.

src/dcr.c.dep.sum:1: c33129421847b7d897d4e244caf1b8c0 dcr.c.dep

src/dcr.c.do.sum:1: 71d94d651922bd5ff5b543bba52f47d0 dcr.c.do

It also checksums the target file itself. If credo finds, the next
time it runs, that the current checksum of the target does not match,
then it assumes that the target was changed by hand, and will not
overwrite it.

src/dcr.c.sum:1: 2fed3667f390fd80993e090a7eb92c75 dcr.c

Compile objects and executable

We now have all the source, so we go to the object-file and executable
directory, and ask dodep to provide do and dep files to build dcr.exe.
From the “c”-language toolset, we use “cc” to compile an “o”bject file
into an “exe”cutable.

; cd ../obj
; dodep (c cc o exe) dcr.exe
credo dcr.exe

This time the dodep command created two *.do files, dcr.exe.dep.do and
dcr.exe.do, instead of a do and dep file for the target dcr.exe.

obj/dcr.exe.dep.do:1: #!/dis/sh
obj/dcr.exe.dep.do:2: dep = $1
obj/dcr.exe.dep.do:3: exe = `{echo $dep | sed 's,\.dep,,'}
obj/dcr.exe.dep.do:4: (stem ext o) = `{crext o $exe}
obj/dcr.exe.dep.do:5:
obj/dcr.exe.dep.do:6: adddep $exe /env/ars /env/cc /env/cflags /env/ldflags /env/objs
obj/dcr.exe.dep.do:7: adddep $exe $o
obj/dcr.exe.dep.do:8: adddep $exe `{/lib/do/c/coneed $o}

dcr.exe.dep.do creates the dependency list dcr.exe.dep for the target
dcr.exe by adding a set of credo-specific (ars and objs) and standard
(cc, cflags, and ldflags) shell variables; the primary object file,
named for the executable; and any other object files which the primary
one needs. The tool coneed does this last bit of analysis by compiling
the primary object file, looking for unresolved symbols in available
source code, compiling the source code to make sure, and printing the
set of matching object files.

obj/dcr.exe.do:1: #!/dis/sh
obj/dcr.exe.do:2: exe = $1
obj/dcr.exe.do:3: if {no $cc} {cc = cc}
obj/dcr.exe.do:4: if {
obj/dcr.exe.do:5: flag x +
obj/dcr.exe.do:6: os -T $cc $cflags -o $exe $objs $ars $ldflags
obj/dcr.exe.do:7: } {
obj/dcr.exe.do:8: echo os -T ./$exe
obj/dcr.exe.do:9: }

To gather enough information to compile the executable, credo relays
information from dependencies back to calling targets through *.relay
files, which are shell scripts that set the environment for calling targets.

Finally, to start the build process, we locate the source code,
record which compilation tools to use, and again call credo.

; srcdir = ../src/
; echo cpp-3 > default.cpp.env
; echo -I../src/ > default.cppflags.env
; echo gcc-3 > default.cc.env
; credo dcr.exe
credo dcr.exe.dep
os -T gcc-3 -I../src/ -c ../src/dcr.c
os -T gcc-3 -I../src/ -c ../src/header.c
credo dcr.o.dep
credo dcr.o
credo header.o.dep
credo header.o
credo dcr.exe
os -T gcc-3 -o dcr.exe dcr.o header.o
os -T ./dcr.exe

Credo first runs dcr.exe.dep.do to find and store the dependencies of
dcr.exe in dcr.exe.dep. dcr.exe.dep is an implicit dependency of dcr.exe,
so credo runs its *.do script automatically.

obj/dcr.exe.dep:1: 0 /env/ars
obj/dcr.exe.dep:2: 131eb9ab2f6a65b34e0158de1b321e3c /env/cc
obj/dcr.exe.dep:3: 0 /env/cflags
obj/dcr.exe.dep:4: 0 /env/ldflags
obj/dcr.exe.dep:5: 84a1a3c306e006dd723bebe9df29ee6c /env/objs
obj/dcr.exe.dep:6: 3f0d90c1c7483ad1805080cf9e48d050 dcr.o
obj/dcr.exe.dep:7: 1db618b791dc87ac0bd5504f69434273 header.o

Coneed uses $srcdir to find dcr.c, and the setting of cppflags in
default.cppflags.env to find lex.h. Once coneed compiles dcr.o,
it finds the unresolved symbol for the header function, finds a
definition of header() in header.c, and compiles header.o to verify
that it defines the symbol. Coneed finds no other unresolved symbols
supplied by other source code in $srcdir (c.f. printf), so it stops.
Coneed uses “dodep (c cc c o)” to compile the source code in $srcdir
into object files in the current directory (obj). This generates
*.o.dep.do and *.o.do for each source file: those for dcr are shown,
the ones for header are identical.

obj/dcr.o.dep.do:1: #!/dis/sh
obj/dcr.o.dep.do:2: dep = $1
obj/dcr.o.dep.do:3: o = `{echo $dep | sed 's,\.dep,,'}
obj/dcr.o.dep.do:4: (stem ext c) = `{crext c $srcdir^$o}
obj/dcr.o.dep.do:5:
obj/dcr.o.dep.do:6: adddep $o /env/cc /env/cflags /env/cppflags
obj/dcr.o.dep.do:7: adddep $o $c
obj/dcr.o.dep.do:8: adddep $o `{/lib/do/c/findh $c}

obj/dcr.o.do:1: #!/dis/sh
obj/dcr.o.do:2: o = $1
obj/dcr.o.do:3: (sum c) = `{grep '\.c$' $o^.dep}
obj/dcr.o.do:4:
obj/dcr.o.do:5: if {no $cc} {cc = cc}
obj/dcr.o.do:6:
obj/dcr.o.do:7: if {
obj/dcr.o.do:8: flag x +
obj/dcr.o.do:9: os -T $cc $cflags $cppflags -c $c
obj/dcr.o.do:10: } {
obj/dcr.o.do:11: echo 'objs = $objs '^$o > $o^.relay
obj/dcr.o.do:12: }

Before credo runs dcr.o.do it runs dcr.o.dep.do to generate dcr.o.dep
(header.o likewise). To find the paths to C header files it calls findh,
which gathers header-file #includes from the C source files,
and searches for them in local and system directories using cppflags
and the search list printed by $cpp -v.

obj/dcr.o.dep:1: 131eb9ab2f6a65b34e0158de1b321e3c /env/cc
obj/dcr.o.dep:2: 0 /env/cflags
obj/dcr.o.dep:3: 9134215aef7b4657beb5c4bb7a20d4a1 /env/cppflags
obj/dcr.o.dep:4: 2fed3667f390fd80993e090a7eb92c75 ../src/dcr.c
obj/dcr.o.dep:5: feea1fa232f248baa7a7d07743ee86c4 ../src/lex.h
obj/dcr.o.dep:6: fb584676de41ee148c938983b2338f5b /n/C/cygwin/usr/include/stdio.h
obj/dcr.o.dep:7: f6409b1008743b1866d4ad8e53f925cc /n/C/cygwin/usr/include/string.h
obj/dcr.o.dep:8: 468b1dd86fef03b044dceea020579940 /n/C/cygwin/usr/include/errno.h
obj/dcr.o.dep:9: 4e6678324ba6b69666eba8376069c950 /n/C/cygwin/usr/include/stdlib.h
obj/dcr.o.dep:10: c7575313e03e7c18f8c84a5e13c01118 /n/C/cygwin/usr/include/inttypes.h
obj/dcr.o.dep:11: a8fd5fa102b8f74d1b96c6c345f0e22d /n/C/cygwin/usr/include/unistd.h

obj/header.o.dep:1: 131eb9ab2f6a65b34e0158de1b321e3c /env/cc
obj/header.o.dep:2: 0 /env/cflags
obj/header.o.dep:3: 9134215aef7b4657beb5c4bb7a20d4a1 /env/cppflags
obj/header.o.dep:4: ecd87752a211e69078e6bc37afbb561b ../src/header.c
obj/header.o.dep:5: feea1fa232f248baa7a7d07743ee86c4 ../src/lex.h
obj/header.o.dep:6: fb584676de41ee148c938983b2338f5b /n/C/cygwin/usr/include/stdio.h

At this point credo has the dependencies for dcr.exe, so it works
through them, calling the *.relay files—generated by the object files’
do scripts—to gather object names in $objs.

obj/dcr.o.relay:1: objs = $objs dcr.o

obj/header.o.relay:1: objs = $objs header.o

There’s not much to do since coneed already compiled the object files,
so it links them, and prints an os command to run the executable,
since Inferno can’t directly run a Cygwin executable.

Clean up

To clean up, we remove generated files in the src and obj directories.

; rm -f *.redoing *.redont *.renew *.reold *.sum

This removes all the temporary state files created by credo.
Once this is done credo will rebuild from scratch, and reconstruct
each target’s view of its dependencies.

; rm -f `{lsdo | sed 's,^c?redo ,,'}

This removes all the targets created by do scripts. The lsdo command
(called by credo with no targets) prints credo commands for all the
credo targets in the current directory. For example:

; cd src; credo
credo dcr.c

; cd obj; credo
credo dcr.exe
credo dcr.exe.dep
credo dcr.o
credo dcr.o.dep
credo header.o
credo header.o.dep

Once the targets are removed, credo will unconditionally generate them.

; rm -f *.do *.dep *.relay

This removes all the instructions credo uses to build files.
These may usually be regenerated by dodep, adddep (which adds
to the given target’s dependency list the given files), and
rmdep (which removes the given files).

A single library script is provided to remove the state, target,
and dodep files.

; rm -f *.env

This removes default and per-target environment settings.

Once we remove these sets of files, the directories contain only the
files present in their starting state.


by catena at July 03, 2011 07:51 PM

July 01, 2011

RSC

_rsc: Floating Point to Decimal Conversion is Easy http://t.co/1DADWqg

_rsc: Floating Point to Decimal Conversion is Easy http://t.co/1DADWqg

July 01, 2011 01:12 PM