Меткив Nemerle
От: hardcase Пират http://nemerle.org
Дата: 27.02.10 21:28
Оценка:
Хочу прояснить механизм работы меток в языке.
Например есть следующий код:
def a = [1, 2, 3, 4];
def x = x_result: {
    foreach(i in a) {
        when(i == 3)
            x_result(i)
    }
    0;
}
WriteLine(x);

Если принять к сведению, что foreach — это макрос, разворачивающийся в рекурсивную функцию, — то каким образом происходит передача управления изнутри нее в метку x_result, находящуюся вовне?
Видимо близким аналогом можно считать такой код:
def a = [1, 2, 3, 4];
def x = x_result: {
    def loop(lst) {
        | i :: tail => 
            when(i == 3)
                x_result(i);
            loop(tail)
        | _ => 0
    }
    loop(a)
}
WriteLine(x);
/* иЗвиНите зА неРовнЫй поЧерК */
Re: Меткив Nemerle
От: hardcase Пират http://nemerle.org
Дата: 27.02.10 21:54
Оценка:
Здравствуйте, hardcase, Вы писали:

Похоже что механизм меток контролирует логику переходов уже после того, как произошли все оптимизации хвостовых рекурсий, так как на код вида
def x = x_result: {
    def loop(lst) {
        | i :: tail => 
            _ = loop(tail);
            when(i == 3)
                x_result(i);
            0
        | _ => 0
    }
    loop(a)
}
WriteLine(x);

компилятор сообщает об ошибке перехода

Error: non local goto (block return?) detected
/* иЗвиНите зА неРовнЫй поЧерК */
Re: Меткив Nemerle
От: VladD2 Российская Империя www.nemerle.org
Дата: 27.02.10 22:30
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Хочу прояснить механизм работы меток в языке.

H>Например есть следующий код:
H>
H>def a = [1, 2, 3, 4];
H>def x = x_result: {
H>    foreach(i in a) {
H>        when(i == 3)
H>            x_result(i)
H>    }
H>    0;
H>}
H>WriteLine(x);
H>


Это не метки, а именованные блоки — базовая фича языка.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Меткив Nemerle
От: Иванков Дмитрий Россия  
Дата: 27.02.10 22:39
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Похоже что механизм меток контролирует логику переходов уже после того, как произошли все оптимизации хвостовых рекурсий

Ну да, примерно так и есть, от того инлайнится ли функция может зависеть компилируемость block return и yield.
Re[2]: Меткив Nemerle
От: Mr.Cat  
Дата: 27.02.10 23:09
Оценка:
Здравствуйте, hardcase, Вы писали:
H>
H>Error: non local goto (block return?) detected
H>

Эх, а со стороны так на named let было похоже.
Re[2]: Меткив Nemerle
От: hardcase Пират http://nemerle.org
Дата: 28.02.10 09:30
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Здравствуйте, hardcase, Вы писали:


H>Похоже что механизм меток контролирует логику переходов уже после того, как произошли все оптимизации хвостовых рекурсий, так как на код вида

H>
H>def x = x_result: {
H>    def loop(lst) {
H>        | i :: tail => 
H>            _ = loop(tail);
H>            when(i == 3)
H>                x_result(i);
H>            0
H>        | _ => 0
H>    }
H>    loop(a)
H>}
H>WriteLine(x);
H>

H>компилятор сообщает об ошибке перехода

H>
H>Error: non local goto (block return?) detected
H>



А ведь в принципе такой код можно сделать рабочим, стоит только вспомнить об исключениях.
x_result(i) выбрасывает исключение, а в блоке x_result происходит его перехват — вуаля, мы получаем результат (да здравствует доширак!). Но, конечно, производительность такого подхода будет невысока.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[3]: Меткив Nemerle
От: nikov США http://www.linkedin.com/in/nikov
Дата: 28.02.10 09:32
Оценка:
Здравствуйте, hardcase, Вы писали:

H>А ведь в принципе такой код можно сделать рабочим, стоит только вспомнить об исключениях.

H>x_result(i) выбрасывает исключение, а в блоке x_result происходит его перехват — вуаля, мы получаем результат (да здравствует доширак!). Но, конечно, производительность такого подхода будет невысока.

И промежуточный catch все испортит. Так, кстати, было сделано в Scala.
Re[4]: Меткив Nemerle
От: hardcase Пират http://nemerle.org
Дата: 28.02.10 09:38
Оценка:
Здравствуйте, nikov, Вы писали:

N>И промежуточный catch все испортит.


Да, заэкранировать catch во внешнем коде не выйдет.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[4]: Меткив Nemerle
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.02.10 12:01
Оценка:
Здравствуйте, nikov, Вы писали:

N>И промежуточный catch все испортит. Так, кстати, было сделано в Scala.


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