December 4, 2010

it really does not matter for choosing among languages

the original webpage: click

Lisp被许多资深程序员视为编程语言中的圣杯,因为学起来很难。著名程序员、最热门的技术问答网站StackOverflow创始人Joel Spolsky曾经在"Java语言学校的危险性"一 文中说,自己当年在大学里学习用Lisp的导论课程也是苦不堪言,而Lisp这样的函数式语言实际开发中并不常用,但是一旦到了体现优势的时候,你如果不 懂,将失之千里。他还认为,Google的核心技术之一MapReduce就来自函数式语言,而且使Google领先微软多年。请注意,Spolsky曾 经1990年代微软的Excel项目经理,VBA的主要创造者。

《Unix编程艺术》的作者Eric Raymond也在"如何成为黑客"(英文版)中说过,Lisp是对黑客特别重要的语言,"掌握了之后,你会得到丰富的启迪和经验。 即使实际上很少使用Lisp,这些经验也会使你在以后的日子里成为更好的程序员。"

而Paul Graham更是Lisp的头号吹鼓手,他曾与蠕虫病毒发明者Robert Morris一起,成功地用Lisp开发历史上第一个Web应用――ViaWeb,并高价卖给Yahoo致富。他在2001年写了一篇宣传Lisp的名文"Beating the Averages"(英文),其中说到:"Lisp之所以极为优秀,并不是因为只有铁杆粉丝才知道的某些魔术般的性质,而在于它确实是最强大的编程语言。大家不用它的原因,在于编程语言不只是技术,而且也是思维习惯,这是改变起来最慢的东西。"

有意思的是,美国时间10月18日,著名技术新闻网站Hacker News上,名为kung-fu-master的用户发了一篇名为"问PG: Lisp与Python (2010)"的帖子,内容很简单:"好像许多Lisp老枪都开始转而用Python的(比如Peter Norvig)。今天你怎么看Lisp与Python?"

这里的PG就是指Hacker News的创始人、著名Lisp程序员与吹鼓手Paul Graham。而其中提到的Peter Norvig则是另一个著名Lisp程序员,现任Google研发总监。他有一篇经典的文章"十年学会编程"(英文版),相信大家都已经看过,他的首选推荐语言当然也是Lisp(更准确的说是Lisp的方言Scheme)。

面对这样直接的问题,专家们是怎么回答的呢?
Paul Graham说:
这问题好像来自2005年而不是2010年。Lisp现在由于Clojure(Lisp的现代方言,可以运行在JVM和.NET上――CSDN编者注)的出现,已经又变得时髦了。当然Python也有很好的库,但是我觉得用缺乏宏的语言编程很受局限。

许多网友对Python没有宏的问题进行了讨论。有人说不支持宏是出于代码可读性的考虑。而更多的人则认同宏是一种抽象工具,任何工具都会被误用、滥用,但并不表示工具本身有问题。

另一Lisp专家,《Coder at Work》和《Practical Common Lisp》作者>Peter Seibel也加入了讨论(他最近忙于编辑一种杂志Code Quarterly)。他说:自己与Peter Norvig有类似的体验。虽然自己Lisp非常熟练,但是在表达算法方面Python是最佳选择。不过,相比Lisp实现,CPython的运行速度慢得惊人,甚至差5-10倍。

而Peter Norvig也罕见地现出真身,给出了自己的回答,内容一如既往地经典:
我 是Peter Norvig。我转向Python不是因为它比Lisp更好、更令人满意、更实用,而是因为它用作伪代码更合适。许多学生说,在《人工智 能》(Norvig与Russell合著的经典教材)一书中的伪代码与我们在网上提供的Lisp代码之间进行转换太难了。于是我要寻找一种更近似伪代码的 语言,发现Python是最合适的。然后我就自学了Python,熟练到足以实现教材中示例的地步。我发现Python对于一些类型的小问题非常合适,有 些库也是我与其他的一些代码(包括在Google内和网上其他地方的代码)集成非常需要的。 我认为Lisp对更大的项目和编译速度很重要的应用而言仍然具有优势。但是在主要目的是交流而非编程的时候(比如针对数量众多的学生),Python更有 优势。

就更一般意义上的编程而言,在Google和其他地方,我认为语言的选择并不如其他方面的选择那么重要:如果你有了正确的总体架构、正确的程序员团队、正确的开发过程(能够快速开发、持续改善),那么很多语言都能胜任;但如果以上的东西你没有,那无论选择什么语言,你都会陷入一团糟。

