Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-4041-

Enterpise LISPERRRS

Name: Anonymous 2015-06-30 5:54

http://tech.grammarly.com/blog/posts/Running-Lisp-in-Production.html

One line paraphrase
Lisp is nice and we used it and here's all the stuff that was broken with SBCL I had to fix.

We use SBCL for production deployment and CCL on most of the developers' machines. One of the nice things about Lisp is that you have an option of choosing from several mature implementations with different strengths and weaknesses: in our case, we optimized for processing speed on the server, and compilation speed in the dev environment

Quicklisp repository hosts more than 1,000 Lisp libraries — not a mind-blowing number but quite enough for covering all of our production needs.

Overall, the problems we face with integrating a Lisp app into the cloud world are not radically different from the ones we encounter with many other technologies. If you want to use Lisp in production, and to experience the joy of writing Lisp code, there is no valid technical reason not to!

oh noes!

We've built an esoteric application (even by Lisp standards), and in the process have hit some limits of our platform. One unexpected thing was heap exhaustion during compilation. We rely heavily on macros, and some of the largest ones expand into thousands of lines of low-level code. It turned out that SBCL compiler implements a lot of optimizations that allow us to enjoy quite fast generated code, but some of which require exponential time and memory resources.

We had to tune the generation sizes, and it turned out that the best option was to use an over-sized heap: our application consumes 2-4 gigabytes of memory, but we run it with 25G heap size which automatically results in a huge volume for the nursery. Yet another customization we had to make — a much less obvious one — was to run full GC programmatically every N minutes. With a large heap, we have noticed a gradual memory usage buildup over periods of tens of minutes which resulted in spans of more time spent in GC and decreased application throughput. Our periodic GC approach got the system into a much more stable state with almost constant memory usage.

oh noes!

Of all these challanges, the worst bug I've ever seen was a network bug. As usual with such stories, it was not a bug in the application but a problem in the underlying platform (this time — SBCL).

oh noes!

As we were just beginning running our service under substantial load in production, after some period of normal operation all of the servers would suddenly start to slow down and then would become unresponsive. After much investigation centering on our input data, we discovered that the problem was instead a race condition in low-level SBCL network code, specifically in the way the socket function getprotobyname, which is non-reentrant, was called.

This is useful

With trace, you define a function to trace, run the code, and Lisp prints all calls to that functions with arguments and all of its returns with results. It is somewhat similar to stacktrace, but you don't get to see the whole stack and you dynamically get a stream of traces, not stopping the application. trace is like print on steroids that allows you to quickly get into the inner workings of arbitrary complex code and monitor complicated flows. The only shortcoming is that you can't trace macros.

Name: Anonymous 2015-06-30 6:02

I've sent them my resume, but got no response

