KRAZY感情TEXTYLE

"くれいじー かんじよう てきしたいる" と読みます

thread_localメモ

自分用覚書、thread_local!で定義したstatic変数はスレッド毎に LocalKeyという構造体でwrapされる。各スレッド変数はそれぞれ外側に不変である、可変参照をしたいならRefCellを被せたりする。

use std::cell::RefCell;

thread_local! {
    static X: RefCell<Vec<usize>> = RefCell::new(vec![]);
}

fn main() {
    X.with(|v| {
        println!("initial {:?}", v.borrow());
    });

    let j = std::thread::spawn(move || {
        X.with(|v| {
            v.borrow_mut().push(1000);
            println!("other thread {:?}", v.borrow());
        });
    });
    j.join().unwrap();
    X.with(|v| {
        println!("after other thread {:?}", v.borrow());
        v.borrow_mut().push(1024);
    });

    main_other_fn();
}

fn main_other_fn() {
    X.with(|v| {
        println!("main_other_fn {:?}", v.borrow());
    });
}

initial
other thread [1000]
after other thread

main_other_fn [1024]

SEKIROトロコンした

こんにちは、id:Krouton です。初任給でゲーミングPCを買ったんですけど本当に光るんですね、感動しました。

それはそれとしてこのPCでSEKIROをトロコンしたのでエントリ書きます。Discordで友達にGo Liveで配信しながらやってました。途中から社会人のくせに頻度高すぎて誰も来なくなったのは内緒。

f:id:Krouton:20200525105250p:plain
全体の7.1%って結構少ない気がする?
f:id:Krouton:20200525102727j:plain
Steam版です
f:id:Krouton:20200525102730j:plain
IGTは47時間半とかなのでそこそこ早い方?

初見はWikiなど禁止、ただし動画勢の友人達ががヒカルの碁のサイのように助言をしてきたりはありましたが。 2週目からはWiki解禁して最低限のボス+気分で中ボスだったので効率重視でやってました。

TL;DR

未トロコン勢

弦ちゃん倒せたらトロコンできるからそこまで頑張って

その他

