crypt of decay - July 3rd, 2017 [entries|archive|friends|userinfo]
ketmar

[ userinfo | ljr userinfo ]
[ archive | journal archive ]

July 3rd, 2017

лисп, замыкания [Jul. 3rd, 2017|02:52 am]
в общем, в итоге я придумал то, что до меня придумали в Lua. видимо, потому, что ничего особо другого не придумывается.

поскольку машина у меня регистровая (дебильное название, конечно; она скорее фрэймослотовая, но принято называть «регистровая» отчего-то), и локалы живут на стеке, а не выделяются в хипе (как делают обычно в компиляторах схемы, например [ладно, ладно, там делают гибридно, но не будем усложнять без нужды]), то я не могу просто таскать вместе с замыканием его окружение: его в явном виде нет.

зато я могу собрать все обращения к upvalues в массив вида «выше на L фрэймов, слот номер N». пока нам не надо создавать полноценное замыкание (а это надо только если ламбду присваивают какой-то перменной — в том числе передают как аргумент), мы обходимся бесплатным (за счёт nan boxing) «стековым недозамыканием», которое просто хранит BP (base pointer: начало стекового фрэйма родителя) на время создания, и ищет апвалуи путём путешествий по цепочке BP. элементы массива опять же укутаны в nan-ы.

а когда надо создать «настоящее» замыкание, мы просто создаём новый массив апвалуев, и заменяем все его элементы на текущие значения, используя точно то же путешествие, что и раньше. теперь у нас значения правильно закрыты.

небольшая сложность состоит в том, что нам может понадобиться закрыть другую ламбду: с ней поступаем тем же самым алгоритмом, рекурсивно. но не забываем схоронять новосозданые замыкания где-то в укромном месте, чтобы не создавать кучу замыканий для одной и той же ламбды, случайно оказавшейся в разных локалах: это будет не просто некорректно в итоге, но ещё и потенциально бесконечно рекурсивно.

тот же процесс надо провести и для всех вложеных функций, но создавать «неполные» замыкания, закрывая только обращения к апвалуям, у которых L больше, чем степерь вложенности текущей обрабатываемой функции. благо, функции у нас first class citizens, и внутри представляют из себя обычные литералы, живущие в массиве литералов (опять прелесть непрямого обращения!), так что их снова можно отпидорасить рекурсией.

в конце этих мучений у нас получится корректное замыкание, которое уже можно раздавать направо и налево. я ему ставлю флажок «full closure», чтобы не сложно трекать это в компиляторе, а дёшево откупиться ничегонеделанием в исполняторе, если флажок уже стоит.

сам по себе алгоритм несложный, но имеет нюансы, которые легко упустить или нечаянно налажать, поэтому с налёта реализовать не получилось, пришлось таки подумать.

ещё одна проблема есть с TCO: оно может грохнуть стековый фрэйм, в котором живут какие-то нужные нам апвалуи. но делать полное замыкание при этом нельзя, потому что тогда вложеные функции перестанут работать правильно (получат по копии локалов родителя, и будут изменять эти копии, что чушь). я про это не подумал, и долго пытался понять, что же за фигня происходит. решение (ещё не реализованое) в том, чтобы опять создать «частичное замыкание», закрыв только значения из того стекового фрейма, который TCO заменит на новый. то есть, строго апвалуи из текущего фрэйма, перед заменой.

вся эта гибкость по созданию частичных и полных замыканий возможна только потому, что мы не кодируем уровни и индексы напрямую в опкоде, а ходим строго индеректом через массив апвалуев. желание «оптимайзнуть», засунув всю информацию в опкод, конечно, возникает сразу, и его сразу же надо давить. иначе реализация правильных замыканий не будет сделана никогда — заебёшься функции пересобирать каждый раз.
Link3 meows|meow!

doom, вады [Jul. 3rd, 2017|03:41 am]
No Sleep For The Dead: впечатления смешаные. то ли я сильно тупил, то ли слишком дохера «нелинейные» уровни, наглухо лишённые каких-либо визуальных «опорных точек». в итоге я довольно часто уныло бэктрэкал с мыслями: «где же эта сраная дверь, я ваш фобос шатал!»

ещё автор любит спамить свиньями, и это раздражает.

в целом: не самый плохой, но особо ничем не примечательный вад. что уже выше среднего, вообще-то. вполне пойдёт как первый эпизод, разве что с монстроспамом переборщили: если идти на 100% kills без инфайтинга, то я не уверен, что патронов хватит.

как обычно, поисками секретов я не занимаюсь, попадаю на них исключительно случайно. иногда попадал. правило ромеры («если наружу видно, наружу должно быть можно») тоже соблюдено, тащемта.

короче: играйте, определённое удовольствие получите. не такое, как от No End In Sight, временами немножко задалбывающее и монотонное, но что-то получите. я бы ещё в такое же поиграл, в принципе.

p.s.: а анонимус ниже говорит, что у него наоборот, патроны с запасом. может и так. ещё один повод проверить лично, например.
Link19 meows|meow!

navigation
[ viewing | July 3rd, 2017 ]
[ go | Previous Day|Next Day ]