2025-06-02

vak: (Украина)
Украинцы освободили Европу от страха перед российской ядрёной дубинкой. Стратегическая авиация отправилась по маршруту русского военного корабля.

Россияне находятся в иллюзии, что их так называемая ядерная триада даёт им магическую власть над миром. Но в России традиционно всё построено на вранье. Ядрёные бомбы давно протухли. Подлодка Курск как "утонула", так с тех пор и остальные не лучше. Баллистические ракеты не летают. Коллективный путин продолжает трясти своими орешками, то есть "орешником", но над ним не смеётся только ленивый. Только самолёты до недавнего времени продолжали летать, чуть ли не ежедневно бомбя Украину. Но теперь им каюк.

Трамп наверное расстроится. Он собирался продавать Европе безопасность за большие деньги. Но украинцы опять явились, и снова без костюма. Лучше уж Европа вложится в свою и в украинскую оборонную промышленность. Тем более что американское оружие вроде никого нынче защищать не станет. По крайней мере при Трампе.

OCaml

2025-06-02 13:18
vak: (Знайка)
Новая книжка на моей полке.



Свет не сошёлся клином на одном Rust. За последние годы появился ещё один значимый язык. В 2023 году OCaml получил престижную премию SIGPLAN Award. Когда-то в юности я фигел от Снобола-4, позже от Scheme. А здесь всё совсем удобно сделано.



Сижу разбираюсь, как устроен NQCC, компилятор Си из книжки, написанный на OCaml. И прихожу к выводу, что сделан он весьма неплохо, причём во многом благодаря OCaml. Если бы я сейчас начинал какую нибудь серьёзную разработку типа компилятора, возможно я бы делал его на OCaml вместо Rust или Golang.

Для примера, перепрём /bin/echo на OCaml.
let process_escapes str =
let len = String.length str in
let buf = Buffer.create len in
let rec loop i =
if i >= len then Buffer.contents buf
else if str.[i] <> '\\' then (
Buffer.add_char buf str.[i];
loop (i + 1)
) else if i + 1 < len then (
match str.[i + 1] with
| 'n' -> Buffer.add_char buf '\n'; loop (i + 2)
| 't' -> Buffer.add_char buf '\t'; loop (i + 2)
| '\\' -> Buffer.add_char buf '\\'; loop (i + 2)
| _ -> Buffer.add_char buf str.[i]; loop (i + 1)
) else (
Buffer.add_char buf str.[i];
loop (i + 1)
)
in
loop 0

let echo no_newline enable_escapes args =
let process = if enable_escapes then process_escapes else fun x -> x in
let output = String.concat " " (List.map process args) in
if no_newline then print_string output
else print_endline output

let main () =
let no_newline = ref false in
let enable_escapes = ref false in
let args = ref [] in
let speclist = [
("-n", Arg.Set no_newline, "do not output the trailing newline");
("-e", Arg.Set enable_escapes, "enable interpretation of backslash escapes");
] in
Arg.parse speclist (fun arg -> args := arg :: !args) "Usage: echo [-n] [-e] [string ...]";
echo !no_newline !enable_escapes (List.rev !args)

let () = main ()
Компилируем, запускаем:
$ ocamlopt -O2 -o echo echo.ml

$ ./echo --help
Usage: echo [-n] [-e] [string ...]
-n do not output the trailing newline
-e enable interpretation of backslash escapes
-help Display this list of options
--help Display this list of options

$ ./echo -e "Hello\nWorld"
Hello
World