いいゲームだから動画エアプ勢もその他も買って(はぁと

SEKIRO: SHADOWS DIE TWICE - PS4

SEKIRO: SHADOWS DIE TWICE - PS4

  • 発売日: 2019/03/22
  • メディア: Video Game

以下雑に語る

思い出が残ってるところだけ、ネタバレありなので注意されたい。

続きを読む

自作言語の構文を考えるのがめんどくさいそこのアナタ、Rustのマクロで楽してもいいわよ?

最近 とっくんのYouTubeチャンネル - YouTube さんの再度ハマり言語野が支配されてます、id:Krouton です。

事の発端

つまり「言語を作りたいけど具象構文考えるのめんどくせ〜〜!!!!」「パーサジェネレータ使うにしてもそれすら書き下すのもめんどくせ〜〜!!!!!」って時ありますよね?(あってくれ)
そんなアナタのためにS式でASTを表現するのをオススメします。Rustが書きたかったのでそうしましたが、他のマクロがサポートされてる言語なら大体できそう?

TL;DR と まとめ

  • (1 + 2) + (3 + 4) を表現するのに
BinOP(
    Box::new(BinOP(Box::new(Number(1)), Add, Box::new(Number(2)))),
    Add,
    Box::new(BinOP(Box::new(Number(3)), Add, Box::new(Number(4)))),
)

から

ast!((+ (+ 1 2) (+ 3 4)))

という風にS式で表現できるようになる。Box::newを手書きするのから解放されるようになる。

  • 簡単にコンパイラのミドルエンド*1から手をつけられるようになる。
  • 言語処理系が書きたくなる。

本編

type AST = Expression;

#[derive(Debug, PartialEq)]
pub enum Expression {
    Number(usize),
    Ident(String),
}

use Expression::*;

impl From<usize> for Expression {
    fn from(n: usize) -> Self {
        Number(n)
    }
}

impl<'a> From<&'a str> for Expression {
    fn from(s: &'a str) -> Expression {
        Ident(s.to_string())
    }
}

macro_rules! ast {
    ($i:ident) => {
        Expression::from(stringify!($i))
    };
    ($e:expr) => {
        Expression::from($e)
    };
}

fn main() {
    dbg!(ast!(2)); // Number(2)
    dbg!(ast!(id)); // Ident("id")
}

ここはFromを使ってるだけで特に難しいところはありませんね。ASTとマクロを拡張して関数適用(Apply)を考えてみましょう。

#[derive(Debug, PartialEq)]
pub enum Expression {
    // 略
    Apply {
        fn_lit: Box<Expression>,
        args: Vec<Expression>,
    },
}

macro_rules! ast {
    (($fn:tt $( $arg:tt )*)) => {
        Apply {
            fn_lit: Box::new(ast!($fn)),
            args: vec![$( ast!($arg), )*]
        }
    };
    // 略
    ($e:expr) => {
        Expression::from($e)
    };
    // exprより後にしないと1 や 2が全てIdentになるので最後に置く
    ($t:tt) => {
        Expression::from(stringify!($t))
    }
}

ast!((print 1 2)); // Apply { fn_lit: Ident("print"), args: [Number(1), Number(2)] }
ast!((+ 1 2)); // Apply { fn_lit: Ident("+"), args: [Number(1), Number(2)] }

ミソとしては四則演算を関数適用として、stringify!で+などの演算子をIdentとして解釈する部分です。これのおかげで、四則演算用のマクロのルールを定義せずに表現できるようになりました。
あとは好きな風にASTを拡張して好きなS式で表現しましょう!

拡張したgist gist.github.com

Special Thanks

*1: コンパイラのミドルエンドって滅多に使わない言葉らしいってWikipedia先生が言ってた コンパイラ - Wikipedia

*2: 質問者は私です

Goの[]byte -> stringへのcastってshrinkするんですか?

珍しく技術系の投稿をします(ただし疑問、忘備録

tooEnoughBuf := make([]byte, tooEnoughSize)
Write1(tooEnoughBuf, src)
string(tooEnoughBuf) == string(src) // false

をしたい時のbufの長さをshrinkする方法を考えています。

なぜこの等価判定がfalseになるかというと

len(tooEnoughBuf) == len(src)

がfalseになるからですね。

func shrinkString(s string) string {
	var eos byte
	buf := make([]byte, 0)
	for _, b := range []byte(s) {
		if b == eos {
			break
		}
		buf = append(buf, b)
	}
	return string(buf)
}

のような実装を与えてあげればいいのだろうか・・・?わからない・・・

株式会社はてなに入社しました

id:Krouton です。株式会社はてなに新卒入社しました。
本日からWebアプリケーションエンジニアです。
株式会社はてなに入社しました - hitode909の日記


所属してる会社は隠そうと思いましたが、GitHubのOrganizationを見れば分かってしまうし隠すのもなんか嫌なのでエントリにすることにしました。試用期間中にリストラされないことを祈っています。
されたら誰か誘ってください。とりあえずがんばります。

www.amazon.jp

五カ年計画(後付)した電気通信大学を卒業しました

こんばんは。3/31で無事卒業できたので電通大卒業エントリを書こうと思います。今は無き情報理工学部の先端工学基礎課程(以下、K課程)に所属していました。

動機

親「国公立に入れ」
僕「家から近いから横国がいいな〜、勉強無理だ。電通大ってとこあるじゃん、前期受けよ!!」

センター試験

僕「緊張しまくって数学半分も解けなかった・・・、もう無理だ、ごちうさでも見てよう」
ごちうさ「線路へぽっぴんジャンプ♪ 恥決定♪」
僕「ア・・・、ア・・・・・」

前期試験後

僕「無理だな、浪人!!」
一緒に電通大受けたフォロワー「俺も無理だった〜、夜間主が2次募集してるんだけど受ける?」
僕「受ける!」

と言った流れで受験し、無事合格しました。フォロワーは落ちました。*1
K課程の2次募集は 3/29-30(午前) に募集、3/30(午後)に合格発表というなかなかアツいスケジュールでした。一人暮らしの人どうやって物件決めたんだ・・・。

1年前期(2015)

Twitterで気が合いそうなオタクを探しながら授業を受ける、バイトをしないといけなかったので授業中に探したりするも1ヶ月ぐらい連続で落ち続ける。*2
プログラミングに興味があったので学内のサークルに入るも、経験がなく何も分からないし、ノートPC持ってなかったので手を動かせずに消える。
Vim vs Emacsみたいなことをしていてたくさん会話してて面白そうだけど一切わからんしここは俺のためのところじゃないなぁと幽霊になる。
結局ファミマでバイトをしてました。初の落単を経験する。

1年後期

幽霊してたサークルの同学年のオタクが技術系バイトをしてることを知る。当人に「最低賃金で立ちっぱのバイトつらそう」と言われ、悔しくなったのでバイト代でMBPを買った。

苦しんで覚えるC言語

苦しんで覚えるC言語

  • 作者:MMGames
  • 発売日: 2011/06/24
  • メディア: 単行本
たのしいRuby 第6版 (Informatics&IDEA)

たのしいRuby 第6版 (Informatics&IDEA)

このへんの本 *3を読んで筋力をつけた。特に実装したいものもなかったが、コードを書きたかったので、基礎科学実験の計算結果を求めるためだったり、LaTeXの表のコードを吐かせるコードを書いたりしてた。実務未経験でバイトを探すのは本当に難しかったが、やる気を買っていただいた人たちと大学名に感謝。Pythonでクローラ書いたりしてた。

2年前期(2016)

SIerっぽいとこがバイト先になった。d3.jsでグラフ書いたり、出たばっかのSwift3を使ってiOSアプリのプロトタイプ版みたいなのを一人で作ったりしてた。JSもSwiftも何もわからなかった。

2年後期

学生ベンチャー企業と掛け持ちした。JSとAWSでサーバサイドをやってた。心理的安全性がありえん低く辛かったのに加え、年明けに高1から付き合ってた彼女に振られて心が壊れる。電車の中で涙が出てきたり、途中下車して号泣したりしてた日もあった。

3年前期(2017)

心が壊れてました。土曜1限起きれなくて落単、これが留年のきっかけになる。あとインターンシップが必修であったので、夏休みに2週間フルタイムで行ってた。そこではCircleCIとシェルをにらめっこしてた。

3年後期

初めて心療内科に行く。行くまでは自分の精神も管理できないどうしようもなくダメな人間だと思っていたけど、見方が変わった。SICPを少し読んだ。インターン先がバイト先になった。ScalaとTypeScriptを雰囲気で書いてた。それまで静的型付けがない言語を触っていたが、型があるといいな〜とか思い始める。この辺から言語に対する興味が強くなった。

4年前期(2018)

セキュキャンのCコンパイラゼミに通る。自分より圧倒的にすごい人達に圧倒される。謙虚になった。セルフコンパイルはできてないし未だにずっと「やろうやろう」考えている。本当に。
knium.hatenadiary.com

K課程は4年前期まで必修が誰でもあるカリキュラムになっているのだが、3年前期の落単科目が突然時間割変更して4年の必修科目に衝突する。留年確定。

4年後期

2科目ぐらいしかなかったのでほぼ引きこもりみたいになってた。わからん。記憶がない。科目はすべて必修だが、出席を取らなかったのでほとんど出た記憶がない。テスト前に教えてくれた友人達に圧倒的感謝。

5年前期

タスクを複数同時に持つと死ぬことを学ぶ。複数持ってたタスクは全部投げ出した。院試を受けたけど全然ダメだった。単位取りきった。就活もした。

5年後期

休学、インターンとバイト、卒業

振り返ってみて

授業の記憶ない・・・。通学に往復3時間かかるとそれだけで起きてる時間の1/5は持ってかれるのでできるだけ近くに住んだほうがいい、でも自分みたいな人間は一人暮らししたら破滅が見えるので難しいね。
4年前期に留年が確定してなかったらセキュキャンに行くことはなかったと思う。*4
GPAが低い自分が言うのもアレですが、情報やプログラミング、CS系は努力した分だけ報われるのがよく分かる分野だと思う。たぶん真の意味で技術は好きじゃないのかもしれないけど、生きる分にはそれでもいいかなってなってきた。何回も挫折したし、やめたくなったけど何とか辞めずに続けたし、これからも何とか続けて生きていたいなぁと思います。

*1: 翌年無事に合格したっぽい

*2: その時までにコンビニ2年半ぐらい経験してたのに・・・

*3: 結局制御構造まではわかったけどポインタはわからんかったぐらい、たのしいRubyは正直覚えてない

*4: 院試と時期被ってたし

Haskellやる

いちいちTokenizerやParserをライブラリを使わずに書くのはダルい。だからパーサジェネレータ(lex/yacc)を使ったりするものだが、Rustで書こうとするとパーサコンビネータである
github.com
が強いっぽい。nomを見てみたら何もわからん状態になったので影響を強く受けたっぽい
github.com
のtutorialから雰囲気でやってみようと思ったけどこれまた何もわからない。
なので、手元にすごいH本もあるしやってみようと思う。