История изменений
Исправление AndreyKl, (текущая версия) :
Т.е. реализовали перезапуски из лиспа? Круто. А чем-то за это приходится жертвовать? Просто получается есть два механизма для одного и того же, но эффекты лучше исключений во всём.
Да, перезапуски. Лисп вообще в переди планеты всей)). В целом это легко реализуется в любом языке, хоть в том же хаскеле с использованием монад или алгебраических эффектов. Не знаю часто ли это использовалось, поскольку для узких по производительности мест это было использовать сложнее - всё в куче. Мне пользоваться не доводилось.
Разница с текущей реализацией в окамле именно в том что в окамле это объекты первого класса, то есть поддерживаются компилятором и работают со стеком а не с кучей, соответственно работать удобнее (меньше бойлерплейта) и на данный момент пожертвовали типизацией. Т.е. эффекты - это нетипизированные исключения по сути. Механизм, видимо, один: теперь исключение - отдельный случай в обработчике эффектов. В реальном коде сейчас обработчик - это запись вот такого типа
type ('a,'b) handler =
{ retc: 'a -> 'b;
exnc: exn -> 'b;
effc: 'c.'c t -> (('c,'b) continuation -> 'b) option }
т.е. мы можем сказать что делать если функция вернула результат (
retc), если бросила исключение (exnc) и если выполнила какой-то эффект (effc).Имея функцию вида
let int_of_string l =
try int_of_string l with
| Failure _ -> perform (Conversion_failure l)
let rec sum_up acc =
let l = input_line stdin in
acc := !acc + int_of_string l;
sum_up acc
описав обработчик вида
hdl = { effc = (fun (type c) (eff: c Effect.t) ->
match eff with
| Conversion_failure s -> Some (fun (k: (c,_) continuation) ->
Printf.fprintf stderr "Conversion failure \"%s\"\n%!" s;
continue k 0)
| _ -> None
)}
мы вызываем его так
match_with sum_up hdl
Но это всё в данный момент `unchecked exceptions` т.е. если мы не поймали что то, компилятор не предупредит нас об этом, а мы просто получим исключение в рантайме.
Вроде бы то ли в 5.7, то ли в 6.0 обещают что всё будет типизировано. Прототип в OxCaml уже работоспособен.
Исходная версия AndreyKl, :
Т.е. реализовали перезапуски из лиспа? Круто. А чем-то за это приходится жертвовать? Просто получается есть два механизма для одного и того же, но эффекты лучше исключений во всём.
Да, перезапуски. Лисп вообще в переди планеты всей)). В целом это легко реализуется в любом языке, хоть в том же хаскеле с использованием монад или алгебраических эффектов. Не знаю часто ли это использовалось, поскольку для узких по производительности мест это было использовать сложнее - всё в куче. Мне пользоваться не доводилось.
Разница с текущей реализацией в окамле именно в том что в окамле это объекты первого класса, то есть поддерживаются компилятором и работают со стеком а не с кучей, соответственно работать удобнее (меньше бойлерплейта) и на данный момент пожертвовали типизацией. Т.е. эффекты - это нетипизированные исключения по сути. Механизм, видимо, один: теперь исключение - отдельный случай в обработчике эффектов. В реальном коде сейчас обработчик - это запись вот такого типа
type ('a,'b) handler =
{ retc: 'a -> 'b;
exnc: exn -> 'b;
effc: 'c.'c t -> (('c,'b) continuation -> 'b) option }
т.е. мы можем сказать что делать если функция вернула результат (
retc), если бросила исключение (exnc) и если выполнила какой-то эффект (effc).Имея функцию вида
let int_of_string l =
try int_of_string l with
| Failure _ -> perform (Conversion_failure l)
let rec sum_up acc =
let l = input_line stdin in
acc := !acc + int_of_string l;
sum_up acc
описав обработчик вида
hdl = { effc = (fun (type c) (eff: c Effect.t) ->
match eff with
| Conversion_failure s -> Some (fun (k: (c,_) continuation) ->
Printf.fprintf stderr "Conversion failure \"%s\"\n%!" s;
continue k 0)
| _ -> None
)}
мы вызываем его так
match_with sum_up hdl
Но это всё в данный момент `unchecked exceptions` т.е. если мы не поймали что то, компилятор не предупредит нас об этом, а мы просто получим исключение в рантайме.
Вроде бы то ли в 5.7, то ли в 6.0 обещают что всё будет типизировано. Прототип в OxCaml уже работоспособен.