If you know somebody there, can you please recommend me and point to my repo (https://github.com/saniv)

Although I dunno if moving to Ukraine would really be possible during war.

Name: Anonymous 2015-06-30 6:08

>>2
lol are they actually based in ukraine?

Name: Anonymous 2015-06-30 6:09

>>3
Yes.

Name: Anonymous 2015-06-30 6:18

Ahhh, so you people aren't just voices in my head then? You are actually people, in various parts of the earth? Ahhhh this is so weird.

Name: Anonymous 2015-06-30 11:20

>>5
You are actually people, in various parts of the earth?

Mostly on the surface to be honest.

Name: Anonymous 2015-07-01 2:03

>>2
Clojure is not a LISP

Name: Anonymous 2015-07-01 3:30

>>2
We would never ever hire a racist soviet like you, Nikita. Please stop sending us your CV.

Name: Anonymous 2015-07-01 6:35

>>8
But I'm not soviet. I despise Russia.

Name: Anonymous 2015-07-01 6:51

>>9
In fact I love watching the chechclear video, where blonde soviet racist occupant is getting beheaded for his crimes against the chechen people. I'm all pro-exterminating the blue eyed blondes. Totally not racist minority rights activist.

Name: Anonymous 2015-07-01 7:00

>>7
What? I not familiar with Clojure. Only SBCL and Racket.

Name: Anonymous 2015-07-01 7:31

>>10
It's hard for me to tell when you're serious...

Name: Anonymous 2015-07-01 7:35

>>12
seriousness is subjective

Name: Anonymous 2015-07-01 7:51

Google Common Lisp Style Guide.

Because ``with great power comes great responsibility!''

It's written in XML, in Japanese, with english translation in XML comments.

Name: Anonymous 2015-07-01 7:52

Name: Anonymous 2015-07-01 7:55

SHOULD
This word, or the adjective "RECOMMENDED", means that
there may exist valid reasons in particular circumstances
to ignore the demands of the guideline, but
the full implications must be understood and carefully weighed
before choosing a different course.
You must ask forgiveness for violating a SHOULD.

Name: Anonymous 2015-07-01 7:57

There are cases where transgression of some of these rules
is useful or even necessary.
In some cases, you must seek permission or obtain forgiveness
from the proper people.

Name: Anonymous 2015-07-01 8:01

Conventional guidelines are indoctrination.
Their purpose is to make you follow the mores of the community,
so you can more effectively cooperate with existing members.

Name: Anonymous 2015-07-01 8:02

I want to be a Japanese Lispperrr that follows the Common Lisp Style Guide like an honorable Samaria follows Bushido.

Name: Anonymous 2015-07-01 8:20

but fuck google. I wouldn't work for them even if I was writing lisp.

Name: Anonymous 2015-07-01 8:31

Often, the smallest hammer is to use an existing library.
Or one that doesn't exist yet.
In such cases, you are encouraged to use or develop such a library,
but you must take appropriate precautions

You MUST NOT start a new library
unless you established that none is already available
that can be fixed or completed into becoming what you need.
That's a rule against the NIH syndrome ("Not Invented Here"),
which is particularly strong amongst Lisp hackers.

Name: Anonymous 2015-07-01 8:37

Use your judgment to distinguish
general-purpose versus business-specific code,
and open-source the general-purpose parts,
while keeping the business-specific parts a trade secret.

Open-Sourcing code has many advantages,
including being able to leverage third parties for development,
letting the development of features be user-directed,
and keeping you honest with respect to code quality.

Whatever code you write, you will have to maintain anyway,
and make sure its quality is high enough to sustain use in production.

There should therefore be no additional burden to Open-Sourcing,
even of code that (at least initially)
is not directly usable by third parties.

Name: Anonymous 2015-07-01 12:41

I still have no idea how one gets a Lisp programming job.

All places I have sent my resume to I got no response from.

Name: Anonymous 2015-07-01 16:28

<!-- Common Lisp does not have global lexical variables, -->
<!-- so a naming convention is used to ensure that globals, -->
<!-- which are dynamically bound, -->
<!-- never have names that overlap with local variables. -->
Common Lispは大域レキシカル変数を持ちません、
命名についての慣習は大域変数の動的束縛と
ローカル変数による名前の上書きからの保護を行います。
<!-- It is possible to fake global lexical variables -->
<!-- with a differently named global variable -->
<!-- and a <code>DEFINE-SYMBOL-MACRO</code>. -->
これは違う名前の大域変数と<code>DEFINE-SYMBOL-MACRO</code>による
偽りの大域レキシカル変数によって可能になります。
<!-- You should not use this trick, -->
<!-- unless you first publish a library that abstracts it away. -->
あなたが最初にそれを抽象化するライブラリを発行する場合を除いて、
あなたはこのようなトリックを使うべきではありません。
</p>

Name: Anonymous 2015-07-01 16:41

<p>
<!-- You should name boolean-valued functions and variables with a -->
<!-- trailing <code>"P"</code> or <code>"-P"</code>, -->
<!-- to indicate they are predicates. -->
<!-- Generally, you should use -->
<!-- <code>"P"</code> when the rest of the function name is one word -->
<!-- and <code>"-P"</code> when it is more than one word. -->
ブール値を返す関数や変数はそれらが述語であることを示すために<code>"P"</code>か<code>"-P"</code>で終わる名前とすべきです。
一般的に名前が単語の場合は、<code>"P"</code>を使い、複数語の場合は、<code>"-P"</code>を使うべきです。
</p>
<p>
<!-- A rationale for this convention is given in -->
<!-- <a href="http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node69.html">the CLtL2 chapter on predicates</a>. -->
この慣習の根拠となるものには、
<a href="http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node69.html">CLtL2 predicatesの章</a>
があります。
</p>

Name: Anonymous 2015-07-01 16:51

<p>
<!-- Your package must not shadow (and thus effectively redefine) -->
<!-- symbols that are part of the Common Lisp language. -->
パッケージでCommon Lispの仕様の一部となっているシンボルをシャドウ(そして事実上再定義も)してはいけません。
<!-- There are certain exceptions, -->
<!-- but they should be very well-justified and extremely rare: -->
例外もありますが、これらはかなり正当化されているべきで、ほとんど起こらないはずです:
</p>
<ul>
<li>
<!-- If you are explicitly replacing a Common Lisp symbol -->
<!-- by a safer or more featureful version. -->
より安全、もしくはより多機能になるように明示的にCommon Lispのシンボルを再定義している場合。
</li>
<li>
<!-- If you are defining a package not meant to be "used", -->
<!-- and have a good reason to export a symbol -->
<!-- that clashes with Common Lisp, -->
<!-- such as <code>log:error</code> and <code>log:warn</code> -->
<!-- and so on. -->
"use"されることを意図していなくて、Common Lispのシンボルと衝突してまでエクスポートするだけの理由があるパッケージを定義する場合。
例えば<code>log:error</code>や<code>log:warn</code>など。
</li>
</ul>

Name: Anonymous 2015-07-01 16:53

<p>
<!-- Lisp is best used as a "mostly functional" language. -->
Lispは"極力関数型"言語としての使うのが最適です。
</p>
<p>
<!-- Avoid modifying local variables, try rebinding instead. -->
変数は変更(代入)するのではなく、再束縛を試みましょう。
</p>
<p>
<!-- Avoid creating objects and the SETFing their slots. -->
<!-- It's better to set the slots during initialization. -->
オブジェクトを生成してスロットに値をSETFするのではなく、
初期化時にスロットに値を設定する方がより好ましいでしょう。
</p>
<p>
<!-- Make classes as immutable as possible, that is, avoid giving slots -->
<!-- setter functions if at all possible. -->
極力クラスは変更不可なものとして設計しましょう。換言すれば、それが可能な場合には、スロットにはセッター関数を付加しないということです。
</p>
<p>
<!-- Using a mostly functional style makes it much easier -->
<!-- to write concurrent code that is thread-safe. -->
<!-- It also makes it easier to test the code. -->
極力関数的スタイルに則せば、スレッドセーフな並行動作のコードを書くこともより易くなり、コードをテストするのもまたより易しくなります。
</p>

Name: Anonymous 2015-07-01 16:56

<p>
<!-- Common Lisp systems are not required to implement -->
<!-- function calls from tail positions without leaking stack space -->
<!-- &#8212; which is known as proper tail calls (PTC), -->
<!-- tail call elimination (TCE), -->
<!-- or tail call optimization (TCO). -->
Common Lispシステムは、真正な末尾呼び出し(PTC)や末尾呼び出しの削除(TCE)、および末尾呼び出し最適化(TCO)などとして知られる、
スタック空間の溢れることがない末尾位置での関数呼び出しの実装が要求されていません。
<!-- This means that indefinite recursion through tail calls -->
<!-- may quickly blow out the stack, -->
<!-- which hampers functional programming. -->
これが意味するところは、末尾再帰での無限再帰であったとしてもスタックが即座に溢れてしまうかもしれず、これが関数的なプログラミングの妨げになる、ということです。
<!-- Still, most serious implementations (including SBCL and CCL) -->
<!-- do implement proper tail calls, but with restrictions: -->
とはいうものの、制約付きでもっとも実用的な実装(SBCLやCCL)は最適末尾呼び出しを実装しています:
</p>
<ul>
<li>
<!-- The <code>(DECLARE (OPTIMIZE ...))</code> settings -->
<!-- must favor <code>SPEED</code> enough and -->
<!-- not favor <code>DEBUG</code> too much, -->
<!-- for some compiler-dependent meanings of "enough" and "too much". -->
<code>(DECLARE (OPTIMIZE ...))</code>設定は、
いくつかのコンパイラにおける「十分」と「過度」の意味のために、
<code>SPEED</code>を十分に優先して、必要以上に<code>DEBUG</code>を優先しないように
しなければなりません
<!-- (For instance, in SBCL, you should avoid <code>(SPEED 0)</code> -->
<!-- and <code>(DEBUG 3)</code> to achieve proper tail calls.) -->
(例えばSBCLにおいて、あなたは末尾呼び出しの優先を結果として得るためには、
<code>(SPEED 0)</code>と<code>(DEBUG 3)</code>を回避すべきです)。
</li>
<li>
<!-- There should not be dynamic bindings around the call -->
<!-- (even though some Scheme compilers are able to properly treat -->
<!-- such dynamic bindings, called parameters in Scheme parlance). -->
関数呼び出しを包むような動的な束縛は避けるべきです。(訳注: 再帰的な関数呼び出しに伴ない、動的束縛が入れ子になると動的束縛も関数呼び出しとは別にスタックを消費するた>め、これが原因でスタックが溢れる)
<!-- 動的束縛が再帰呼び出しで入れ子になり、結果としてスタックを溢れさせるのを避けるという意味だと思われますが原文が曖昧で良く分かりません -g000001 -->
(いくつかのSchemeコンパイラはこのような、Schemeの用法でパラメタと呼ばれる動的束縛を適切に修正することができますが)
</li>
</ul>

Name: Anonymous 2015-07-01 16:58

<p>
<!-- For compatibility with all compilers and optimization settings, -->
<!-- and to avoid stack overflow when debugging, -->
<!-- you should prefer iteration or the built in mapping functions -->
<!-- to relying on proper tail calls. -->
すべてのコンパイラと最適化設定、そしてデバッグ時のスタックオーバフローを回避するために、
組み込みの末尾再帰の最適化に依存するよりも、繰り返し構文、もしくはマッピング関数の利用をあなたは優先すべきです。
</p>
<p>
<!-- If you do rely on proper tail calls, -->
<!-- you must prominently document the fact, -->
<!-- and take appropriate measures to ensure an appropriate compiler is used -->
<!-- with appropriate optimization settings. -->
もしあなたが最適末尾呼び出しに依存することをするのなら、
あなたは、その動作の実際について明確に文書化し、適切な最適化設定と共に適切なコンパイラを使用することを保証するために
適切な措置を講じなければなりません。
<!-- For fully portable code, you may have to use trampolines instead. -->
完全な移植性をもつコード(訳注: 挙動がコンパイラのセッティングに依らないコード)のためには、あなたは代わりにトランポリンを使わなければならないかもしれません。
</p>

Name: Anonymous 2015-07-02 2:31

Name: Anonymous 2015-07-02 3:53

<!-- Do not clean up by resignaling. -->
再通知によって処理の後始末をしてはなりません。
<!-- If you do that, and the condition is not handled, -->
<!-- the stack trace will halt at the point of the resignal, -->
<!-- hiding the rest. -->
もしそうした場合、コンディションが始末されないと、
スタックトレースは、再通知された地点で停止し、
残りを隠してしまいます。
And the rest is the part we really care about!
<BAD_CODE_SNIPPET>
;; 悪い例
(handler-case
(catch 'ticket-at
(etd-process-blocks))
(error (c)
(reset-parser-values)
(error c)))
</BAD_CODE_SNIPPET>
<CODE_SNIPPET>
;; 良い例
(unwind-protect
(catch 'ticket-at
(etd-process-blocks))
(reset-parser-values))
</CODE_SNIPPET>

Name: Anonymous 2015-07-02 4:32

<p>
<!-- Using <code>(declare (type ...))</code> -->
<!-- is the least-desirable mechanism to use -->
<!-- because, as Scott McKay puts it: -->
<code>(declare (type ...))</code>の使用は、
最低限にすることが望ましいです。その理由については、
Scott McKayによって説明されています。
</p>
<blockquote>
<p>
<!-- The fact is, <code>(declare (type ...))</code> does different things -->
<!-- depending on the compiler settings of speed, safety, etc. -->
実際のところ、<code>(declare (type ...))</code>は
コンパイラ設定のspeedや、safetyの設定に依存している。

<!-- In some compilers, when speed is greater than safety, -->
<!-- <code>(declare (type ...))</code> will tell the compiler -->
<!-- "please assume that these variables have these types" -->
<!-- <em>without</em> generating any type-checks. -->
いくつかのコンパイラはsafetyよりspeedを優先した場合、
<code>(declare (type ...))</code>
を、コンパイラに対する
「これらの変数はこれらの型だと信用してください」
というメッセージとし、いくつかの型判定を<em>しない</em>ために使います。

<!-- That is, if some variable has the value <code>1432</code> in it, -->
<!-- and you declare it to be of type <code>string</code>, -->
<!-- the compiler might just go ahead and use it as though it's a string. -->
例えば、ある変数が値<code>1432</code>を持ち、
あなたがその型を<code>string</code>として宣言すると、
コンパイラはそれを文字列と見做して使用します。
</p>
<p>
<!-- Moral: don't use <code>(declare (type ...))</code> -->
<!-- to declare the contract of any API functions, -->
<!-- it's not the right thing. -->
良識:<code>(declare (type ...))</code>を、
なんらかのAPI関数の契約として使ってはいけません。
それはうまいやり方ではありません。
<!-- Sure, use it for "helper" functions, but not API functions. -->
もちろん、ヘルパー関数のためには使えますが、API関数のために使ってはいけません。
</p>
</blockquote>

Name: No MOP for you! 2015-07-02 4:34

<!-- You must not use MOP "intercessory" operations at runtime. -->
<!-- You should not use MOP "intercessory" operations at compile-time. -->
<!-- At runtime, they are at worst a danger, at best a performance issue. -->
<!-- At compile-time, it is usually cleaner that -->
<!-- macros should set things up the right way in one pass -->
<!-- than have to require a second pass of fixups through intercession; -->
<!-- but sometimes, fixups are necessary to resolve forward references, -->
<!-- and intercession is allowed then. -->
<!-- MOP intercession is a great tool for interactive development, -->
<!-- and you may enjoy it while developping and debugging; -->
<!-- but you should not use it in normal applications. -->
MOPのintercessory(仲裁的)オペレーション[訳注:intercessionは技術用語で、
プログラムの構成要素を調べる(introspection)ことに対して、その構成要素を変更することを指します
(出典: <a href="http://bc.tech.coop/blog/050919.html">http://bc.tech.coop/blog/050919.html</a>)。
このようなオペレータの例としては、<code>defclass</code>の内部で使われる<code>COMPUTE-CLASS-PRECEDENCE-LIST</code>
や<code>DEFMETHOD</code>の内部で使われる<code>ADD-METHOD</code>等があります。]を実行時に使用してはなりません。
MOPの"intercessory"オペレーターをコンパイル時に使用してもなりません。
実行時では、最悪の場合、危険を犯すことになり、良くてもパフォーマンス上の問題があります。
コンパイル時では、通常、しかるべきマクロで事を正しく1パスで行う方が、2パス目が必要となるintercessionによる対処より簡潔です。
しかし、前方参照の解決のための対処が必要なこともあるでしょう。そのときにはintercessionの利用も許されま
MOPのintercessionは、対話的開発では素晴らしい道具ですし、開発中とデバッグ中は、楽しんで使うことができるでしょうが、
通常のアプリケーション内でこれを利用するべきではありません。
<!-- MOPのintercession/introspectionについては http://bc.tech.coop/blog/050919.html
簡単に言うとintrospectionは classのメタ情報の読み出し
intercessionは class への書き込み・変更
[ラテン語「…の間へ行く」の意 (INTER-+cēdere ‘go'); 【名詞】 intercession] by weblio
-->

Name: copying this entire section 2015-07-02 4:36

<!-- <CATEGORY title="Meta-language guidelines"> -->
<CATEGORY title="メタ言語ガイドライン">
<!-- <STYLEPOINT title="Macros"> -->
<STYLEPOINT title="マクロ">
<SUMMARY>
<!-- Use macros when appropriate, which is often. -->
<!-- Define macros when appropriate, which is seldom. -->
マクロを使うことは多いですが、適切な場合に利用しましょう。
それほど多くありませんが、それが適切な場合にはマクロを定義しましょう。
</SUMMARY>
<BODY>
<p>
<!-- Macros bring syntactic abstraction, which is a wonderful thing. -->
<!-- It helps make your code clearer, by describing your intent -->
<!-- without getting bogged in implementation details -->
<!-- (indeed abstracting those details away). -->
<!-- It helps make your code more concise and more readable, -->
<!-- by eliminating both redundancy and irrelevant details. -->
<!-- But it comes at a cost to the reader, -->
<!-- which is learning a new syntactic concept for each macro. -->
<!-- And so it should not be abused. -->
マクロは構文的抽象をもたらし、これは素晴らしいことです。
実装の詳細に囚われることなく意図を記述することを可能にし、コードを明確にするのを助けます(まさにそれらの詳細を抽象化します)。
冗長であったり、無関係であったりする詳細のどちらも省くことで、より簡潔に、より読みやすくすることを助けます。
しかし、マクロごとに新しい構文概念の学習という読み手への負担をもたらします。
それ故にマクロは乱用すべきではありません。
</p>
<p>
<!-- The general conclusion is that there shouldn't be -->
<!-- any recognizable <em>design pattern</em> -->
<!-- in a good Common Lisp program. -->
<!-- The one and only pattern is: <em>use the language</em>, -->
<!-- which includes defining and using syntactic abstractions. -->
一般的結論として、良いCommon Lispのプログラムの中に、何か<em>デザイン・パターン</em>とされるようなものはない筈です。
<em>言語を使う</em>のが唯一のパターンであり、これは構文的抽象化の定義と利用を含みます。
</p>

Name: Anonymous 2015-07-02 4:38

The general conclusion is that there shouldn't be
any recognizable design pattern
in a good Common Lisp program.
The one and only pattern is: use the language,
which includes defining and using syntactic abstractions.
This should be a quote.

Name: Anonymous 2015-07-02 5:48

LISP is a mental attitude rather than a programming language. It uses a certain process of the mind expressed spontaneously through keyboard. I'm concerned with retaining that process.

LISP is an open-ended programming language for open minds.

Anyone can learn Lisp in a few minutes, but nobody could master lisping in a thousand years.

It bugs me when people try to analyze Lisp as a mathematical theorem. It's not. It's feeling.

Lisp, for me, has always been a place where anything is possible--a refuge, a magical world where anyone can go, where all kinds of people can come together, and anything can happen. We are limited only by our imagination.

I hate static languages. I have to change language to my own way of doing it. That's all I know.

One thing I like about Lisp, kid, is that I don't know what's going to happen next. Do you?

The whole thing of programming LISP is not to control it but to be swept away by it. If you're swept away by it you can't wait to do it again and the same magical moments always come.

My own feelings about the direction in which LISP should go are that there should be much less stress on static exhibitionism and much more on dynamic content, on what might be termed humanity in programming and the freedom to express all that you want.

Not to deny that LISP is a thinking people's programming language, but when I'm lisping if I ever catch myself thinking, I'm in trouble--I know something is wrong.

Lispness is not a state of mind, It's a fact of life!

Surrender your whole being to LISP, and gravity disappears...with few macros, one could write code as deep as the ocean.

Macros are to Lisp what yeast is to bread--without it, it's flat.

Recursion is the ability to talk to oneself.

Making the simple complicated is commonplace; making the complicated simple, awesomely simple, that's creativity. — Charles Mingus

Lisp is your own experience, your thoughts, your wisdom. If you don't live it, it won't come out of your REPL.

It is becoming increasingly difficult to decide where LISP starts or where it ends, or even where the borderline lies between between programming in general and LISP. I feel there is no boundary line.

LISP is what we need when other languages fail us, but we cannot remain silent.

"Lisp" stands for "Lisp Is Syntactically Pure"

If it ain't Lisp, it's crap.

Name: Anonymous 2015-07-02 9:17

>>36
Did we decide to invalidate ``LISP is shit.''? Could it be true that not all things are shit?

Name: Anonymous 2015-07-02 9:38

<SUMMARY>
<!-- You must not use <code>EVAL</code> at runtime. -->
実行時に<code>EVAL</code>を使ってはなりません。
</SUMMARY>
<BODY>
<p>
<!-- Places where it is actually appropriate to use <code>EVAL</code> -->
<!-- are so few and far between that you must consult with your reviewers; -->
<!-- it's easily misused. -->
<code>EVAL</code>を使うことが真に適切であるという極まれな場面でも、
あなたはあなたの査読者と相談しなければなりません。
EVALは容易に誤用されるからです。
</p>
<p>
<!-- If your code manipulates symbols at runtime -->
<!-- and needs to get the value of a symbol, -->
<!-- use <code>SYMBOL-VALUE</code>, not <code>EVAL</code>. -->
もしもあなたのコードが、実行時にシンボルを操作し、
シンボルの値を取得することを必要とするときは
<code>EVAL</code>ではなく<code>SYMBOL-VALUE</code>を使いましょう。
</p>
<p>
<!-- Often, what you really need is to write a macro, -->
<!-- not to use <code>EVAL</code>. -->
良くあること: あなたが本当に必要としていることは「マクロを書く」ことで「<code>EVAL</code>を使う」ことではありません。
</p>
<p>
<!-- You may be tempted to use <code>EVAL</code> as a shortcut -->
<!-- to evaluating expressions in a safe subset of the language. -->
言語の安全なサブセット内において、式を評価するときの近道として、<code>EVAL</code>
を利用する誘惑にかられるかもしれません。
<!-- But it often requires more scrutiny to properly check and sanitize -->
<!-- all possible inputs to such use of <code>EVAL</code> -->
<!-- than to build a special-purpose evaluator. -->
<!-- You must not use <code>EVAL</code> in this way at runtime. -->
しかし、大抵の場合、特殊用途の評価器をつくりあげるよりも<code>EVAL</code>を使う方が、
すべての入力の可能性について有効性と安全を保つための監視の手間が増えます。
このような場合、<code>EVAL</code>は使わないようにしないとなりません。
</p>
<p>
<!-- Places where it is OK to use <code>EVAL</code> are: -->
<code>EVAL</code>を使うことが許される状況を以下に記します。
</p>
<ul>
<li>
<!-- The implementation of an interactive development tool. -->
インタラクティブな開発ツールの実装。
</li>
<li>
<!-- The build infrastructure. -->
基盤の構築。
</li>
<li>
<!-- Backdoors that are part of testing frameworks. -->
<!-- (You MUST NOT have such backdoors in production code.) -->
テストフレームワークにおけるバックドア
(実用コードにおいてこの手のバックドアを設けてはなりません)。
</li>
<li>
<!-- Macros that fold constants at compile-time. -->
コンパイル時に定数をたたみ込むマクロ。
</li>
<li>
<!-- Macros that register definitions to meta-data structures; -->
メタデータ構造のための定義を登録するマクロ。
<!-- the registration form is sometimes evaluated at compile-time -->
<!-- as well as included in the macro-expansion, -->
<!-- so it is immediately available to other macros. -->
登録を行うフォームは時にコンパイル時に評価、もしくは、マクロ展開で組み込まれるので、
即座に他のマクロから利用可能になります。
</li>
</ul>
<p>
<!-- Note that in the latter case, -->
<!-- if the macro isn't going to be used at the top-level, -->
<!-- it might not be possible to make these definitions available -->
<!-- as part of the expansion. --> <!-- g000001: なんとなく分かりますが具体的にどういうコードになるのか想像できないですね -->
注記: 後の例<!-- マクロ展開時のことを指している? g000001 -->において、もしマクロがトップレベルで使用できる状態にならない場合、
展開の一部分である定義が展開されず、[結果として]それらの定義も有効にならない可能性があるということに注意が必要です。
<!-- The same phenomenon may happen in a <code>DEFTYPE</code> expansion, -->
<!-- or in helper functions used by macros. -->
同じような現象は<code>DEFTYPE</code>での展開や、
マクロに利用されるヘルパ関数においても起こります。
<!-- In these cases, you may actually have to use -->
<!-- <code>ASDF-FINALIZERS:EVAL-AT-TOPLEVEL</code> in your macro. -->
こういった場合、マクロ内において、
<code>ASDF-FINALIZERS:EVAL-AT-TOPLEVEL</code>を使う必要が実際にあるかもしれません。
<!-- It will not only <code>EVAL</code> your definitions -->
<!-- at macro-expansion time for immediate availability, -->
<!-- it will also save the form aside, for inclusion in a -->
<!-- <code>(ASDF-FINALIZERS:FINAL-FORMS)</code> -->
<!-- that you need to include at the end of the file being compiled -->
<!-- (or before the form is needed). -->
これは、マクロ展開時に、フォームを<code>EVAL</code>し、即時に有効化するだけでなく、
ファイルがコンパイルされる時にファイルの末尾に置く必要があるものとして(もしくは、そのフォームが必要とされる前に)、
<code>(ASDF-FINALIZERS:FINAL-FORMS)</code> が含めるフォームとして取っておきます。
<!-- This way, the side-effects are present when loading the fasl --><!-- faslはコンパイルされてると思うのでfileの間違い?: g000001 -->
<!-- without having compiled it as well as while compiling it; -->
この方法は、コンパイルしたfasl[ファイル?]においてもしないものにおいても副作用を持っています。
<!-- in either case, the form is made available at load-time. -->
どちらの場合も、フォームはロード時に使えるようになります。
<!-- <code>ASDF-FINALIZERS</code> ensures that the form is present, -->
<!-- by throwing an error if you omit it. -->
<code>ASDF-FINALIZERS</code>はフォームが存在することを保証し、[フォームを]省略した場合はエラーを投げます。
</p>
</BODY>

Name: Anonymous 2015-07-02 10:06

Damn I think I'm guilty of this one.

<p>
<!-- You must not use <code>INTERN</code> at runtime. -->
<!-- Not only does it cons, -->
<!-- it either creates a permanent symbol that won't be collected -->
<!-- or gives access to internal symbols. -->
<!-- This creates opportunities for memory leaks, denial of service attacks, -->
<!-- unauthorized access to internals, clashes with other symbols. -->
<code>INTERN</code>を実行時に使用してはなりません。
これは[GCに]回収されない恒久的なシンボルの生成であろうと、内部シンボルの生成であろうと良くありません。
<!-- pros and consのconsか、それともはboxingのことか、それとも「construct」の意味か -g000001 -->
これらの実行は、メモリリーク・DoS攻撃・内部への不正アクセス・他のシンボルとの競合、等の発生を生む可能性があります。
</p>
<p>
<!-- You must not <code>INTERN</code> a string -->
<!-- just to compare it to a keyword; -->
<!-- use <code>STRING=</code> or <code>STRING-EQUAL</code>. -->
単にキーワード[シンボル]を比較するためだけに、文字列を<code>INTERN</code>してはなりません。
<code>STRING=</code>か<code>STRING-EQUAL</code>を使いましょう。
</p>
<BAD_CODE_SNIPPET>
(member (intern str :keyword) $keys) ; 悪い
</BAD_CODE_SNIPPET>
<CODE_SNIPPET>
(member str $keys :test #'string-equal) ; より良い
</CODE_SNIPPET>
<p>
<!-- You must not use <code>UNINTERN</code> at runtime. -->
<!-- It can break code that relies on dynamic binding. -->
<!-- It makes things harder to debug. -->
<!-- You must not dynamically intern any new symbol, -->
<!-- and therefore you need not dynamically unintern anything. -->
<code>UNINTERN</code>を実行時に使用してはなりません。
これは、動的な束縛に依存したコードを破壊する可能性があります。
また、これは、デバッグを困難なものにします。
動的に新しいシンボルを<code>INTERN</code>してはなりませんし、そうなると、まったく動的にシンボルを<code>UNINTERN</code>する必要もありません。<!-- un/internは別個>のものでは? -g000001 -->
</p>
<p>
<!-- You may of course use <code>INTERN</code> at compile-time, -->
<!-- in the implementation of some macros. -->
<!-- Even so, it is usually more appropriate -->
<!-- to use abstractions on top of it, such as -->
<!-- <code>ALEXANDRIA:SYMBOLICATE</code> or -->
<!-- <code>ALEXANDRIA:FORMAT-SYMBOL</code> -->
<!-- to create the symbols you need. -->
勿論、コンパイル時には、マクロの組み立ての中で<code>INTERN</code>は使えるでしょう。
とはいえ、大抵は[<code>INTERN</code>を直に使うより]、それを抽象化したものを使うのがより適切であり、
必要なシンボルを生成するのには<code>ALEXANDRIA:SYMBOLICATE</code>や<code>ALEXANDRIA:FORMAT-SYMBOL</code>のようなものを使うことでしょう。
</p>

Name: Anonymous 2015-07-02 10:27

defconstant is bad

<p>
<!-- Note that with optimizing implementations, such as SBCL or CMUCL, -->
<!-- defining constants this way precludes any later redefinition -->
<!-- short of <code>UNINTERN</code>ing the symbol -->
<!-- and recompiling all its clients. -->
SBCLやCMUCLなどの最適化をする処理系ではこのように定数を定義するとシンボルを<code>UNINTERN</code>してしまうため、定数を使っているコード全てを再コンパイルする以外には後
から定数を再定義する方法は無いことを覚えておきましょう。
<!-- This may make it "interesting" to debug things at the REPL -->
<!-- or to deploy live code upgrades. -->
これによってREPLでのデバッグやホットデプロイが「愉快な」ことになってしまいます。
<!-- If there is a chance that your "constants" are not going to be constant -->
<!-- over the lifetime of your server processes -->
<!-- after taking into consideration scheduled and unscheduled code patches, -->
<!-- you should consider using -->
<!-- <code>DEFPARAMETER</code> or <code>DEFVAR</code> instead, -->
<!-- or possibly a variant of <code>DEFINE-CONSTANT</code> -->
<!-- that builds upon some future library implementing global lexicals -->
<!-- rather than <code>DEFCONSTANT</code>. -->
もし想定内/外のパッチを考慮するならば、サーバー上で動いている間に「定数」の値が変更され得るなら<code>DEFCONSTANT</code>ではなく<code>DEFPARAMETER</code>や<code>DEFVAR</code>、あるいは[未来のグローバルレキシカル変数の上に実装された|???]<code>DEFINE-CONSTANT</code>の変種の使用を考えるべきです。
<!-- TODO: builds upon some future library implementing global lexicalsの訳が分りませんでした。global lexicals?(κeen) -->
<!-- featureなんですかね?。それとも、グローバルなレキシカル変数が実現されることを未来と呼んでいるのか。
なんにしろ無用な修飾の気もしますね…。 g000001 -->
<!-- You may keep the <code>+plus+</code> convention in these cases -->
<!-- to document the intent of the parameter as a constant. -->
この場合は定数として扱う意図であることを示すために<code>+plus+</code>のコーディング規約を一貫して用いることができるでしょう。
</p>

Name: Anonymous 2015-07-02 19:19

I've been doing LISP all wrong.

Name: Anonymous 2015-07-02 20:24

>>41
At the end of the day, it's just wise opinions of a Japanese EXPERT LISP PROGRAMMER who works at google. Unless you're writing a server application most of these are just good style.

Name: Anonymous 2015-07-02 20:35

Bu- but, it's LISt Processing!

<!-- <STYLEPOINT title="Do not abuse lists"> -->
<STYLEPOINT title="リストの乱用はしない">
<SUMMARY>
<!-- You must select proper data representation.
You must not abuse the LIST data structure. -->
データ表現は正しく選択しなければなりません。
<code>LIST</code>構造を乱用してはなりません。
</SUMMARY>
<BODY>
<p>
<!-- Even though back in 1958, LISP was short for "LISt Processing", -->
<!-- its successor Common Lisp has been a modern programming language -->
<!-- with modern data structures since the 1980s. -->
1958の昔にまで遡ればLISPは"LISt Processing"の略でありましたが、1980年代以降、その後継であるCommon Lispはモダンなデータ構造を持ったモダンなプログラミング言語であり続け
ています 。
<!-- You must use the proper data structures in your programs. -->
プログラムには適切なデータ構造を使わなければなりません。
</p>
<p>
<!-- You must not abuse the builtin (single-linked) <code>LIST</code> -->
<!-- data structure where it is not appropriate, -->
<!-- even though Common Lisp makes it especially easy to use it. -->
Common Lispは確かにビルトインの(単方向連結)<code>LIST</code>の操作が簡単になっていますが、不適切な場面でそれを乱用してはなりません。
</p>
<p>
<!-- You must only use lists -->
<!-- when their performance characteristics -->
<!-- is appropriate for the algorithm at hand: -->
<!-- sequential iteration over the entire contents of the list. -->
リストを使うときはそのパフォーマンスの特徴上適切なアルゴリズム ─ シーケンシャルにリスト全体を舐めるようなもの ─ で操作する場合に限らなければなりません。
</p>
<p>
<!-- An exception where it is appropriate to use lists -->
<!-- is when it is known in advance -->
<!-- that the size of the list will remain very short -->
<!-- (say, less than 16 elements). -->
例外として事前にリストのサイズが小さい(具体的には要素数が16未満)と分かっている場合があげられます。
</p>
<p>
<!-- List data structures are often (but not always) -->
<!-- appropriate for macros and functions used by macros at compile-time: -->
<!-- indeed, not only is source code passed as lists in Common Lisp, -->
<!-- but the macro-expansion and compilation processes -->
<!-- will typically walk over the entire source code, sequentially, once. -->
リストは大抵の場合(だがしかしいつもではない)マクロやコンパイル時に使われる関数には適切です。
というのも、Common Lispのソースコードがリストとして渡されるだけでなく、マクロ展開やコンパイル処理で典型的には全ソースコードを1回舐めるからです。
<!-- (Note that advanced macro systems don't directly use lists, but instead -->
<!-- use abstract syntax objects that track source code location and scope; -->
<!-- however there is no such advanced macro system -->
<!-- in Common Lisp at this time.) -->
(進んだマクロシステムでは直接はリストを使わずソースコードの位置やスコープを追跡する抽象構文オブジェクトを使いますが、現時点ではCommon Lispにはそのようなマクロシステム
は存在しないことに気を付けましょう。)
</p>
<p>
<!-- Another exception where it is appropriate to use lists is -->
<!-- for introducing literal constants -->
<!-- that will be transformed into more appropriate data structures -->
<!-- at compile-time or load-time. -->
もう一つの例外としてコンパイル時やロード時に適切なデータ構造に変換される[リストの]リテラルを導入する場合があげられます。
<!-- It is a good to have a function with a relatively short name -->
<!-- to build your program's data structures from such literals. -->
比較的短かい名前でそのようなリテラルから自分のプログラムのデータ構造を構成する関数を用意するのは良いことです。
</p>
<p>
<!-- In the many cases when lists are not the appropriate data structure, -->
<!-- various libraries such as -->
<!-- <a href="http://cliki.net/cl-containers">cl-containers</a> or -->
<!-- <a href="http://cliki.net/lisp-interface-library">lisp-interface-library</a> -->
<!-- provide plenty of different data structures -->
<!-- that should fulfill all the basic needs of your programs. -->
リストがデータ構造として適切でない場合は<a href="http://cliki.net/cl-containers">cl-containers</a>や<a href="http://cliki.net/lisp-interface-library">lisp-interface-library</a>などのライブラリがプログラムの基本的な需要を全て満足する多種多様なデータ構造を提供してくれます。
<!-- If the existing libraries are not satisfactory, see above about -->
<!-- <a href="#Using_Libraries">Using Libraries</a> and -->
<!-- <a href="#Open-Sourcing_Code">Open-Sourcing Code</a>. -->
もし既存のライブラリで満足できないなら、<a href="#Using_Libraries">Using Libraries</a>や<a href="#Open-Sourcing_Code">Open-Sourcing Code</a>を参考にして下さい。
</p>
</BODY>
</STYLEPOINT>

Name: Anonymous 2015-07-02 23:41

Wow I never knew about this. Common Lisp is an acceptable D.

<STYLEPOINT title="DYNAMIC-EXTENT">
<SUMMARY>
<!-- You should only use <code>DYNAMIC-EXTENT</code> -->
<!-- where it matters for performance, -->
<!-- and you can document why it is correct. -->
<code>DYNAMIC-EXTENT</code> の利用はパフォーマンスが重要である場合に限るべきです。
さらには、宣言の利用の正当性を文書化しておきます。
</SUMMARY>
<BODY>
<p>
<!-- <code>DYNAMIC-EXTENT</code> declarations are -->
<!-- a particular case of -->
<!-- <a href="#Unsafe_Operations">unsafe operations</a>. -->
<code>DYNAMIC-EXTENT</code>宣言は<a href="#Unsafe_Operations">安全でない操作</a>のケースの1つです。
</p>
<p>
<!-- The purpose of a <code>DYNAMIC-EXTENT</code> declaration -->
<!-- is to improve performance by reducing garbage collection -->
<!-- in cases where it appears to be obvious that an object's lifetime -->
<!-- is within the "dynamic extent" of a function. -->
<!-- That means the object is created at some point -->
<!-- after the function is called, and -->
<!-- the object is always inaccessible after the function exits by any means. -->
<code>DYNAMIC-EXTENT</code> 宣言の目的は、
該当オブジェクトの生存期間が関数の“動的エクステント″の範囲に収まっていることが明白な場合において、
ガベージ・コレクションの発生を抑制することにより、パフォーマンスを向上させることにあります。
この動作が意味するところは、関数が呼ばれることにより、ある時点で該当オブジェクトが生成されるとして、
この関数の実行が終了した後には、該当オブジェクトには、どのような意味でも常にアクセス不可能になる、ということです。
</p>
<p>
<!--
By declaring a variable or a local function <code>DYNAMIC-EXTENT</code>,
the programmer <em>asserts</em> to Lisp
that any object that is ever a value of that variable
or the closure that is the definition of the function
has a lifetime within the dynamic extent of the (innermost) function
that declares the variable.
もってまわりすぎ?
-->
変数や局所関数に<code>DYNAMIC-EXTENT</code>宣言を付けることにより、プログラマは、
変数やクロージャーの寿命は(最内周の)関数の動的エクステント内であることを、Lisp処理系に<em>強引に指定</em>することになります。
</p>
<p>
<!-- The Lisp implementation is then free to use that information -->
<!-- to make the program faster. -->
宣言時、Lisp処理系は、任意でこの情報をプログラムの速度向上のために活用することができます。
<!-- Typically, Lisp implementations can take advantage of this knowledge -->
<!-- to stack-allocate: -->
典型的には、Lisp処理系は、この知識をスタック割付けに役立てます:
</p>
<ul>
<li>
<!-- The lists created to store <code>&amp;REST</code> parameters. -->
<code>&amp;REST</code> 引数により作られるリスト
</li>
<li>
<!-- Lists and vector allocated within a function. -->
<!-- Lists, vectors and structures allocated within a function. -->
アロケートが関数内で収まっているリスト、ベクタ、構造体
</li>
<li>
<!-- Closures. -->
クロージャー
</li>
</ul>
<p>
<!-- If the assertion is wrong, i.e. if the programmer's claim is not true, -->
<!-- the results can be <em>catastrophic</em>: -->
<!-- Lisp can terminate any time after the function returns, -->
<!-- or it can hang forever, or — worst of all — -->
<!-- it can produce incorrect results without any runtime error! -->
もし指定が間違っていれば、つまりプログラマの主張が真でなければ、<em>大災害</em>にもなるでしょう:
Lispは[dynamic-extent指定をした]関数の値が返るときいつでも終了、あるいはフリーズ、最悪の場合エラーすら起さずに間違った値を返し得ます。
</p>
<p>
<!-- Even if the assertion is correct, -->
<!-- future changes to the function might introduce -->
<!-- a violation of the assertion. -->
もし指定が正しかったとしても将来関数を変更するときに暴発しかねません。
<!-- This increases the danger. -->
危険性は増大します。
</p>
<p>
<!-- In most cases, such objects are ephemeral. -->
たいていの場合、そのような[dynamic-extent宣言を付けたくなるような]オブジェクトは短命です。
<!-- Modern Lisp implementations use generational garbage collectors, -->
<!-- which are quite efficient under these circumstances. -->
モダンなLisp処理系は世代別ガーベジコレクションを使いますが、それはこのような状況においては非常に効率的です。
</p>
<p>
<!-- Therefore, <code>DYNAMIC-EXTENT</code> declarations -->
<!-- should be used sparingly. You must only use them if: -->
それゆえ、<code>DYNAMIC-EXTENT</code>宣言は滅多に使うべきではありません。使うべき状況は:
</p>
<ol>
<li>
<!-- There is some good reason to think that the overall effect -->
<!-- on performance is noticeable, and -->
パフォーマンスにおける総合的な影響が顕著であると考えるに十分な理由がある。
</li>
<li>
<!-- It is absolutely clear that the assertion is true. -->
その指定が自明に正しい。
</li>
<li>
<!-- It is quite unlikely that the code will be changed -->
<!-- in ways that cause the declaration to become false. -->
その宣言が正しくなくなるような変更が加えられる可能性が非常に低い。
</li>
</ol>
<p>
<!-- Point (1) is a special case of -->
<!-- the principle of avoiding premature optimization. -->
1つめの項目は早過ぎる最適化を避けるの原則の特別な場合です。
<!-- An optimization like this only matters if such objects -->
<!-- are allocated at a very high rate, e.g. "inside an inner loop". -->
このような最適化は「[ネストした]内側のループの中」などの非常に高い頻度でアロケートされるような場合にのみ意味があります。
</p>
<p>
<!-- Note that is relatively easy to ascertain that -->
<!-- a function will not escape the dynamic extent of the current call frame -->
<!-- by analyzing where the function is called and -->
<!-- what other functions it is passed to; -->
<!-- therefore, you should somewhat wary of declaring a function -->
<!-- <code>DYNAMIC-EXTENT</code>, but this is not a high-stress declaration. -->
関数がどこで呼ばれてどの別の関数に渡されるかを分析すれば、その関数が現在のコールフレームの動的スコープを抜けないことを突き止めることは比較的容易なので、関数に<code>DYNAMIC-EXTENT</code>を宣言するときは用心する必要はありますが、これはそれほどストレスの高いものではないことを覚えておきましょう。
<!-- On the other hand, it is much harder to ascertain that -->
<!-- none of the objects ever bound or assigned to that variable -->
<!-- and none of their sub-objects -->
<!-- will escape the dynamic extent of the current call frame, -->
<!-- nor will in any future modification of a function. -->
<!-- and that they still won't in any future modification of a function. -->
逆に、ある変数に束縛されたオブジェクトとそのサブオブジェクトのどれもが現在のコールフレームの動的エクステントを抜けない、そして将来の修正のときにも影響も受けないことを
確実にするのは非常に困難を極めます。
<!-- Therefore, you should be extremely wary -->
<!-- of declaring a variable <code>DYNAMIC-EXTENT</code>. -->
それゆえ、変数に<code>DYNAMIC-EXTENT</code>を宣言するときは細心の注意を払いましょう。
</p>
<p>
<!-- It's usually hard to predict the effect of such optimization on performance. -->
通常、このようなパフォーマンスの最適化の影響を予測するのは難しいものです。
<!-- When writing a function or macro -->
<!-- that is part of a library of reusable code, -->
<!-- there's no a priori way to know how often the code will run. -->
再利用可能なライブラリの一部として関数やマクロを定義するときはどのくらい使われるかを知る有効な手段はありません。
<!-- Ideally, tools would be available to discover -->
<!-- the availability and suitability of using such an optimization -->
<!-- based on running simulations and test cases, but -->
<!-- in practice this isn't as easy as it ought to be. -->
理想的には、シュミレーションをしてそのような最適化が使えるか、適当であるかを判断するツールが使えると良いのですが、実際には難しいものがあります。
<!-- in practice this isn't as easy as it ought to beを意訳しました -->
<!-- It's a tradeoff. -->
トレードオフです。
<!-- If you're very, very sure that the assertion is true -->
<!-- (that any object bound to the variable and any of its sub-objects -->
<!-- are only used within the dynamic extent of the specified scope), -->
<!-- and it's not obvious how much time will be saved -->
<!-- and it's not easy to measure, -->
<!-- then it may be better to put in the declaration than to leave it out. -->
変数に束縛されたオブジェクトとそのサブオブジェクトのどれもが動的[エクステントとなるような]スコープでしか使われないという絶対の自身があって、どの程度最適化の効果がある
か分からず、容易に効果の測定もできないなら、そのまま放っておくよりは、宣言する方が良いでしょう。
<!-- (Ideally it would be easier to make such measurements -->
<!-- than it actually is.) -->
(もっと測定が容易であれば良いのですが。)
</p>
</BODY>
</STYLEPOINT>

Name: Anonymous 2015-07-03 0:58

Oh no, I can't use reduce or apply! Fuck!

<STYLEPOINT title="REDUCE か APPLY か">
<SUMMARY>
<!-- You should use <code>REDUCE</code> -->
<!-- instead of <code>APPLY</code> where appropriate. -->
<code>APPLY</code> を利用する方がより適切な場合を除いて <code>REDUCE</code> を利用すべきです。
</SUMMARY>
<BODY>
<p>
<!-- You should use <code>REDUCE</code> -->
<!-- instead of <code>APPLY</code> and a consed-up list, -->
<!-- where the semantics of the first operator argument -->
<!-- otherwise guarantees the same semantics. -->
<!-- Of course, you must use <code>APPLY</code> -->
<!-- if it does what you want and <code>REDUCE</code> doesn't. -->
<!-- For instance -->
第一引数の関数の意味論が同じと保証されるなら、<!-- ? -->
リストを作って<code>APPLY</code>する代りに<code>REDUCE</code>を使うべきです。
勿論、<code>REDUCE</code>では駄目で、求めるものが<code>APPLY</code>であるなら使わなければなりません。
例えば:
</p>
<BAD_CODE_SNIPPET>
;; Bad
(apply #'+ (mapcar #'acc frobs))
</BAD_CODE_SNIPPET>
<CODE_SNIPPET>
;; Better
(reduce #'+ frobs :key #'acc :initial-value 0)
</CODE_SNIPPET>
<p>
<!-- This is preferable because it does not do extra consing, -->
<!-- and does not risk going beyond <code>CALL-ARGUMENTS-LIMIT</code> -->
<!-- on implementations where that limit is small, -->
<!-- which could blow away the stack on long lists -->
<!-- (we want to avoid gratuitous non-portability in our code). -->
これは、余計なコンスをしないのと、<code>CALL-ARGUMENTS-LIMIT</code>
の上限が小さい処理系において、長いリストでスタックをあふれさせるリスクがない点で好ましいと言えます。
(コードに無用な可搬性の無さを持ち込むのは避けたい)
</p>
<p>
<!-- However, you must be careful not to use <code>REDUCE</code> -->
<!-- in ways that needlessly increase -->
<!-- the complexity class of the computation. -->
<!-- For instance, <code>(REDUCE 'STRCAT ...)</code> is <i>O(n^2)</i> -->
<!-- when an appropriate implementation is only <i>O(n)</i>. -->
<!-- Moreover, <code>(REDUCE 'APPEND ...)</code> -->
<!-- is also <i>O(n^2)</i> unless you specify <code>:FROM-END T</code>. -->

<!-- In such cases, you must use proper abstractions -->
<!-- that cover those cases instead of calling <code>REDUCE</code>, -->
<!-- first defining them in a suitable library if need be. -->

<!-- In such cases, you MUST NOT use <code>REDUCE</code>, -->
<!-- and you MUST NOT use <code>(APPLY 'STRCAT ...)</code> -->
<!-- or <code>(APPLY 'APPEND ...)</code> either. -->
<!-- Instead you MUST use proper abstractions -->
<!-- from a suitable library (that you may have to contribute to) -->
<!-- that properly handles those cases -->
<!-- without burdening users with implementation details. -->
<!-- See for instance <code>UIOP:REDUCE/STRCAT</code>. -->
とはいうものの、不要に計算量を増大させるような<code>REDUCE</code>の用法には注意しなければなりません。
例えば、<code>(REDUCE #'STRCAT ...)</code>を用いれば<i>O(n^2)</i>となりますが、
[<code>REDUCE</code>ではなく]適切な実装を用いた場合には<i>O(n)</i>にしかなりません。
加えて、<code>(REDUCE #'APPEND ...)</code>
もまた、<code>:FROM-END T</code>を指定しない限り<i>O(n^2)</i>となります。
このような場合、<code>REDUCE</code>を使ってはなりませんし、<code>(APPLY 'STRCAT ...)</code>や、<code>(APPLY 'APPEND ...)</code>も使ってはなりません。
代わりに、実装の詳細についてをユーザーが負担することなしに、このようなケースを上手く回せるような、
利用するにふさわしいライブラリ(もしかするとあなたが協力する必要もあるかもしれない)から適切な抽象化を提供するものを利用しなくてはなりません。
例としては、<code>UIOP:REDUCE/STRCAT</code>を参照のこと。
</p>

</BODY>
</STYLEPOINT>

Name: lambda reader 2015-07-03 1:27

<!-- Note that if you start writing a new system -->
<!-- in a heavily functional style, -->
<!-- you may consider using -->
<!-- <a href="http://cliki.net/lambda-reader">lambda-reader</a>, -->
<!-- a system that lets you use the unicode character <code>λ</code> -->
<!-- instead of <code>LAMBDA</code>. -->
<!-- But you must not start using such a syntactic extension -->
<!-- in an existing system without getting permission from other developers. -->
加えて、関数型スタイルを重用してシステムを新規に書き始める際は、
<a href="http://cliki.net/lambda-reader">lambda-reader</a>の使用を考えてみても良いでしょう。
これは、Unicodeの<code>λ</code>を<code>LAMBDA</code>の代わりに使えるライブラリです。
しかし、既にあるシステムに他の開発者の賛同なくこういった構文拡張を導入してはなりません。

Name: Anonymous 2015-07-03 1:31

I finished reading it finally. By the time I got to the end of it my faith in Common LISP was more shaken than before.

Name: Anonymous 2015-07-03 1:55

>>24
Fuck yapan asshol yapan kill people.

Name: Anonymous 2015-07-04 9:48

Bump for LITHP.

Don't change these.
Name: Email:
Entire Thread Thread List