Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

codepoint_atで下位サロゲートが残っている #561

Open
FineArchs opened this issue Feb 9, 2024 · 18 comments
Open

codepoint_atで下位サロゲートが残っている #561

FineArchs opened this issue Feb 9, 2024 · 18 comments

Comments

@FineArchs
Copy link
Member

expected behaviour

let char = "𩸽" 
<: s.codepoint_at(0) // 171581
<: s.codepoint_at(1) // null

actual behaviour

let char = "𩸽" 
<: s.codepoint_at(0) // 171581
<: s.codepoint_at(1) // 56893
@FineArchs
Copy link
Member Author

@MineCake147E 👀

@MineCake147E
Copy link
Contributor

codepoint_atのインデックスは16bit単位なので、下位サロゲートの位置を直接指定した場合は下位サロゲートを返します。

@FineArchs
Copy link
Member Author

あー、JavaScriptのcodePointAtがその仕様なんですね
ただAiScriptにはcharcode_atもあることを考えると、codepoint_atはサロゲートペア単位にした方が用途が多いと思います

@MineCake147E
Copy link
Contributor

to_unicode_arrto_unicode_codepoint_arrがコードポイントごとに区切るので、その用途ではそれをご利用ください。

<: `{'𩸽👉🏿👨‍👦'.to_unicode_arr()}`
<: `{'𩸽👉🏿👨‍👦'.to_unicode_codepoint_arr()}`
str [ "𩸽", "👉", "🏿", "👨", "‍", "👦" ]
str [ 171581, 128073, 127999, 128104, 8205, 128102 ]
(null)

こちらの方が、毎回分割するよりはパフォーマンス的にも良いかと思います。

@FineArchs
Copy link
Member Author

仕様の形としては直感的でないですが、パフォーマンス的には確かにそうですね…

@marihachi
Copy link
Contributor

marihachi commented Feb 11, 2024

codepoint_atでindexをコードポイント単位にはできないですかね?(ある程度パフォーマンスを維持しながら)
もしできなさそうであれば、代替の方法もあるわけなのでこのAPIはあまり必要ない気がします。

@MineCake147E
Copy link
Contributor

MineCake147E commented Feb 11, 2024

codepoint_atでindexをコードポイント単位にはできないですかね?(ある程度パフォーマンスを維持しながら)

出来なくはないかもしれませんが、互換性等を考慮すると、オプション引数を新設する必要があると思います。
毎回to_unicode_arr相当の処理を行うのは無駄が多いため現在の仕様となっています。(indexが0の場合だけ特殊対応をしてもいいかもしれませんが…)

もしできなさそうであれば、代替の方法もあるわけなのでこのAPIはあまり必要ない気がします。

to_unicode_arrしたものから一文字分のコードポイントを取得する際に必要になります。
毎回to_unicode_codepoint_arrを実行すると、毎回配列を返すことになり無駄が多いため、codepoint_atは結局必要だと思います。

@marihachi
Copy link
Contributor

marihachi commented Feb 11, 2024

一文字からコードポイントの取得はこの関数しかないんですね...
あとは、1文字にto_unicode_codepoint_arrして0番目を取りだすという方法もある?

@marihachi
Copy link
Contributor

1文字からコードポイントを取得する関数があってもよさそうです。
それならcodepoint_atがなくても良いですよね?

@MineCake147E
Copy link
Contributor

codepoint_at(0)を専用の関数にするということでよろしいですか?

@marihachi
Copy link
Contributor

marihachi commented Feb 11, 2024

  1. 文字列をコードポイントの情報を元に文字やコードポイントに分割する
  2. 分割された文字を必要に応じてコードポイントに変換する

この流れでAPIを利用できれば十分だと思います

@FineArchs
Copy link
Member Author

それだと機能が減るだけで変更のメリットが何もないような気がしますが…

@marihachi
Copy link
Contributor

codepoint_atの下位サロゲートが残る問題はjsの仕様で仕方ないですけど、codepoint_atが無くなればその問題は解消されますね

@marihachi
Copy link
Contributor

直感的でない部分が排除されることで、API全体の分かりやすさは向上すると思います。

@marihachi
Copy link
Contributor

少し話が変わりますが
jsが内部的にUTF-16で文字列を保持してるためインデックスもUTF-16コード単位になってると思うので、
AiScriptではコードポイントの配列を文字列の内部表現にするのもアリな気がしました。
コードポイント単位で文字が保持されているならcodepoint_atもうまく実装できそうです。
他のAPIはいろいろ検討する必要がありそうなので分かりませんが。

@FineArchs
Copy link
Member Author

直感的でない部分が排除されることで、API全体の分かりやすさは向上すると思います。

うーんまあ確かにそうかもです

AiScriptではコードポイントの配列を文字列の内部表現にするのもアリな気がしました。

今の実装だと文字列処理では内部的にはJavaScriptの文字列をそのまま使っている訳ですが、それらを全部独自実装に置き換える感じですか?

@marihachi
Copy link
Contributor

marihachi commented Feb 12, 2024

今の実装だと文字列処理では内部的にはJavaScriptの文字列をそのまま使っている訳ですが、それらを全部独自実装に置き換える感じですか?

独自実装といえばそうですね。
文字列からコードポイントの配列、コードポイントの配列から文字列への変換は、今でもやってるようにjsの機能で可能だと思うので、AiScriptのインタプリタが文字列を保持するときにはコードポイントの配列に変換しておくというイメージです。

@FineArchs
Copy link
Member Author

毎回変換すると重くなりそうなので両方保持しておきたい気もします
キャッシュみたいに必要次第で持っておくのもいいかも

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants