00:04:38 @lo48576@mastodon.cardina1.red
icon

@koba789 Deref 実装してませんでした……

00:10:07 @lo48576@mastodon.cardina1.red
icon

あー、もしかしてこれ PartialEq 追加で解決できるか

00:14:37 @lo48576@mastodon.cardina1.red
icon

うーん?

00:14:47 @lo48576@mastodon.cardina1.red
icon

あーはいはいはいはい

00:17:56 @lo48576@mastodon.cardina1.red
icon

あーーーー完全に把握

00:18:05 @lo48576@mastodon.cardina1.red
icon

AsRef<Eqname> for Box<Eqname> の実装が抜けてたわ

00:19:36 @lo48576@mastodon.cardina1.red
icon

いや、これ普通に std と conflict するとか言われてるし blanket impl あるじゃん

00:27:52 @lo48576@mastodon.cardina1.red
icon

unwrap すると通るのか……

00:31:39 @lo48576@mastodon.cardina1.red
icon

あああああああああああああああああああ

00:33:26 @lo48576@mastodon.cardina1.red
icon

doc.rust-lang.org/1.71.1/std/r

よく見たら
impl<T, E> PartialEq<Result<T, E> for Result<T, E>
where T: PartialEq<T>, E: PartialEq<E>
はあるけど、
impl<T, E, U, F> PartialEq<Result<U, F>> for Result<T, E>
where T: PartailEq<U>, E: PartialEq<F>
がないやんけ!!!

00:33:36 @lo48576@mastodon.cardina1.red
icon

マジかよ

00:33:53 @lo48576@mastodon.cardina1.red
icon

そして assert_eq の文脈でこれに躓くの何度目だよ……

00:34:03 @lo48576@mastodon.cardina1.red
icon

いつも忘れた頃に引っ掛かるんだよなぁ

00:35:31 @lo48576@mastodon.cardina1.red
icon

doc.rust-lang.org/1.71.1/std/r

で、 Result::as_ref() は Result<&T, &E> しか返してくれないので AsRef<U> for T が使えなくて、 Deref<Target=U> for T も意図的に実装を避けているので Result::as_deref() も使えない

00:35:38 @lo48576@mastodon.cardina1.red
icon

はぁ……

00:40:06 @lo48576@mastodon.cardina1.red
2023-08-06 00:36:32 KOBA789の投稿 koba789@misskey.io
icon

このアカウントは、notestockで公開設定になっていません。

00:40:46 @lo48576@mastodon.cardina1.red
icon

仕方ないので

fn ok_as_ref<T, U: ?Sized, E>(res: &Result<T, E>) -> Result<&U, &E>
where
T: AsRef<U>,
{
match res {
Ok(v) => Ok(v.as_ref()),
Err(e) => Err(e),
}
}

みたいなのを用意して、
assert_eq!(ok_as_ref(&foo()), Ok("hello"));
のようにして解決した。あまり愉快ではないが……

00:41:03 @lo48576@mastodon.cardina1.red
icon

何が嫌って、これ本命の処理じゃなくて単なるユニットテストなんだよなぁ

00:41:25 @lo48576@mastodon.cardina1.red
icon

また脇道で苦しんでしまった

00:42:22 @lo48576@mastodon.cardina1.red
icon

assert_eq!(foo().map(AsRef::<str>::as_ref), Ok("hello"));
みたいなのは map でさっさと T が死んでしまって参照が無効になるので駄目

01:57:59 @lo48576@mastodon.cardina1.red
02:37:53 @lo48576@mastodon.cardina1.red
icon

文字列型を沢山定義して相互変換を実装しようとしたら組み合わせが爆発して泣いてる

02:38:21 @lo48576@mastodon.cardina1.red
icon

Nmtoken, Name, QName, NCName, URIQualifiedName, EQName, およびこれらにキャッシュ情報を付けた版

02:39:11 @lo48576@mastodon.cardina1.red
icon

よくよく考えたら、パーサを定義すると同時に「そのパーサが受理するような文字列だけを値として持つような文字列型」も一緒に定義されてくれないと不便極まりないんだよな。自動化するしかない

02:40:23 @lo48576@mastodon.cardina1.red
icon

型を作ってからパーサを書くというのがそもそも順序として微妙。パーサを書いたらそのうちいくつかについて型を割り当てたくなるというのが正しい。だったら根本的にはパーサに何かマーク付けただけで型が生えてきてくれないと困る。

02:41:35 @lo48576@mastodon.cardina1.red
icon

でもなぁ……カスタムのスライス型に適宜トレイトを付けたり付けなかったりを制御しつつ macro で関連実装のボイラープレートを削減するという試み、何回かやって使えるには使えるものができているけど毎回敗北している

02:41:55 @lo48576@mastodon.cardina1.red
icon

モノはあるが諸手を上げて使い続けたいものではないしメンテもしたくない、くらいの……

02:42:14 @lo48576@mastodon.cardina1.red
icon

いやあ厳しい

02:44:50 @lo48576@mastodon.cardina1.red
icon

compiler magic っぽく振る舞ってほしくて、 proc macro が呼び出された context の情報が欲しい。

impl AsRef<str> for Foo {
custom_slicer::auto_impl!();
}

みたいに書いたら

fn as_ref(&self) -> AsRef<str> {
<Foo as custom_slicer::CustomSlice>::as_inner(self)
}

みたいに先祖ブロックのコンテキストを参照してコード生成してくれるようなものがほしいのよ

02:45:43 @lo48576@mastodon.cardina1.red
icon

ここで引数に与える方法で
custom_slicer::auto_impl!(impl AsRef<str> for Foo);
みたいにするのももちろん手ではあるんだが、ちょっと文法的にあまり素敵でないというか……

02:46:11 @lo48576@mastodon.cardina1.red
icon

`OwnedSliceSpec::inner_as_slice_inner` design is always broken for incompatible inner types · Issue #1 · lo48576/validated-slice
github.com/lo48576/validated-s

思い出して鬱になってきた

Web site image
`OwnedSliceSpec::inner_as_slice_inner` design is always broken for incompatible inner types · Issue #1 · lo48576/validated-slice
02:49:38 @lo48576@mastodon.cardina1.red
icon

これは実装自動化というよりは型定義と最低限のインターフェースをどうするかの話か

02:50:15 @lo48576@mastodon.cardina1.red
icon

proc macro で再挑戦してみるかねぇ。その価値はあると今でも思うんだけど、いかんせん実装がつらい

02:54:44 @lo48576@mastodon.cardina1.red
icon

custom-slice-macros - crates.io: Rust Package Registry
crates.io/crates/custom-slice-

トレイト実装を #[derive(..)] 形式にしようとするとつらいので、次やるならこうはしない

02:55:51 @lo48576@mastodon.cardina1.red
02:57:35 @lo48576@mastodon.cardina1.red
icon

現時点での知見としては、

* トレイト実装の自動化は、 #[derive(..)] ではなく impl<..> Trait<..> for Ty<..> {} のような実際の文法に近い形で指定しないとかなりつらい
* underlying slice type と conversion source は完全に分離しないとつらい

などがある

02:59:16 @lo48576@mastodon.cardina1.red
icon

underlying と source の分離というのは、たとえば struct DatetimeStr(str); と struct DatetimeStr([u8]); のどちらも可能だし状況次第でどちらにも優位性があるのでどうするか、というのが underlying type の選択。
DatetimeStr::try_from(&str) と DatetimeStr::try_from(&[u8]) の両方が可能だけどどう実装しようか、というのが conversion source の問題。

03:01:36 @lo48576@mastodon.cardina1.red
icon

impl TryFrom<&[u8]> for DatetimeStr {
type Error = ..;
fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
core::str::from_utf8(bytes)
.map_err(Self::Error::from)
.and_then(Self::try_from)
}
}

みたいにして conversion source をまとめることもできるんだが、これだと parsing で重複したコストがかかることになって非効率な場合があるので、実はよろしくない

03:02:07 @lo48576@mastodon.cardina1.red
icon

たとえば「バイト列に対して実装されたパーサで validation を行っているが文字列の内部では str を持ちたい」みたいな場合に str としての validation は完全に無駄になる

03:03:55 @lo48576@mastodon.cardina1.red
icon

で、そもそもそのような場合だと &[u8] に対して validation したことをもって &str としても valid であるという知識をユーザが暗黙に与えることになるので、たとえばパーサのバグどころかマクロの使い方のミス程度のことでたやすく UB になりかねない。仕方ないといえば仕方ないかもしれないが、さすがにそれはライブラリとして微妙すぎる

03:04:45 @lo48576@mastodon.cardina1.red
icon