还有人找出今年2月Norvig在一次采访(无法直接访问)中类似的话,透露了Google内部的一些信息:
(1) Google最开始似乎核心程序员都是用C++的,效率很高。这部分形成了公司的文化。
(2) Google早期的Lisp程序员(Erann Gat) 注意到其他程序员和自己的效率差不多,甚至更好。关键还是在人,与20年前相比,现在语言的选择不那么重要了。
(3) Lisp是为单个程序员或者一小组程序员进行探索性工作而专门设计的……如果我想自己在周末修改代码,会更愿意用Lisp,但是如果有几百个程序员一起改代码,那就不是编程语言的问题,而是社会问题了。
(4) 库。

其他人举出的材料中,最有意思的应该来自Lisp之父、计算机科学巨人约翰麦卡锡。这篇博客(无法直接访问)里生动讲述了这位图灵奖得主在某次听Peter Norvig改而鼓吹Python的演讲后的情景:
Norvig 演讲后,进入提问环节。出乎我的意料,他点了一位皱巴巴的老头。老头的胡子和头发都花白了,而且乱糟糟的,看上去像是来此参观但是迷路了,到这里来休息一 下,好奇地听听我们在说什么。我第一个念头是,估计他已经被这么艰深的话题弄晕了。但是马上想到,不对啊,这里离斯坦福很近,这老头的年纪也对,难道 是……
只听Norvig说:"是,John,你有什么问题?"我记不清Lisp之父当时怎么问的了,但不超过十 个词,就是问Python是否能如Lisp那样优雅地像数据一样处理代码。"不,John,不行。"Norvig回答,然后静等麦卡锡继续发问。但是,老 人什么也没有再说。此时真是无言胜千语啊……

看来,在大师眼中,数据与代码等同处理是最重要的语言特性之一。他还曾经在访谈中这样评价Ruby(提问者说Ruby从Lisp中借鉴了很多):"Ruby能像数据那样使用列表结构吗?那每次算加和减的时候,都得进行解析?这方面Ruby还不如1960年的Lisp。"

November 19, 2010

coding advices

After decades of programming I do not even think about these three ways to read code. I just glance at it and know what it means, and I can even glance at a whole screen of code, and all the bugs and errors jump out at me. That took an incredibly long time and quite a bit more study than is sane. To get that way, I learned these three ways of reading most any programming language:

1. Front to back.
2. Back to front.
3. Counter-clock-wise.

Try them out when you have a difficult statement to figure out. When you type the next block of your code, go over it in these ways. This one is gonna be fun.

......

I am warning you, this will be frustrating. In the business we call this "yak shaving". Yak shaving is any activity that is mind numblingly irritatingly boring and tedious that you have to do before you can do something else that's more fun. You want to create cool Python projects, but you can't do that until you setup a skeleton directory, but you can't setup a skeleton directory until you install some packages, but you can't install pacakages until you install package installers, and you can't install package installers until you figure out how your system installs software in general, and so on.

Struggle through this anyway. Consider it your trial-by-annoyance to get into the programmer club. Every programmer has to do these annoying tedious tasks before they can do something cool.

......

What I discovered after this journey of learning is that the languages did not matter, it's what you do with them. Actually, I always knew that, but I'd get distracted by the languages and forget it periodically. Now I never forget it,
and neither should you.

Which programming language you learn and use does not matter. Do not get sucked into the religion surrounding programing languages as that will only blind you to their true purpose of being your tool for doing interesting things.

Programming as an intellectual activity is the only art form that allows you to create interactive art. You can create projects that other people can play with, and you can talk to them indirectly. No other art form is quite this  interactive. Movies flow to the audience in one direction. Paintings do not move. Code goes both ways.

Programming as a profession is only moderately interesting. It can be a good job, but if you want to make about the same money and be happier, you could actually just go run a fast food joint. You are much better off using code as
your secret weapon in another profession.

People who can code in the world of technology companies are a dime a dozen and get no respect. People who can code in biology, medicine, government, sociology, physics, history, and mathematics are respected and can do amazing things to advance those disciplines.

