(rontolisp) docs
← cl パッケージの関数

char schar

(char string index) -- (schar string index)

string の 0 始まりの index にある文字を返します。ここでは char と schar は同じ動作をします。Common Lisp では schar は単純文字列向けの変種ですが、rontolisp では同一に扱います。WASM バックエンドは文字列をバイト単位でインデックス参照するため、インデックス参照が正しく定義されるのは ASCII テキストのみです。文字列でない string や整数でない index は、演算子名を含む type-error を通知します (CHAR: The value 5 is not of type STRING)。下記の setf 形式では (SETF CHAR) / (SETF SCHAR) として報告され、文字でない値を格納した場合も同様です ((SETF CHAR): The value 5 is not of type CHARACTER)。

どちらも setf の場所になります: (setf (schar s i) c) / (setf (char s i) c) は位置 i の文字を置き換えて c を返します。実行中のプログラムが確保した文字列 — たとえば make-string のバッファ — はその場で書き換えられます。文字列リテラルはどのバックエンドでも書き換えられません。リテラルはソース中の定数であり、それが現れるフォームを評価するたびに同じオブジェクトが返るため、書き込みは文字列を作り直して場所を再束縛します。したがってリテラルを保持する場合、文字列式は変数である必要があり ((setf (char "abc" 0) #\Z) のようにリテラルへ直接書いたり、アクセサ経由で取り出したリテラルへ書いたりするのはエラーです)、書き込み前に作られた別名参照はリテラル自身の内容のままになります。コンパイル系バックエンドでは、copy-seq/subseq、concatenate 'string、string-upcase ファミリ、format nil、with-output-to-string、read-line が作った文字列は make-string バッファと同じく可変であり、別名参照は書き込みを見ます。そこでまだ不変値を返す少数のプロデューサ (たとえば princ-to-string) の結果にはこの作り直しと再束縛が適用され、別名参照が書き込みを見ることはありません。