自動実装者が持つべき知識をちゃんと表現できないと永遠につらいままだな、これ

03:08:10 @lo48576@mastodon.cardina1.red
icon

尤もマクロの使い方の話をするなら、そもそも #[repr(transparent)] を型定義で忘れていても derive macros でない限り型定義のトークン列を得られないのでどうしようもないなどの問題もあり、一番最初の段階から既にどうしようもなさがあるが

03:15:34 @lo48576@mastodon.cardina1.red
icon

明日はも〜っと疲れるよ。ねっ、ハム太郎!

03:23:54 @lo48576@mastodon.cardina1.red
icon

だんだん思い出してきた、 owned types と borrowed slice types の相互作用とか実装の移譲も考えないといけないのだった……

03:26:48 @lo48576@mastodon.cardina1.red
icon

あと Partial{Eq,Ord} の移譲も……

03:27:38 @lo48576@mastodon.cardina1.red
icon

本題でないことで無限につらみを発掘していくのつらすぎる、もうやめよう

05:58:12 @lo48576@mastodon.cardina1.red
icon

こういう時間に限って進捗が捗るんだよなぁ

07:08:05 @lo48576@mastodon.cardina1.red
icon

激オモタスクが終わった、風呂入って寝るか……

07:08:27 @lo48576@mastodon.cardina1.red
icon

型変換を定義し終えただけでまだパーサを書いていないという地獄

07:24:51 @lo48576@mastodon.cardina1.red
icon

✅ git commit

07:29:11 @lo48576@mastodon.cardina1.red
2023-08-06 07:25:39 たかなしの投稿 g_fukurowl_zenyasai@zenyasai.g-fukurowl.club
icon

このアカウントは、notestockで公開設定になっていません。

07:29:47 @lo48576@mastodon.cardina1.red
icon

おねショタが潜んでいるのを見出してしまって何かの隠語表現なのかと頭を捻っていたが、もしかして文字通りの意味か……

07:30:04 @lo48576@mastodon.cardina1.red
icon

頭が駄目になってるのを暑さのせいにできる季節です (?)

18:42:45 @lo48576@mastodon.cardina1.red
icon

ぽきた

21:57:18 @lo48576@mastodon.cardina1.red
icon

なんかインスタグラムにありそうとか言われそうなとんでもなくハッシュタグだらけの写真投稿流れてきて、いやそういえば fediverse なんだから PixelFed みたいなサーバから流れてきててもおかしくないよなと思って元サイト見てみたら Mastodon だった

23:12:29 @lo48576@mastodon.cardina1.red
2023-08-06 22:36:07 アカハナの投稿 akahana@fla.red
icon

このアカウントは、notestockで公開設定になっていません。

23:13:40 @lo48576@mastodon.cardina1.red
2023-08-05 22:54:48 らりお・ザ・何らかの🈗然㊌ソムリエの投稿 lo48576@mastodon.cardina1.red
icon

クイズ:
LC_TIME=ja_JP.utf-8 環境でカレンダーを表示してくれるのは、以下のどれ?

  • cal ㋇3
  • cal 8月1
  • cal 8月0
  • cal 八月0
23:13:41 @lo48576@mastodon.cardina1.red
2023-08-05 22:57:10 らりお・ザ・何らかの🈗然㊌ソムリエの投稿 lo48576@mastodon.cardina1.red
icon

クイズ2:
前述のクイズの答えの後ろに「2000」を付けて実行した場合の結果は?

  • 2000年8月が表示される1
  • 2000年8月以外の何かが表示される3
  • エラーになる0
23:15:24 @lo48576@mastodon.cardina1.red
icon

ロケールクイズの答えですが、

* 「cal 8月」で8月のカレンダーが表示される。
* 「㋇」「8月」「八月」「葉月」は月として認識されない
* 「cal 8 2000」のようにすると2000年8月が表示されるのに「cal 8月 2000」にするとエラーになる

でした!

Attach image
23:15:30 @lo48576@mastodon.cardina1.red
icon

クソすぎ

23:40:36 23:41:26 @lo48576@mastodon.cardina1.red
icon

@orange_in_space ちゃんとロケール使って解析されてます (8月は en_US.utf-8 で使えず、 August は ja_JP.utf-8 で使えない)

Attach image
23:45:12 @lo48576@mastodon.cardina1.red
icon

自動呪殺