Of course, all of this advice is pointless. If you liked learning to write software with this book, you should try to use it to improve your life any way you can. Go out and explore this weird wonderful new intellectual pursuit that barely anyone in the last 50 years has been able to explore. Might as well enjoy it while you can.

Finally, I will say that learning to create software changes you and makes you different. Not better or worse, just different. You may find that people treat you harshly because you can create software, maybe using words like "nerd". Maybe you will find that because you can dissect their logic that they hate arguing with you. You may even find that simply knowing how a computer works makes you annoying and weird to them.

To this I have one just piece of advice: they can go to hell. The world needs more weird people who know how things work and who love to figure it all out. When they treat you like this, just remember that this is your journey, not theirs. Being different is not a crime, and people who tell you it is are just jealous that you have picked up a skill they never in their wildest dreams could acquire.

You can code. They cannot. That is pretty damn cool.
===

***CLASS STYLE
* Your class should use “camel case” like SuperGoldFactory rather than super_gold_factory.
* Try not to do too much in your __init__ functions. It makes them harder to use.
* Your other functions should use “underscore format” so write my_awesome_hair and not myawesomehair or MyAwesomeHair.
* Be consistent in how you organize your function arguments. If your class has to deal with users, dogs, and cats, keep that order throughout unless it really doesn't make sense. If you have one function takes (dog, cat, user) and the other takes (user, cat, dog), it'll be hard to use.
* Try not to use variables that come from the module or globals. They should be fairly self-contained.
* A foolish consistency is the hobgoblin of little minds. Consistency is good, but foolishly following some idiotic mantra because everyone else does is bad style. Think for yourself.
* Always, always have class Name(object) format or else you will be in big trouble.

***CODE STYLE
* Give your code vertical space so people can read it. You will find some very bad programmers who are able to write reasonable code, but who do not add any spaces. This is bad style in any language because the human eye and brain use space and vertical alignment to scan and separate visual elements. Not having space is the same as giving your code an awesome camouflage paint job.
* If you can't read it out loud, it's probably hard to read. If you are having a problem making something easy to use, try reading it out loud. Not only does this force you to slow down and really read it, but it also helps you find difficult passages and things to change for readability.
* Try to do what other people are doing in Python until you find your own style.
* Once you find your own style, do not be a jerk about it. Working with other people's code is part of being a programmer, and other people have really bad taste. Trust me, you will probably have really bad taste too and not even realize it.
* If you find someone who writes code in a style you like, try writing something that mimics their style.

***GOOD COMMENTS
* There are programmers who will tell you that your code should be readable enough that you do not need comments. They'll then tell you in their most official sounding voice that, "Ergo you should never write comments." Those programmers are either consultants who get paid more if other people can't use their code, or incompetents who tend to never work with other people. Ignore them and write comments.
* When you write comments, describe why you are doing what you are doing. The code already says how, but why you did things the way you did is more important.
* When you write doc comments for your functions , make the comments documentation for someone who will have to use your code. You do not have to go crazy, but a nice little sentence about what someone does with that function helps a lot.
* Finally, while comments are good, too many are bad, and you have to maintain them. Keep your comments relatively short and to the point, and if you change a function, review the comment to make sure it's still correct.

some useful link for programming format

高质量C++/C编程指南

Google code: google style code (including C/C++, Javascript, and Python)

Microsoft: All-In-One Code Framework

some advices about python coding

from 《learn python the hard way》
======

Every if-statement must have an else. If this else should never be run because it doesn't make sense, then you must use a die function in the else that prints out an error message and dies, just like we did in the last exercise. This will find many errors.

Never nest if-statements more than 2 deep and always try to do them 1 deep. This means if you put an if in an if then you should be looking to move that second if into another function.

Treat if-statements like paragraphs, where each if,elif,else grouping is like a set of sentences. Put blank lines before and after. Your boolean tests should be simple. If they are complex, move their calculations to variables earlier in your function and use a good name for the variable.

The best way to debug a program is to use print to print out the values of variables at points in the program to see where they go wrong.

Make sure parts of your programs work as you work on them. Do not write massive files of code before you try to run them. Code a little, run a little, fix a little.
======

Every if-statement must have an else. If this else should never be run because it doesn't make sense, then you must use a die function in the else that prints out an error message and dies, just like we did in the last exercise. This will find many errors.

Never nest if-statements more than 2 deep and always try to do them 1 deep. This means if you put an if in an if then you should be looking to move that second if into another function.

