LINUX.ORG.RU

расширяемая система

 , ,


1

3

http://www.gnu.org/software/emacs/emacs-paper.html#SEC17

Ричард Столлман на наглядном примере поясняет, что замена динамического связывания явной передачей аргументов, в расширяемых системах означает де-факто, что такие системы вместо расширения переписываются полностью.

Поскольку большинство современных языков не имеют динамического связывания, это означает, что системы, написанные на таких языках вообще никогда не являются расширяемыми системами. Все что произносится относительно этих языков по поводу расширяемости, совместного повторного использования кода, рефакторинга и тп, является не более чем баззвордами и мантрами, и никакого отношения к реальности не имеет.



Последнее исправление: linearisation (всего исправлений: 3)

Ответ на: комментарий от linearisation

Не в каждом статически-компилируемом ЯП есть такие возможности?

Если имеется в виду в «статически-типизированном», то да, не в каждом. И не в каждом динамически-типизированном. В Javascript, например, нету.

Miguel ★★★★★
()
Ответ на: комментарий от Miguel

статически компилируемые языки

Это ещё что?

Это те, которые компилируемые, но при этом не динамически компилируемые. И, к слову, в них всех работает longjmp за редким исключением.

monk ★★★★★
()
Последнее исправление: monk (всего исправлений: 1)
Ответ на: комментарий от Miguel

при этом не динамически компилируемые

А это что?

Java, и прочий JIT.

monk ★★★★★
()
Ответ на: комментарий от tailgunner

Нет, пройти вверх по стеку и изменить словарь локальных переменных.

В питоне можно изменить адрес возврата в стеке? А как?

monk ★★★★★
()
Ответ на: комментарий от monk

Динамические проще перечислить где есть: Scheme и Ruby.

Это ты говоришь про «полноценные» первоклассные продолжения с возможностью возврата, динамический перехват выброшенного исключения реализован во многих ЯП, например в JS,


main = function(){
   try{foo()()}catch(e){console.log(e + " was catched dynamically")}
}

foo = function(){
   try{return function(){throw "foo"}}catch(e){console.log(e + "was catched statically")}
}

main() // из main мы вызываем внутреннюю функцию, исключение перехватывается динамически, в main, c места вызова, это форма продолжения.

//>>>> foo was catched dynamically

и даже JAVA, ЕМНИП, поддерживает.

linearisation
() автор топика
Ответ на: комментарий от Miguel

В Javascript, например, нету.

В нем, как раз есть, см пример выше

linearisation
() автор топика
Ответ на: комментарий от linearisation

Я уже сказал, что это мантры. На самом деле они переписываются подчистую, под видом рефакторинга. Сама по себе явная передача аргументов этому способствует.

Ну пусть даже так :-) Этому способствует не какая-то там «явная передача аргументов», а появление новых требований к программе :-) Нет требований - значит менять для красоты - кому это надо кроме идеалистов? :-) И, кстати, ты наверное слышал, что любая функция имеет всегда ровно 1 аргумент, поэтому любая функция f(x, y) = f(g(y)) :-) Для тех, кому это не понятно, есть всякие там JSON'ы - делаешь 1 аргумент f(json_object) и расширяй json_object сколько хочешь :-) А ещё есть глобальные переменные, которые нынче модно называть синглтонами :-)

Вот это они называют умными словами — добавление функционала и тп, де факто это тупое переписывание кода, из-за хардкора, порожденного статичным кодом

Будто с динамическим экстентом переписывание становится умным :-) Лол :-)

anonymous
()
Ответ на: комментарий от linearisation

динамический перехват выброшенного исключения реализован во многих ЯП, например в JS,

try/catch фактически реализован во всех. Либо штатно (если есть понятие исключения), либо через signal() и raise(), если «на коленке».

monk ★★★★★
()
Ответ на: комментарий от linearisation

каким образом он перехватывает брошенные исключения

Так везде динамически. На С++

func foo() {
  try {
    return []() { throw "foo" }}
  } catch (...) { cout << "statically" }
}

