Translated on 2016-11-25 by Google Neuralnet Machine Translation
Lisp in Web-Based Applications
WebããŒã¹ã®ã¢ããªã±ãŒã·ã§ã³ã«ãããLisp
Paul Graham
ããŒã«ã°ã©ãã
(This is an excerpt of a talk given at BBN Labs in Cambridge, MA, in April 2001.)
ïŒããã¯2001幎4æãã±ã³ããªããžã®BBN Labsã§è¬æŒãããè¬æŒã®æç²ã§ãïŒ
Any Language You Want
ããªããæããã¹ãŠã®èšèª
One of the reasons to use Lisp in writing Web-based applications is that you can use Lisp. When youâre writing software that is only going to run on your own servers, you can use whatever language you want.
WebããŒã¹ã®ã¢ããªã±ãŒã·ã§ã³ãæžãéã«Lispã䜿ãçç±ã®1ã€ã¯ãLispã䜿ãããšãã§ãããšããããšã§ãã ããªãèªèº«ã®ãµãŒããŒäžã§å®è¡ãããã ãã®ãœãããŠã§ã¢ãæžããšãã¯ãã©ããªèšèªã§ã䜿ããŸãã
For a long time programmers didnât have a lot of choice about what language to use for writing application programs. Until recently, writing application programs meant writing software to run on desktop computers. In desktop software there was a strong bias toward writing the application in the same language as the operating system. Ten years ago, for all practical purposes, applications were written in C.
é·ãéãããã°ã©ããŒã¯ãã¢ããªã±ãŒã·ã§ã³ããã°ã©ã ã®äœæã«ã©ã®èšèªã䜿çšãããã«ã€ããŠå€ãã®éžæè¢ããããŸããã§ããã æè¿ãŸã§ãã¢ããªã±ãŒã·ã§ã³ããã°ã©ã ãæžãããšã¯ããã¹ã¯ãããã³ã³ãã¥ãŒã¿äžã§å®è¡ãããœãããŠã§ã¢ãæžãããšãæå³ããŠããŸããã ãã¹ã¯ããããœãããŠã§ã¢ã§ã¯ããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãšåãèšèªã§ã¢ããªã±ãŒã·ã§ã³ãæžãããšã«åŒ·ããã€ã¢ã¹ããããŸããã 10幎åããã¹ãŠã®å®çšçãªç®çã®ããã«ãã¢ããªã±ãŒã·ã§ã³ã¯Cèšèªã§æžãããŸããã
With Web-based applications, that changes. You control the servers, and you can write your software in any language you want. You can take it for granted now that you have the source code of both your operating system and your compilers. If there does turn out to be any kind of problem between the language and the OS, you can fix it yourself.
WebããŒã¹ã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ããããå€åããŸãã ããªãã¯ãµãŒããŒãå¶åŸ¡ããå¿ èŠãªèšèªã§ãœãããŠã§ã¢ãæžãããšãã§ããŸãã ããªãã¯ããªãã®ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãšã³ã³ãã€ã©ã®äž¡æ¹ã®ãœãŒã¹ã³ãŒããæã«å ¥ããã®ã§ãããã¯åœç¶ã®ããšã§ãã èšèªãšOSã®éã«äœããã®åé¡ãçºçããå Žåã¯ãèªåã§ä¿®æ£ããããšãã§ããŸãã
This new freedom is a double-edged sword, however. Having more choices means that you now have to think about which choice to make. It was easier in the old days. If you were in charge of a software project, and some troublesome person suggested writing the software in a different language from whatever you usually used, you could just tell them that it would be impractical, and that would be the end of it.
ãããããã®æ°ããèªç±ã¯äž¡åã®å£ã§ãã ããå€ãã®éžæè¢ããããšããããšã¯ãããªããä»ã©ã®éžæããããã«ã€ããŠèããå¿ èŠãããããšãæå³ããŸãã ããã¯æã®ã»ããç°¡åã§ããã ããªãããœãããŠã§ã¢ãããžã§ã¯ããæ åœããŠããŠãé¢åãªäººã®äžã«ã¯ãé垞䜿çšããŠããèšèªãšã¯ç°ãªãèšèªã§ãœãããŠã§ã¢ãæžãããšãææ¡ãããŠããã°ãå®çšçã§ã¯ãªããšèšãããããããŸããã
Now, with server-based applications, everything is changed. Youâre now subject to market forces in what language you choose. If you try to pretend that nothing has changed, and just use C and C++, like most of our competitors did, you are setting yourself up for a fall. A little startup using a more powerful language will eat your lunch.
çŸåšããµãŒããŒããŒã¹ã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ããã¹ãŠã倿ŽãããŠããŸãã ããªãã¯çŸåšãããªããéžãã èšèªã§åžå Žã®åã«æããŠããŸãã äœãå€ãã£ãŠããªããšæã£ãŠãCãC ++ã䜿ãã ããªããã»ãšãã©ã®ç«¶åä»ç€Ÿãšåãããã«ã ããªãã¯ç§ã®ããã«èªåèªèº«ãèšå®ããŠããŸãã ãã匷åãªèšèªã䜿çšããŠå°ãã¹ã¿ãŒãã¢ããã¯ããªãã®ã©ã³ããé£ã¹ãã§ãããã
Incremental Development
ã€ã³ã¯ãªã¡ã³ã¿ã«éçº
There is a certain style of software development associated with Lisp. One of its traditions is incremental development: you start by writing, as quickly as possible, a program that does almost nothing. Then you gradually add features to it, but at every step you have working code.
Lispã«ã¯ããçš®ã®ãœãããŠã§ã¢éçºã¹ã¿ã€ã«ããããŸãã ãã®äŒçµ±ã®äžã€ã¯ã挞é²çãªéçºã§ããããªãã¯ã§ããã ãæ©ããã»ãšãã©äœãããªãããã°ã©ã ãæžãããšããå§ãŸããŸãã ãã®åŸåŸã ã«æ©èœã远å ããŸããããã¹ãŠã®ã¹ãããã§äœæ¥ã³ãŒãããããŸãã
I think this way you get better software, written faster. Everything about Lisp is tuned to this style of programming, because Lisp programmers have worked this way for at least thirty years.
ç§ã¯ããªããããéãæžãããããè¯ããœãããŠã§ã¢ãåŸããã®æ¹æ³ã ãšæããŸãã Lispã®ããã°ã©ãã¯å°ãªããšã30幎éãã®æ¹æ³ã§äœæ¥ããŠããã®ã§ãLispã«é¢ãããã¹ãŠã®ããšããã®ã¹ã¿ã€ã«ã®ããã°ã©ãã³ã°ã«èª¿æŽãããŠããŸãã
The Viaweb editor must be one of the most extreme cases of incremental development. It began with a 120-line program for generating Web sites that I had used in an example in a book that I finished just before we started Viaweb. The Viaweb editor, which eventually grew to be about 25,000 lines of code, grew incrementally from this program. I never once sat down and rewrote the whole thing. I donât think I was ever more than a day or two without running code. The whole development process was one long series of gradual changes.
Viawebãšãã£ã¿ã¯ãã€ã³ã¯ãªã¡ã³ã¿ã«éçºã®æã極端ãªã±ãŒã¹ã®1ã€ã§ãªããã°ãªããŸããã ããã¯ãç§ãViawebãå§ããçŽåã«å®æããæ¬ã®äŸã§äœ¿ã£ãWebãµã€ããçæããããã®120è¡ã®ããã°ã©ã ããå§ãŸããŸããã æçµçã«çŽ25,000è¡ã«æ¡å€§ããViawebãšãã£ã¿ã¯ããã®ããã°ã©ã ããæ®µéçã«æé·ããŸããã ç§ã¯äžåºŠåº§ã£ãŠå šäœãæžãçŽããããšã¯ãããŸããã ç§ã¯ã³ãŒããå®è¡ããŠããªã1æ¥ã2æ¥ä»¥äžã¯ãªãã£ããšæããŸãã å šäœã®éçºããã»ã¹ã¯ãåŸã ã«å€åããé·ãäžé£ã®ãã®ã§ããã
This style of development fits well with the rolling releases that are possible with Web-based software. Itâs also a faster way to get software written generally.
ãã®ãããªéçºã¹ã¿ã€ã«ã¯ãWebããŒã¹ã®ãœãããŠã§ã¢ã§å¯èœãªããŒãªã³ã°ãªãªãŒã¹ã«é©ããŠããŸãã ãŸãããœãããŠã§ã¢ãäžè¬çã«æžãããã®ããéãæ¹æ³ã§ãã
Interactive Toplevel
ã€ã³ã¿ã©ã¯ãã£ããããã¬ãã«
Lispâs interactive toplevel is a great help in developing software rapidly. But the biggest advantage for us was probably in finding bugs. As I mentioned before, with Web-based applications you have the usersâ data on your servers and can usually reproduce bugs.
Lispã®ã€ã³ã¿ã©ã¯ãã£ããªãããã¬ãã«ã¯ããœãããŠã§ã¢ãæ¥éã«éçºãã倧ããªå©ããšãªããŸãã ããããç§ãã¡ã®æå€§ã®ã¡ãªããã¯ãããããã°ãçºèŠããããšã§ããã å ã«è¿°ã¹ãããã«ãWebããŒã¹ã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ããµãŒããŒäžã«ãŠãŒã¶ãŒã®ããŒã¿ããããéåžžã¯ãã°ãåçŸã§ããŸãã
When one of the customer support people came to me with a report of a bug in the editor, I would load the code into the Lisp interpreter and log into the userâs account. If I was able to reproduce the bug Iâd get an actual break loop, telling me exactly what was going wrong. Often I could fix the code and release a fix right away. And when I say right away, I mean while the user was still on the phone.
顧客ãµããŒãæ åœè ã®1人ããšãã£ã¿ã§ãã°ã®å ±åãåããŠç§ã«æ¥ããšããç§ã¯ãã®ã³ãŒããLispã€ã³ã¿ããªã¿ã«ããŒããããŠãŒã¶ã®ã¢ã«ãŠã³ãã«ãã°ã€ã³ããŸãã ãã°ãåçŸã§ããããå®éã®ãã¬ãŒã¯ã«ãŒããçºçããäœãããŸããããªãã®ãæ£ç¢ºã«æããŠãããŸãã ãã°ãã°ãã³ãŒããä¿®æ£ããŠçŽã¡ã«ä¿®æ£ããªãªãŒã¹ããããšãã§ããŸããã ç§ãããã«èšããšããç§ã¯ãŠãŒã¶ãŒããŸã é»è©±ã«ããéã«æå³ããã
Such fast turnaround on bug fixes put us into an impossibly tempting position. If we could catch and fix a bug while the user was still on the phone, it was very tempting for us to give the user the impression that they were imagining it. And so we sometimes (to their delight) had the customer support people tell the user to just try logging in again and see if they still had the problem. And of course when the user logged back in theyâd get the newly released version of the software with the bug fixed, and everything would work fine. I realize this was a bit sneaky of us, but it was also a lot of fun.
ãã®ãããªãã°ä¿®æ£ã®è¿ éãªååž°ã¯ãç§ãã¡ãéåžžã«é åçãªç«å Žã«é¥ããŸããã ãŠãŒã¶ãŒããŸã é»è©±ããããŠããéã«ãã°ãèŠã€ããŠä¿®æ£ã§ããã°ããŠãŒã¶ãŒã«æ³åããŠãããããªå°è±¡ãäžããããšãéåžžã«é åçã§ããã ãããŠãæã«ã¯ïŒåãã§ïŒé¡§å®¢ãµããŒãæ åœè ããŠãŒã¶ãŒã«å床ãã°ã€ã³ããŠãããŸã åé¡ããããã©ããã確èªããããã«æç€ºããããšããããŸããã ãã¡ããããŠãŒã¶ãŒããã°ã€ã³ãããšãã«ããã°ãä¿®æ£ããã°ããã®æ°ãããªãªãŒã¹ãããããŒãžã§ã³ã®ãœãããŠã§ã¢ãå ¥æãããšããã¹ãŠæ£åžžã«åäœããŸãã ç§ã¯ãããç§ãã¡ã®ã¡ãã£ãšåå£ã ã£ãããšãçè§£ããŠããŸãããããã¯ãŸããšãŠã楜ãããã®ã§ããã
Macros for Html
HTMLçšãã¯ã
Lisp macros were another big win for us. We used them very extensively in the Viaweb editor. It could accurately be described as one big macro. And that gives you an idea of how much we depended on Lisp, because no other language has macros in the sense that Lisp does.
Lispãã¯ãã¯ç§ãã¡ã®ããäžã€ã®å€§ããªåå©ã§ããã ç§ãã¡ã¯Viawebãšãã£ã¿ã§éåžžã«å¹ åºã䜿çšããŸããã ããã¯æ£ç¢ºã«1ã€ã®å€§ããªãã¯ããšããŠèšè¿°ããããšãã§ããŸãã ãããŠããã¯Lispã«ã©ããããäŸåããŠããã®ããç¥ãããšãã§ããŸãããªããªããä»ã®èšèªã«ã¯Lispã®æå³ã§ã®ãã¯ãããªãããã§ãã
One way we used macros was to generate Html. There is a very natural fit between macros and Html, because Html is a prefix notation like Lisp, and Html is recursive like Lisp. So we had macro calls within macro calls, generating the most complicated Html, and it was all still very manageable.
ãã¯ãã䜿çšããäžã€ã®æ¹æ³ã¯ãHtmlãçæããããšã§ããã Htmlã¯Lispã®ãããªæ¥é èŸè¡šèšã§ãããHtmlã¯Lispã®ããã«ååž°çã§ããã®ã§ããã¯ããšHtmlã®éã«ã¯éåžžã«èªç¶ãªé©åããããŸãã ã ããç§ãã¡ã¯ãã¯ãåŒã³åºãã®äžã§ãã¯ãåŒã³åºããè¡ããæãè€éãªHTMLãçæããŸããã
Embedded Languages
åã蟌ã¿èšèª
Another big use for macros was the embedded language we had for describing pages, called Rtml. (We made up various explanations for what Rtml was supposed to stand for, but actually I named it after Robert Morris, the other founder of Viaweb, whose username is Rtm.)
ãã¯ãã®ãã1ã€ã®å€§ããªçšéã¯ãRtmlãšããããŒãžãèšè¿°ããããã®åã蟌ã¿èšèªã§ããã ïŒç§ãã¡ã¯ãRtmlãäœãæå³ãããã«ã€ããŠæ§ã ãªèª¬æãããŸããããå®éã«ã¯ãŠãŒã¶ãŒåãRtmã®Viawebã®åµèšè ã§ããRobert Morrisã®ååãä»ããŸããïŒã
Every page made by our software was generated by a program written in Rtml. We called these programs templates to make them less frightening, but they were real programs. In fact, they were Lisp programs. Rtml was a combination of macros and the built-in Lisp operators.
ç§ãã¡ã®ãœãããŠã§ã¢ã«ãã£ãŠäœããããã¹ãŠã®ããŒãžã¯ãRtmlã§æžãããããã°ã©ã ã«ãã£ãŠçæãããŸããã ç§ãã¡ã¯ãããã®ããã°ã©ã ãã³ãã¬ãŒãããããã»ã©æããããã®ã«ããªãããã«åŒã³ãŸããããå®éã®ããã°ã©ã ã§ããã å®éã圌ãã¯Lispããã°ã©ã ã§ããã Rtmlã¯ãã¯ããšçµã¿èŸŒã¿ã®LispæŒç®åã®çµã¿åããã§ãã
Users could write their own Rtml templates to describe what they wanted their pages to look like. We had a structure editor for manipulating these templates, a lot like the structure editor they had in Interlisp. Instead of typing free-form text, you cut and pasted bits of code together. This meant that it was impossible to get syntax errors. It also meant that we didnât have to display the parentheses in the underlying s-expressions: we could show structure by indentation. By this means we made the language look a lot less threatening.
ãŠãŒã¶ãŒã¯èªåã®ããŒãžãã©ã®ããã«èŠãããããèšè¿°ããç¬èªã®Rtmlãã³ãã¬ãŒããæžãããšãã§ããŸãã ãããã®ãã³ãã¬ãŒããæäœããããã®æ§é ãšãã£ã¿ããããŸãã.Interlispã§äœ¿çšããŠããæ§é ãšãã£ã¿ãšãã䌌ãŠããŸãã èªç±åœ¢åŒã®ããã¹ããå ¥åããã®ã§ã¯ãªããè€æ°ã®ã³ãŒããã«ããã¢ã³ãããŒã¹ãããŸãã ããã¯ãæ§æãšã©ãŒãåŸãããšãäžå¯èœã§ããããšãæå³ããŸããã ãŸããåºç€ãšãªãsåŒã«ãã£ãã衚瀺ããå¿ èŠããªãããšãæå³ããŸãããåäžãã«ãã£ãŠæ§é ã衚瀺ããããšãã§ããŸããã ããã«ãããç§ãã¡ã¯èšèªã®èŠãç®ãããŸãè ãããªãããã«ããŸããã
We also designed Rtml so that there could be no errors at runtime: every Rtml program yielded some kind of Web page, and you could debug it by hacking it until it produced the page you meant it to.
ãŸããå®è¡æã«ãšã©ãŒãçºçããªãããã«RtmlãèšèšããŸããããã¹ãŠã®Rtmlããã°ã©ã ã¯äœããã®WebããŒãžãçæãããããããã¯ããŠãããã°ããããšã§ãæå³ããããŒãžãçæããŸãã
Initially we expected our users to be Web consultants, and we expected them to use Rtml a lot. We provided some default templates for section pages and item pages and so on, and the idea was that the users could take them and modify them to make whatever pages they wanted.
åœåã¯ããŠãŒã¶ãŒãWebã³ã³ãµã«ã¿ã³ãã«ãªãããšãæåŸ ããŠããŸããããRtmlãå€ã䜿çšããããšãæåŸ ããŠããŸããã ã»ã¯ã·ã§ã³ããŒãžãã¢ã€ãã ããŒãžãªã©ã®ããã©ã«ãã®ãã³ãã¬ãŒããããã€ãçšæããŸããããŠãŒã¶ãŒã¯ããããæã£ãŠããŠãå¿ èŠãªããŒãžãäœæã§ããããã«å€æŽããããšãã§ããŸããã
In fact it turned out that Web consultants didnât like Viaweb. Consultants, as a general rule, like to use products that are too hard for their clients to use, because it guarantees them ongoing employment. Consultants would come to our Web site, which said all over it that our software was so easy to use that it would let anyone make an online store in five minutes, and theyâd say, thereâs no way weâre using that. So we didnât get a lot of interest from Web consultants. Instead the users all tended to be end-users, the actual merchants themselves. They loved the idea of being in control of their own Web sites. And this kind of user did not want to do any kind of programming. They just used the default templates.
å®éãWebã³ã³ãµã«ã¿ã³ãã¯Viawebã奜ãŸãªãã£ãããšã倿ããŸããã ã³ã³ãµã«ã¿ã³ãã¯ãååãšããŠãç¶ç¶çãªéçšãä¿èšŒããããã顧客ã䜿çšããã«ã¯ããŸãã«ãå°é£ãªè£œåã䜿çšããããšã奜ãã ã³ã³ãµã«ã¿ã³ãã¯ç§ãã¡ã®ãŠã§ããµã€ãã«æ¥ãŠãç§ãã¡ã®ãœãããŠã§ã¢ã¯èª°ãã5åã§ãªã³ã©ã€ã³ã¹ãã¢ãäœããããã«äœ¿ãããããããã䜿çšããæ¹æ³ã¯ãªããšèšã£ãŠããŸãã ã ããæã ã¯Webã³ã³ãµã«ã¿ã³ãããå€ãã®é¢å¿ãåŸãŠããªãã ãã®ä»£ããã«ããŠãŒã¶ãŒã¯ãã¹ãŠå®éã®è²©å£²è ã§ãããšã³ããŠãŒã¶ãŒã§ããåŸåããããŸããã 圌ãã¯èªåã®Webãµã€ãã管çãããšããèããæããŠããŸããã ãããŠããã®çš®ã®ãŠãŒã¶ãŒã¯ã©ããªçš®é¡ã®ããã°ã©ãã³ã°ãããããªãã£ãã 圌ãã¯ã¡ããã©ããã©ã«ããã³ãã¬ãŒãã䜿çšããŸããã
So Rtml didnât end up being the main interface to the program. It ended up playing two roles. First of all, it was an escape valve for the really sophisticated users, who wanted something our built-in templates couldnât provide. Somewhere in the course of doing Viaweb, someone gave me a very useful piece of advice: users always want an upgrade path, even though as a rule theyâll never take it. Rtml was our upgrade path. If you wanted to, you could get absolute control over everything on your pages.
ã ããRtmlã¯ããã°ã©ã ã®äž»ãªã€ã³ã¿ãŒãã§ãŒã¹ã«ãªã£ãããã§ã¯ãããŸããã ããã¯2ã€ã®åœ¹å²ãæãããã ãŸããæ¬åœã«æŽç·ŽããããŠãŒã¶ãŒã®ããã®ãšã¹ã±ãŒããã«ãã§ããããç§ãã¡ã®çµã¿èŸŒã¿ã®ãã³ãã¬ãŒãã§ã¯æäŸã§ããªãã£ãããšãæãã§ããŸããã Viawebããã£ãŠããéäžã§ã誰ããç§ã«éåžžã«æçšãªã¢ããã€ã¹ããããŸããããŠãŒã¶ãŒã¯åžžã«ã¢ããã°ã¬ãŒãã®éãæ±ããŠããŸãã Rtmlãç§ãã¡ã®ã¢ããã°ã¬ãŒããã¹ã§ããã ããªãããããå Žåã¯ãããªãã®ããŒãžã®ãã¹ãŠãå®å šã«å¶åŸ¡ããããšãã§ããŸãã
Only one out of every couple hundred users actually wrote their own templates. And this led to the second advantage of Rtml. By looking at the way these users modified our built-in templates, we knew what we needed to add to them. Eventually we made it our goal that no one should ever have to use Rtml. Our built-in templates should do everything people wanted. In this new approach, Rtml served us as a warning sign that something was missing in our software.
æ°çŸäººã«1人ã®ãŠãŒã¶ãŒããå®éã«èªåã®ãã³ãã¬ãŒããæžããŸããã§ããã ãããŠãããRtmlã®ç¬¬2ã®å©ç¹ã«ã€ãªãã£ãã ãããã®ãŠãŒã¶ãŒãçµã¿èŸŒã¿ã®ãã³ãã¬ãŒãã倿Žããæ¹æ³ãèŠãããšã§ã远å ããå¿ èŠããã£ãããšãããããŸããã æçµçã«ç§ãã¡ã¯èª°ãRtmlã䜿ãå¿ èŠããªããšããç®æšãéæããŸããã ç§ãã¡ã®çµã¿èŸŒã¿ã®ãã³ãã¬ãŒãã¯ã人ã ãæããã¹ãŠãå®è¡ããå¿ èŠããããŸãã ãã®æ°ããã¢ãããŒãã§ã¯ãRtmlã¯ç§ãã¡ã®ãœãããŠã§ã¢ã«äœããæ¬ ããŠãããšããèŠåå åãšããŠåœ¹ç«ã£ãŠããŸããã
The third and biggest win from using Rtml was the advantage we ourselves got from it. Even if we had been the only people who used Rtml, it would have been very much worth while writing the software that way. Having that extra layer of abstraction in our software gave us a big advantage over competitors. It made the design of our software much cleaner, for one thing. Instead of just having bits of actual C or Perl code that generated our Web pages, like our competitors, we had a very high-level language for generating Web pages, and our page styles specified in that. It made the code much cleaner and easier to modify. Iâve already mentioned that Web-based applications get released as a series of many small modifications. When you do that you want to be able to know how serious any given modification is. By dividing your code into layers, you get a better handle on this. Modifying stuff in lower layers (Rtml itself) was a serious matter to be done rarely, and after much thought. Whereas modifying the top layers (template code) was something you could do quickly without worrying too much about the consequences.
Rtmlã䜿çšããããšãã3çªç®ã«å€§ããªå©çãåŸãã®ã¯ãç§ãã¡èªèº«ãåŸãå©ç¹ã§ãããç§ãã¡ãRtmlã䜿ã£ãå¯äžã®äººã§ãã£ããšããŠãããã®ãããªæ¹æ³ã§ãœãããŠã§ã¢ãæžãã®ã¯éåžžã«äŸ¡å€ããã£ãã§ãããããœãããŠã§ã¢ã§ãã®ãããªæœè±¡ã¬ã€ã€ãŒã远å ããããšã§ãç«¶åä»ç€Ÿã«åã倧ããªå©ç¹ãããããããŸãããããã¯ãç§ãã¡ã®ãœãããŠã§ã¢ã®èšèšããã£ãšãããã«ããŸããã WebããŒãžãçæããå®éã®Cã³ãŒããPerlã³ãŒããç«¶åä»ç€Ÿãšåãããã«äœ¿ãã®ã§ã¯ãªããWebããŒãžãçæããããã®éåžžã«é«åºŠãªèšèªãšãã®ããŒãžã¹ã¿ã€ã«ãæå®ããŸãããã³ãŒããããã¯ãªãŒã³ã§ç°¡åã«ä¿®æ£ã§ããŸããã WebããŒã¹ã®ã¢ããªã±ãŒã·ã§ã³ã¯ãäžé£ã®å€ãã®å°ããªå€æŽãšããŠãªãªãŒã¹ããããšç§ã¯ãã§ã«è¿°ã¹ãŸãããããªãããããããšããããªãã¯äžããããä¿®æ£ãã©ããªã«æ·±å»ã§ããããç¥ãããšãã§ããããã«ããããšæã£ãŠããŸããã³ãŒããã¬ã€ã€ãŒã«åå²ããããšã§ããããããããåŠçã§ããŸããäžå±€ïŒRtmlèªäœïŒã®ãã®ã倿Žããããšã¯ããŸãã«ãããããããªãæ·±å»ãªåé¡ã§ããããããã¬ã€ã€ãŒïŒãã³ãã¬ãŒãã³ãŒãïŒã倿Žããããšã¯ãçµæã«ã¯ããŸãå¿é ããããšãªãããã°ããè¡ãããšãã§ããŸããã
Rtml was a very Lispy proposition. It was mostly Lisp macros, to start with. The online editor was, behind the scenes, manipulating s-expressions. And when people ran templates, they got compiled into Lisp functions by calling compile at runtime.
Rtmlã¯éåžžã«Lispyã®åœé¡ã§ããã ããã¯äž»ã«Lispã®ãã¯ãã§ãã£ãã ãªã³ã©ã€ã³ãšãã£ã¿ã¯ãèå°è£ã§såŒãæäœããŠããŸããã ãã³ãã¬ãŒããå®è¡ãããšãå®è¡æã«compileãåŒã³åºãããšã§Lisp颿°ã«ã³ã³ãã€ã«ãããŸããã
Rtml even depended heavily on keyword parameters, which up to that time I had always considered one of the more dubious features of Common Lisp. Because of the way Web-based software gets released, you have to design the software so that itâs easy to change. And Rtml itself had to be easy to change, just like any other part of the software. Most of the operators in Rtml were designed to take keyword parameters, and what a help that turned out to be. If I wanted to add another dimension to the behavior of one of the operators, I could just add a new keyword parameter, and everyoneâs existing templates would continue to work. A few of the Rtml operators didnât take keyword parameters, because I didnât think Iâd ever need to change them, and almost every one I ended up kicking myself about later. If I could go back and start over from scratch, one of the things Iâd change would be that Iâd make every Rtml operator take keyword parameters.
Rtmlã¯ããŒã¯ãŒããã©ã¡ãŒã¿ã«å€§ããäŸåããŠããŸãããç§ã¯ãããŸã§ãCommon Lispã®ããæªãããªæ©èœã®1ã€ãšèããŠããŸããã WebããŒã¹ã®ãœãããŠã§ã¢ããªãªãŒã¹ãããããã倿Žããã®ãç°¡åã«ãªãããã«ãœãããŠã§ã¢ãèšèšããå¿ èŠããããŸãã ãããŠRtmlèªäœã¯ããœãããŠã§ã¢ã®ä»ã®éšåãšåæ§ã«ãç°¡åã«å€æŽããããšãã§ããªããã°ãªããŸããã§ããã Rtmlã®æŒç®åã®ã»ãšãã©ã¯ãããŒã¯ãŒããã©ã¡ãŒã¿ãåãããã«èšèšãããŠãããäœãå©ãã«ãªã£ãŠããããåãããŸããã æŒç®åã®1ã€ã®æ¯ãèãã«å¥ã®æ¬¡å ã远å ãããå Žåã¯ãæ°ããããŒã¯ãŒããã©ã¡ãŒã¿ã远å ããã ãã§æžã¿ãŸããæ¢åã®ãã³ãã¬ãŒãããã¹ãŠåäœãç¶ããŸãã RtmlæŒç®åã®ããã€ãã¯ãããŒã¯ãŒãã®ãã©ã¡ãŒã¿ãåã£ãŠããŸããã§ããããªããªããç§ã¯ãããã倿Žããå¿ èŠã¯ãªããšæã£ãŠããããã§ãã ç§ãæåããããçŽãããšãã§ããã°ãç§ãå€ããã¹ãããšã®1ã€ã¯ããã¹ãŠã®Rtmlãªãã¬ãŒã¿ã«ããŒã¯ãŒããã©ã¡ãŒã¿ãåãããããšã§ãã
We had a couple embedded languages within the editor, in fact. Another one, which we didnât expose directly to the users, was for describing images. Viaweb included an image generator, written in C, that could take a description of an image, create that image, and return its url. We used s-expressions to describe these images as well.
å®éããšãã£ã¿å ã«çµã¿èŸŒã¿ã®èšèªãããã€ããããŸããã ç§ãã¡ããŠãŒã¶ãŒã«çŽæ¥å ¬éããŠããªãã£ããã1ã€ã¯ãç»åãèšè¿°ããããšã§ããã Viawebã«ã¯ãCã§æžãããç»åãžã§ãã¬ãŒã¿ãå«ãŸããŠãããç»åã®èšè¿°ããã®ç»åã®äœæãããã³ãã®URLã®è¿åŽãå¯èœã§ããã ãããã®ç»åãåæ§ã«èšè¿°ããããã«såŒã䜿çšããŸããã
Closures Simulate Subroutines
ã¯ããŒãžã£ããµãã«ãŒãã³ãã·ãã¥ã¬ãŒããã
One of the problems with using Web pages as a UI is the inherent statelessness of Web sessions. We got around this by using lexical closures to simulate subroutine-like behavior. If you understand about continuations, one way to explain what we did would be to say that we wrote our software in continuation-passing style.
WebããŒãžãUIãšããŠäœ¿çšããéã®åé¡ã®1ã€ã¯ãWebã»ãã·ã§ã³ã®æ¬è³ªçãªã¹ããŒãã¬ã¹æ§ã§ãã ãããåé¿ããã«ã¯ããµãã«ãŒãã³ã®ãããªæ¯ãèããã·ãã¥ã¬ãŒãããããã«åå¥è§£æã䜿çšããŸãã ç¶ç¶ã«ã€ããŠçè§£ããŠãããªããç§ãã¡ãäœãããã®ãã説æããäžã€ã®æ¹æ³ã¯ãç§ãã¡ãç¶ç¶çã«æž¡ãã¹ã¿ã€ã«ã§ãœãããŠã§ã¢ãæžãããšèšãããšã§ãããã
When most web-based software generates a link on a page, it tends to be thinking, if the user clicks on this link, I want to call this cgi script with these arguments. When our software generated a link, it could think, if the user clicks on this link, I want to run this piece of code. And the piece of code could an arbitrary piece of code, possibly (in fact, usually) containing free variables whose value came from the surrounding context.
ã»ãšãã©ã®WebããŒã¹ã®ãœãããŠã§ã¢ãããŒãžäžã«ãªã³ã¯ãçæãããšãããŠãŒã¶ãŒããã®ãªã³ã¯ãã¯ãªãã¯ãããšããããã®åŒæ°ã䜿ã£ãŠãã®cgiã¹ã¯ãªãããåŒã³åºãããšãèããããŸãã ç§ãã¡ã®ãœãããŠã§ã¢ããªã³ã¯ãçæãããšãããŠãŒã¶ãŒããã®ãªã³ã¯ãã¯ãªãã¯ãããšããã®ã³ãŒããå®è¡ããããšæããããããŸããã ãããŠã³ãŒãéšåã¯ãåšå²ã®æèããå€ãåŸãããèªç±å€æ°ãå«ãå¯èœæ§ãããïŒå®éã«ã¯ãéåžžã¯ïŒä»»æã®ã³ãŒãã§ããå¯èœæ§ããããŸãã
The way we did this was to write a macro that took an initial argument expected to be a closure, followed by a body of code. The code would then get stored in a global hash table under a unique id, and whatever output was generated by the code in the body would appear within a link whose url contained that hash key. If that link was the next one clicked on, our software would find and call the corresponding bit of code, and the chain would continue. Effectively we were writing cgi scripts on the fly, except that they were closures that could refer to the surrounding context.
ããããã£ãããæ¹ã¯ãæåã®è°è«ãééã§ãããšäºæ³ããããã¯ããæžãããšã§ããããã®åŸã«ã³ãŒããç¶ããŸããã ã³ãŒãã¯ãäžæã®IDã®äžã«ã°ããŒãã«ããã·ã¥ããŒãã«ã«æ ŒçŽãããæ¬äœã®ã³ãŒãã«ãã£ãŠçæãããåºåã¯ããã®ããã·ã¥ããŒãå«ãURLãæã€ãªã³ã¯å ã«è¡šç€ºãããŸãã ãã®ãªã³ã¯ãã¯ãªãã¯ãããæ¬¡ã®ãªã³ã¯ã ã£ãå Žåãç§ãã¡ã®ãœãããŠã§ã¢ã¯å¯Ÿå¿ãããããã®ã³ãŒããèŠã€ããŠåŒã³åºãããã§ãŒã³ã¯ç¶è¡ãããŸãã 广çã«ãç§ãã¡ã¯ãã®å Žã§cgiã¹ã¯ãªãããæžããŠããŸããããããã¯åšå²ã®æèãåç §ã§ããã¯ããŒãžã£ãŒã§ããã
So far this sounds very theoretical, so let me give you an example of where this technique made an obvious difference. One of the things you often want to do in Web-based applications is edit an object with various types of properties. Many of the properties of an object can be represented as form fields or menus. If youâre editing an object representing a person, for example, you might get a field, for their name, a menu choice for their title, and so on.
ãããŸã§ã®ãšãããããã¯éåžžã«çè«çã«èãããã®ã§ããã®ãã¯ããã¯ãæçœãªéããçãå Žæã®äŸãæããŠãããŸãããã WebããŒã¹ã®ã¢ããªã±ãŒã·ã§ã³ã§ãã°ãã°ããããããšã®1ã€ã¯ãããŸããŸãªçš®é¡ã®ããããã£ãæã€ãªããžã§ã¯ããç·šéããããšã§ãã ãªããžã§ã¯ãã®å€ãã®ããããã£ã¯ããã©ãŒã ãã£ãŒã«ããŸãã¯ã¡ãã¥ãŒãšããŠè¡šçŸã§ããŸãã ããšãã°ã人ç©ã衚ããªããžã§ã¯ããç·šéããŠããå Žåã¯ããã£ãŒã«ãåããã®ã¿ã€ãã«ã®ã¡ãã¥ãŒéžæè¢ãªã©ãåŸãããŸãã
Now what happens when some object has a property that is a color? If you use ordinary cgi scripts, where everything has to happen on one form, with an Update button at the bottom, you are going to have a hard time. You could use a text field and make the user type an rgb number into it, but end-users donât like that. Or you could have a menu of possible colors, but then you have to limit the possible colors, or otherwise even to offer just the standard Web colormap, youâd need 256 menu items with barely distinguishable names.
ä»ãããã€ãã®ãªããžã§ã¯ããè²ã§ããããããã£ãæã£ãŠãããšã©ããªããŸããïŒ éåžžã®cgiã¹ã¯ãªããã䜿çšããå Žåã¯ãäžçªäžã®ãæŽæ°ããã¿ã³ã䜿çšããŠãã¹ãŠã1ã€ã®ãã©ãŒã ã§å®è¡ããå¿ èŠããããŸããå°é£ãªå ŽåããããŸãã ããã¹ããã£ãŒã«ãã䜿çšããŠããŠãŒã¶ãããã«rgbçªå·ãå ¥åãããããšãã§ããŸããããšã³ããŠãŒã¶ã¯ãããæ°ã«å ¥ããªãããšãã§ããŸãã ãŸãã¯å¯èœãªè²ã®ã¡ãã¥ãŒãæã€ããšãã§ããŸãããå¯èœãªè²ãå¶éããå¿ èŠããããŸããããã§ãªããã°ãæšæºã®Webã«ã©ãŒãããã ããæäŸããå Žåã§ããã»ãšãã©åºå¥ã§ããååã®256ã®ã¡ãã¥ãŒé ç®ãå¿ èŠã«ãªããŸãã
What we were able to do, in Viaweb, was display a color as a swatch representing the current value, followed by a button that said âChange.â If the user clicked on the Change button theyâd go to a page with an imagemap of colors to choose among. And after they chose a color, theyâd be back on the page where they were editing the objectâs properties, with that color changed. This is what I mean about simulating subroutine-like behavior. The software could behave as if it were returning from having chosen a color. It wasnât, of course; it was making a new cgi call that looked like going back up a stack. But by using closures, we could make it look to the user, and to ourselves, as if we were just doing a subroutine call. We could write the code to say, if the user clicks on this link, go to the color selection page, and then come back here. This was just one of the places were we took advantage of this possibility. It made our software visibly more sophisticated than that of our competitors.
Viawebã§ã¯ãçŸåšã®å€ã衚ãèŠæ¬ãšããŠè²ã衚瀺ããç¶ããŠã倿Žããšè¡šç€ºããããã¿ã³ã衚瀺ãããŸããããŠãŒã¶ãŒã倿Žãã¿ã³ãã¯ãªãã¯ããå Žåããããã®äžããéžæããè²ã®ã€ã¡ãŒãžããããæã€ããŒãžã«ç§»åããŸãã圌ããè²ãéžãã ãããªããžã§ã¯ãã®ããããã£ãç·šéããŠããããŒãžã«æ»ãããã®è²ãå€ãããŸããããã¯ç§ããµãã«ãŒãã³ã®ãããªæ¯ãèããã·ãã¥ã¬ãŒãããããšãæå³ããŠããŸãããœãããŠã§ã¢ã¯ãè²ãéžæããŠæ»ã£ãŠãããã®ããã«æ¯ãèããŸãããã¡ãããããã§ã¯ãããŸããã§ãããããã¯ã¹ã¿ãã¯ã®ããã«èŠããæ°ããcgiã³ãŒã«ãäœã£ãŠããŸãããããããã¯ããŒãžã£ã䜿ãããšã§ããããããµãã«ãŒãã³ã³ãŒã«ãããŠãããã®ããã«ããŠãŒã¶ãŒãšèªåèªèº«ã«èŠããããã«ããããšãã§ããŸãããŠãŒã¶ãŒããã®ãªã³ã¯ãã¯ãªãã¯ãããšãè²éžæããŒãžã«ç§»åããŠãããããã«æ»ã£ãŠãããšããã³ãŒããæžãããšãã§ããŸããããã¯ç§ãã¡ããã®å¯èœæ§ãå©çšããå Žæã®äžã€ã«éããŸããã§ãããããã«ãããåœç€Ÿã®ãœãããŠã§ã¢ã¯ç«¶åä»ç€ŸãããæŽç·Žããããã®ã«ãªããŸããã