Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, korvin_, Вы писали:
_>>Что делать в языках с GC без явного разграничения стэк/куча? Возьмём, к примеру, Hashell или Ocaml. Куда добавить OutOfMemory?
S>Простите, я не понимаю ваш вопрос. Мне, если честно, строго всё равно, откуда malloc берёт память — со стека или из кучи.
S>Может, она вообще для одних n берёт из одного места, а для других — из другого.
S>Но как только malloc может закончиться неудачей, я добавляю это в сигнатуру malloc.
S>Опять же — если я считаю, что пользователю достаточно признака успешности, то у меня получается (T[] | undefined), он же Optional<T[]>.
S>А если мне интересны сценарии вроде "если не хватило памяти для X, давайте захватим X/2", то может потребоваться более интересная сигнатура, вроде (T[] | OutOfMemory), где OutOfMemory — это не унитарный тип, а некая структура с подробностями вроде хинтов на предмет того, какие n были бы приемлемыми.
Хорошо, давайте на примере.
Сначала Java:
class Foo {
...
// constructor
Foo(...) {
...
}
...
}
...
var x = new Foo(...);
Где здесь должно быть указано, что new Foo может вернуть не объект класса Foo, а OutOfMemory? В сигнатуре конструктора Foo? В "сигнатуре" оператора new? Тот же вопрос про StackOverflow: где он должен быть указан? В сигнатуре каждой функции (метода)? Операция () вызов метода автоматически должна его добавлять к каждому методу?
Теперь Haskell. Имеем такой код, например:
data Expr
= Val Int
| Add Expr Expr
| Mul Expr Expr
| If Expr Expr Expr
eval :: Expr -> Expr
eval e = ...
expr0 = If (Mul (Val 1) (Val 0))
(Add (Mul (Val 4) (Val 10))
(Val 2))
(Mul (Add (Val 7) (Val 14))
(Val 2))
print (eval expr0)) -- Val 42
Где тут должено быть указано OutOfMemory?