int main() {
  try {
    foo()(); 
  } catch (...) { cout << "dynamically" }
}

будет работать так же

monk ★★★★★
()
Ответ на: комментарий от cvv

Простое и доступное обьяснение

«If that makes sense to you, you've got a problem» (c)

tailgunner ★★★★★
()
Ответ на: комментарий от monk

А такой код тоже работает аналогично?


foreach = function(array, handler){
    if(array.length < 0) return
    handler(array[0])
    foreach(array.slice(1), handler)
}

try{
 foreach([1, 2, 3, 4, 5, 6, 7], function(element){if(element === 4) throw 4; console.log(element)})
}catch(e){console.log("stop on " + e)}



//>>>> 1
//>>>> 2
//>>>> 3
//>>>> stop on 4

linearisation
() автор топика
Ответ на: комментарий от monk

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

Лямбды в C++ — это объекты неизвестного типа, создающиеся на стеке.

в другом месте пишут:

when inner functions can escape, the question of the visibility of variables from the outer functions becomes rather complex: the duration of closures is greater than simply the execution time of the function, and the simple stack-based model of computation fails (garbage-collection must be used, the closures must be stored on the heap rather than on the stack)

linearisation
() автор топика
Ответ на: комментарий от monk

А кроме того, я где то читал, что в С++ стек обязан разматываться полностью, поэтому, как-бы, непонятно, как там может быть «escape procedure», которая работает таким образом

linearisation
() автор топика
Ответ на: комментарий от linearisation

такой код тоже работает аналогично?

Да. Абсолютно.

в С++ стек обязан разматываться полностью

Так он и разматывается. Функция handler вызвана из foreach, который вызван из main (в JS из <toplevel>). handler кидает исключение. Внутри handler оно не ловится, все переменные хандлер очищаются (в смысле вызова деструктора), в foreach оно не ловится, все переменные foreach очищаются. В main поймалось и передалось в catch.

Про размотку стека упоминают в том смысле, что нельзя написать что-то вроде

try{
 foreach([1, 2, 3, 4, 5, 6, 7], function(element){if(element === 4) throw 4; console.log(element)})
}catch(e){console.log("cathed " + e); continue_after(e);}

Но это и в JS так. Можно в CL (через handler-bind) и Scheme (через продолжения).

monk ★★★★★
()
Ответ на: комментарий от linearisation

А зачем это разматывание и вызовы деструкторов для языков с GC?

Для языков с GC тела размотанных функций и переменные в них становятся с точки зрения GC недоступными и могут быть собраны.

Деструкторы в языках с GC бывают вида try/finally. При размотке блок finally выполняется.

monk ★★★★★
()
Ответ на: комментарий от monk

Но зачем разматывать весь стек (для языка с GC), если можно просто запоминать адреса перехватчиков, если таковые имеются на стеке?

linearisation
() автор топика
Ответ на: комментарий от monk

Я имею в виду, точно так же как при штатном исполнении, есть адрес возврата, так же можно иметь адрес возврата при аварийном завершении, и переходить туда непосредственно, не разматывая весь стек последовательно. Ведь смысл разматывания стека в С++ как раз и заключается в вызове деструкторов? Но поскольку у нас есть GC, этого не требуется, так как ссылки на объекты созданные в процессе формирования стека не будут доступны из root, и соответственно, будут удалены автоматически, при очередном проходе GC

linearisation
() автор топика

Когда тебя уже забанят, генератор тупака.

anonymous
()
Ответ на: комментарий от linearisation

так как ссылки на объекты созданные в процессе формирования стека не будут доступны из root, и соответственно, будут удалены автоматически

Так это и есть разматывание стека. Делание недоступными ссылки с участка стека, относящегося к области видимости функции.

переходить туда непосредственно, не разматывая весь стек последовательно

Если у тебя нет try/finally, unwind-protect или dynamic-wind, то можно и непосредственно. В сишном longjmp так и происходит. А вот в Java из-за finally надо разматывать последовательно.

monk ★★★★★
()
Ответ на: комментарий от anonymous

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

На то они и хакеры, что говно всякое стороной обходят.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.