Treat if-statements like paragraphs, where each if,elif,else grouping is like a set of sentences. Put blank lines before and after. Your boolean tests should be simple. If they are complex, move their calculations to variables earlier in your function and use a good name for the variable.

The best way to debug a program is to use print to print out the values of variables at points in the program to see where they go wrong.

Make sure parts of your programs work as you work on them. Do not write massive files of code before you try to run them. Code a little, run a little, fix a little.


When scrutinizing the code, pay attention on:

1. Functions and what they do.
2. Where each variable is first given a value.
3. Any variables with the same names in different parts of the program. These may be trouble later.
4. Any if-statements without else clauses. Are they right?
5. Any while-loops that might not end.
6. Finally, any parts of code that you can’t understand for whatever reason.

Top 20 Programming Lessons I've Learned in 20 Years

  1. Set a duration of how long you think it should take to solve a problem - C'mon, admit it! I'm just as guilty as the next programmer. I've seen programmers sit in front of a monitor for eight hours at a time trying to solve a particular problem. Set a time table for yourself of 1 hour, 30 minutes, or even 15 minutes. If you can't figure out a solution to your problem within your time frame, ask for help or research your problem on the Internet instead of trying to be super-coder.
  2. A language is a language is a language - Over time, once you understand how one language works, you'll notice similarities between other languages. The language you choose should provide you with a suitable "comfort" level, the ability to produce efficient (and clean) code, and, above all, allow the language to suit the project and vice-versa.
  3. Don't over-"design pattern" applications - Sometimes it's just easier to write a simple algorithm than it is to incorporate a singleton or facade pattern. For the most part, it even allows for cleaner, understandable code. :-)
  4. Always backup your code - I've experienced a complete hard drive failue and lost a lot of code when I was younger and felt horrible because of what had happened. The one time you don't back up your data may be the one time where you have a strict deadline with a client and they need it tomorrow. Source code/version control applies here as well.
  5. You are not the best at programming. Live with it. - I always thought that I knew so much about programming, but there is always someone out there better than you. Always. Learn from them.
  6. Learn to learn more - With number five explained, I've always had a magazine or book in my hand about computers or programming (ask my friends, they'll confirm). True, there is a lot of technology out there and keeping up with it is a fulltime job, but if you have a smart way of receiving your news, you'll learn about new technology every single day.
  7. Change is constant - Your knowledge of technology and/or programming should be similar to how you treat stocks: Diversify. Don't get too comfortable with a particular technology. If there's not enough support for that language or technology, you might as well start updating your resume now and start your training period. My general rule of thumb that has kept me going? Know at least two or three languages, so if one dies off, you have another one to fall back on while you train for a new technology.
  8. Support Junior - Assist and train the junior/entry-level developers on good programming guidelines and techniques. You never know...you may move up in rank and you'll feel more confident having personally trained and prepared them for their next position.
  9. Simplify the algorithm - Code like a fiend, but once you're done, go back through your code and optimize it. A little code improvement here and there will make support happier in the long run.
  10. Document your code - Whether its documenting a Web Service API or documenting a simple class, document as you go. I've been accused of over-commenting my code and that's something I'm proud of. It only takes a second to add an additional comment line for each 3 lines of code. If it's a harder technique to grasp, don't be afraid to over-comment. This is one problem most architects, backup coders, and support groups don't complain about if you've done your job right.
  11. Test, Test, Test - I'm a fan of Black Box Testing. When your routine is finished, your "stamp of approval" period starts. If you have a Quality Assurance department, you may be talking more to them than your project manager regarding errors in your code. If you don't test your code thoroughly, you may develop more than code. Possibly a bad reputation.
  12. Celebrate every success - I've met a lot of programmers who have conquered headache-style problems with a great programming technique and celebrated with a fellow programmer by doing the "shake", the high-five, or even a "happy dance." Everyone has enlightening periods in their life and even though that one happy coder asked you to come and see his extraordinary piece of code and you've seen that one piece of code over 100 times in your experiences, celebrate the success of a fellow developer for the 101-st time.
  13. Have Code Reviews Frequently - On projects and personally. In the company, you will always have code reviews of how well you coded something. Don't look at it as people crucifying your coding style. Think of it as constructive criticism. On the personal front, review your code and always ask, "How could I have done it better?" This will accelerate your learning and make you a better programmer.
  14. Reminisce about your code - There are two ways to looking at old code: "I can't believe I wrote this code" and "I can't believe I wrote this code." The first statement is often of disgust and wondering how you can improve it. You'd be surprised at how old code can be resurrected into a possible and better routine, or maybe even an entire product. The second statement is of amazement and achievement. Developers have their one or two project code achievements that they completed and had everyone standing up and taking notice. Again, based on your excellent coding ability, you could take those past routines or projects and update them into a better product or idea.
  15. Humor is necessary - In my 20 years of development, I have never met a programmer who hasn't had a decent sense of humor. Actually, in this industry, it's a requirement.
  16. Beware the know-it-all, possessive coder, and the inexperienced coder - Humble yourself when you meet these types of coders. The know-it-all tries to upstage you instead of working as a team player, the defensive coder created code that he doesn't want to share with anyone, and the inexperienced coder constantly asks for assistance every ten minutes where the finished code developed is yours, not theirs.
  17. No project is ever simple - I've been asked by friends, family, and associates to just "whip something up for me." To "whip" up a program or web site, it takes planning from both parties to complete something that both sides can appreciate. If someone needs a 3-page web site with Microsoft Access from the start, it winds up becoming a 15-page web site with SQL Server, a forum, and a custom CMS (Content Management System).
  18. Never take anything for granted - If you take on a simple project, you may think that a certain section will be easy to complete. Don't think that even for a moment. Unless you have a class, component, or piece of code already coded...and has been tested thoroughly...and is in production from an existing project, don't think it will be easy.
  19. Software is never finished - A fellow programmer once told me that software is never finished, it's "temporarily completed." Sound advice. If the client is still using a program you wrote and has stood the test of time, chances are, you are still updating it, which isn't a bad thing. It keeps you working. :-)
  20. Patience is definitely a virtue - When clients, friends, or family members use a PC, they get frustrated and proceed to hit a component of the PC or storm off. I keep telling everyone, "you are controlling the computer not the other way around." You need to have a certain level of patience for programming computers. As soon as programmers understand what they did wrong, they look at it from the computers point of view and say, "Oh, that's why it was doing that."

