metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2010-08-25 12:47 pm

Потаенный червизм F#

В F# есть набор вуду-функций, типизация которых у меня вызывает неадекватные ощущения. Конкретно, это функции форматированной печати, например sprintf:
sprintf "%s" : string->string //превращает строку в строку
sprintf "%s %d" : string->int->string //превращает строку и число в строку
Итд, соответственно формату.
Выглядит это весьма удобно и типобезопасно, т.е. неправильное сочетание строки формата и параметров не скомпилируется, но как реализована функция sprintf и аналогичные, я с ходу не соображу.
Там используется какое-то адское метапрограммирование на типах + дотнетовский Reflection, причем даже intellisense в студии показывает, что тип возвращаемый sprintf fmt меняется в зависимости в от того, что запишешь в fmt. И строковый литерал fmt явно где-то хитрой магией конвертируется не в строку, а в String.Format<'T>.

[identity profile] usovalx.livejournal.com 2010-08-25 12:59 pm (UTC)(link)
В ванильном ocaml тоже такое вуду есть. И вроде какая-то документация как оно сделано и как делать самому.

[identity profile] potan.livejournal.com 2010-08-25 01:03 pm (UTC)(link)
В OCaml Printf.printf типизирован так, что компилятор проверяет правильность формата, а реализован через жоunsafe-работу с памятью.
Я когда-то переписывал его через макрос, но как-то лениво поддерживать было.

[identity profile] metaclass.livejournal.com 2010-08-25 01:15 pm (UTC)(link)
Вот я счас в F# ищу, как бы это к реализации подобраться и использовать в своих целях, но там только простые обертки вокруг общей реализации вроде доступны.

[identity profile] zamotivator.livejournal.com 2010-08-25 01:24 pm (UTC)(link)
В ocaml это делается через camlp4

[identity profile] vaddimka.livejournal.com 2010-08-25 01:25 pm (UTC)(link)
sprintf "%s %d" : string->int->string

нет ли тут ошибки? вроде как два аргумента должно быть

[identity profile] cd-riper.livejournal.com 2010-08-25 01:30 pm (UTC)(link)
> но как реализована функция sprintf и аналогичные, я с ходу не соображу.

для меня тож была загадка, но я F# так и не доучил.

как я понимаю, метапрограммирование -- строку для форматирования нужно в compile-time проанализировать и под это дело код подстроить. либо выдать ошибку.

[identity profile] metaclass.livejournal.com 2010-08-25 01:50 pm (UTC)(link)
Тут и есть два.

[identity profile] potan.livejournal.com 2010-08-25 02:07 pm (UTC)(link)
Когда я смотрел реализацию - не делалось. Я переделал, но народ тогда не оценил. Неужели сейчас одумался?

[identity profile] zamotivator.livejournal.com 2010-08-25 02:09 pm (UTC)(link)
Гм, а как оно ещё может быть сделано?
Batteries те же самые как делают?

[identity profile] potan.livejournal.com 2010-08-25 02:11 pm (UTC)(link)
Комментом выше описал :-).

[identity profile] zamotivator.livejournal.com 2010-08-25 02:11 pm (UTC)(link)
Ты хочешь сказать, что это на уровне КОМПИЛЯТОРА сделано?

[identity profile] potan.livejournal.com 2010-08-25 02:18 pm (UTC)(link)
bash$ ocaml
        Objective Caml version 3.10.2

# Printf.printf;;
- : ('a, out_channel, unit) format -> 'a = <fun>
# let s : ('a, out_channel, unit) format = "%d" in s;;
- : (int -> unit, out_channel, unit) format = <abstr>


Я не знаю, как такое сделать в camlp4 :-).

[identity profile] nivanych.livejournal.com 2010-08-25 03:14 pm (UTC)(link)
Судя по расписанию, эти темы разрабатываются кружком имени Эсфири Мендееевны.
Так держать!

[identity profile] thedeemon.livejournal.com 2010-08-25 06:24 pm (UTC)(link)
Не, использование camlp4 надо отдельно указывать, по умолчанию он не используется, однако printf доступен.

(Anonymous) 2010-08-26 05:31 am (UTC)(link)
В хаскелле printf реализован через классы типов, вроде бы.

[identity profile] migmit.vox.com (from livejournal.com) 2010-08-26 09:20 am (UTC)(link)
Вроде, в окамле "%s %d" может быть не string, а какая-то хреновня, тип которой зависит от того, что внутри написано.

[identity profile] metaclass.livejournal.com 2010-08-26 09:21 am (UTC)(link)
В F# то же самое.