- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
next_int() ->
receive {next_int, N} ->
self() ! {next_int, N + 1},
N
after 0 ->
self() ! {next_int, 0},
0
end.
...
[{A, next_int()}|| A <- SomeList]
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
+131
next_int() ->
receive {next_int, N} ->
self() ! {next_int, N + 1},
N
after 0 ->
self() ! {next_int, 0},
0
end.
...
[{A, next_int()}|| A <- SomeList]
Простейший способ пронумеровать элементы списка эрланге. Найдено в продакшне, ошибки сохранены.
bormand 12.12.2014 06:49 # 0
roman-kashitsyn 12.12.2014 11:20 # +2
guest 12.12.2014 18:32 # +2
> чистота
wvxvw 12.12.2014 12:07 # 0
За два прохода.
За один проход, но без хвостовой рекурсии.
Вобщем, хорошего способа по-настоящему чет не наблюдается.
bormand 12.12.2014 18:26 # 0
wvxvw 12.12.2014 18:34 # 0
bormand 12.12.2014 18:35 # 0
http://ideone.com/1crYjm
wvxvw 12.12.2014 18:54 # 0
Ну мой первый вариант тоже с реверсом тогда такой же.
А вообще, я тут подумал, без частично инстанциированых типов данных (альтернатива присваиванию), или нарушения всех трех принципов субструктурной системы типов (обмен, послабление и упрощение) невозможно генерировать список в направлении от начала к концу. Я думаю, что если напрячься, то это како-то формально можно выразить.
bormand 12.12.2014 19:03 # 0
> невозможно генерировать список в направлении от начала к концу
Вроде бы. Не от хорошей же жизни в эрланге всё через хвостовую рекурсию и lists:reverse() пишут.
> формально можно выразить
Ну совсем не формально, но как-то так: мы можем прицепить элемент в начало списка (тем самым строя его с конца); мы можем добавить элемент в конец, скопировав весь список (медленно); мы можем забуферизовать элементы на стеке (не хвостовая рекурсия) и мы можем забуферизовать их в списке (хвостовая рекурсия + reverse). Вроде бы других вариантов тупо нет.
wvxvw 12.12.2014 19:05 # 0
Он же мне на почту приходит :)
bormand 12.12.2014 19:10 # 0
bormand 12.12.2014 19:11 # 0
Вернее они есть, но они сводятся к буферизации элементов в том или ином виде.
Всё печально. lists:reverse/1 неизбежен.
P.S. Радует только то, что джва прохода это всё еще O(n), просто с большей константой, и то, что lists:reverse/1 достаточно шустрый, чтобы не увеличить эту константу вдвое.
bormand 12.12.2014 19:25 # 0
Кстати, а foldr в эрланге поди сначала переворачивает список, а потом отдаёт его foldl'у?
wvxvw 12.12.2014 19:46 # 0
bormand 12.12.2014 19:52 # 0
В теории можно сделать на сях - никто не увидит узлы пока генератор не вернул результат, поэтому можно внаглую добавлять новые в конец. В реализации map'а можно поступить аналогично.
P.S. Но это может нарушить временные характеристики - емнип, тред нельзя прервать, пока он исполняет bif.
guest 12.12.2014 17:40 # −4
>Production
ЩИТО
bormand 12.12.2014 18:15 # +1