November 10, 2010

What make code "looks" more professional?

author: Micheal Lu

这么题目看起来就比较有争议:运行起来专业的代码才专业嘛。但是从另外一个角度来说"让代码看上去比较专业"是一个积极的做法,无论对谁都没有坏处,对工程师,管理者和用户都有益无弊。

 首先这个题目说的是"看上去",所以我不会说明如何使代码真正专业。世界上有很多的书籍和文章告诉软件工程师如何写出专业的代码。如果要说"什么样的代码看上去比较专业?"那就要定义什么是专业的代码。嗯,关于这点我不能下一个准确的定义。那么可以这样,大家可以参考一些大家共认的专业代码。对于Java JDK代码来说几乎没人会否认它是专业的代码。或者一些很有影响力的open source代码,像Spring 和Apache 的代码。当然很多商业软件的代码也是很专业,但是我们看不到,或者说这不是共认的专业代码。

   * 最显而易见的做法是充足的代码注释 和标准缩进 的格式。但是大家一致认为这是最明显的因素。

   * 然后是命名规范 。有人曾经在网上展示自己的一个framework的代码,framework自然是很牛的东西。但是接下来马上有人回帖"我一看到大写开头的方法名,我就没兴趣了"。这是个很典型的例子。

       命名规范里面用拼音 做包名,类名,方法和变量名字也会使代码看上去感觉比较差。我说的是代码,不是注释。

   * 还有就是要用最新的语言特性 。对于Java,譬如要用Annotaion, Generic。虽然这些特性已经出现很多年了。至少要用@Override 一下吧。我知道大家知道用Annotaion, Generic的真正的益处。

   * 尽量不要用Magic number 。如果一看到到处都是"id".equals(...); if(i==356). ..大家就会感觉不好。

   * 还有就是最好包含单元测试 的代码,JUnit 已经成为Java的公认单元测试工具。很多开发人员认为对于一个严肃的程序,单元测试是必需的。

   * 避免冗长的方法和类。我知道大家深受其害。

 其实我认为"看上去"专业能促进代码质量。充足的代码注释和标准缩进的格式能增强可读性,另外在撰写注释的时候也是在"拷问"自己的代码,如果你觉得某个方法的注释很难写,那就要问问自己的这个方法的代码逻辑写得不够清晰。有时候在注释方法的@throws XXXException 的时候,你才会仔细考虑哪些Exception会在什么情况下被抛出。@Override 能够避免低级打字错误。Generic容器比较安全等等。

 从代码演变的角度来说,有个明显的"破窗理论"在起作用。就是越是难看的代码,在它的演化过程中会越来越差。因为当你看到你要bugfix的代码很乱,那么在bugfix的时候一般也会草草了事。一个方法有400行,在修改这个方法的时候大家不会在意再加上几十行代码。因为它看起来很差,它就是很差,我没必要美化它。反过来说,如果待改的代码很整洁很规范,那么修改者也会比较小心。这不是绝对,只是一般情况。一定有很帅的工程师把很难看的代码改得很整洁,也一定有很无畏的工程师在很好的代码上面乱改,这就是生活:)

Susan Sontag: a letter to Borges

13 June 1996 New York
Dear Borges,

Since your literature was always placed under the sign of eternity, it doesn't seem too odd to be addressing a letter to you. (Borges, it's 10 years!) If ever a contemporary seemed destined for literary immortality, it was you. You were very much the product of your time, your culture, and yet you knew how to transcend your time, your culture, in ways that seem quite magical. This had something to do with the openness and generosity of your attention. You were the least egocentric, the most transparent of writers, as well as the most artful. It also had something to do with a natural purity of spirit. Though you lived among us for a rather long time, you perfected practices of fastidiousness and of detachment that made you an expert mental traveller to other eras as well. You had a sense of time that was different from other people's. The ordinary ideas of past, present and future seemed banal under your gaze. You liked to say that every moment of time contains the past and the future, quoting (as I  remember) the poet Browning, who wrote something like, "the present is the instant in which the future crumbles into the past.'' That, of course, was part of your modesty: your taste for finding your ideas in the ideas of other writers.

Your modesty was part of the sureness of your presence. You were a discoverer of new joys. A pessimism as profound, as serene, as yours did not need to be indignant. It had, rather, to be inventive – and you were, above all, inventive. The serenity and the transcendence of self that you found are to me exemplary. You showed that it is not necessary to be unhappy, even while one is clear-eyed and undeluded about how terrible everything is. Somewhere you said that a writer–delicately you added: all persons – must think that whatever happens to him or her is a resource. (You were speaking of your blindness.) You have been a great resource, for other writers. In 1982 – that is, four years before you died – I said in an interview, "There is no writer living today who matters more to other writers than Borges. Many people would say he is the greatest living writer... Very few writers of today have not learnt from him or imitated him.''

That is still true. We are still learning from you. We are still imitating you. You gave people new ways of imagining, while proclaiming over and over our indebtedness to the past, above all, to literature. You said that we owe literature almost everything we are and what we have been. If books disappear, history will disappear, and human beings will also disappear. I am sure you are right. Books are not only the arbitrary sum of our dreams, and our memory. They also give us the model of self-transcendence. Some people think of reading only as a kind of escape: an escape from the "real'' everyday world to an imaginary world, the world of books. Books are much more. They are a way of being fully human.

I'm sorry to have to tell you that books are now considered an endangered species. By books, I also mean the conditions of reading that make possible literature and its soul effects. Soon, we are told, we will call up on "bookscreens'' any "text'' on demand, and will be able to change its appearance, ask questions of it, "interact'' with it. When books become "texts'' that we "interact'' with according to criteria of utility, the written word will have become simply another aspect of our advertising-driven televisual reality. This is the glorious future being created, and promised to us, as something more "democratic''. Of course, it means nothing less then the death of inwardness – and of the book.

This time around, there will be no need for a great conflagration. The barbarians don't have to burn the books. The tiger is in the library. Dear Borges, please understand that it gives me no satisfaction to complain. But to whom could such complaints about the fate of books–of reading itself – be better addressed than to you? (Borges, it's 10 years!) All I mean to say is that we miss you. I miss you. You continue to make a difference. The era we are entering now, this 21st century, will test the soul in new ways. But, you can be sure, some of us are not going to abandon the Great Library. And you will continue to be our patron and our hero.

Extracted from 'Where the Stress Falls' by Susan Sontag (Jonathan Cape, £17.99).

Days of our lives

Daisypath Anniversary tickers