LINUX.ORG.RU

Интерпретация vs компиляция

 ,


0

3

Существует мнение, что интерпретируемый язык гораздо мощней компилируемого. Я много думал, над этим, над сутью этого явления.

На первый взгляд, никакой разницы нет. Допустим, мы захотели получить на вход программы результат работы (исполнения) подпрограммы. Кажется, в этом преимущество? Но вполне возможно реализовать такое и в компилируемом языке. Просто изнутри исолнения можно вызвать некий модуль, который выполнится и отдаст результат на вход основной программы. Реально сделать это и в компил-тайме.

Тогда, что же делает интерпретируемые языки мощными?

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

Крайним случаем выразительности компилируемого языка являются, наверное, макросы. Однако, макросы имеют доступ вовсе не к рантайму, а лишь к исходному коду программы,поэтому они все равно сосут, по сравнению с eval.

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

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

И че, в лиспе для такой простой задачи нужны макросы и евал?

Кстати, любопытно посмотреть, как это решается на *твоем любимом* ЯП. Все-таки, решение на newlisp довольно изящное, имей в виду, что at-least-two — это «обычная» функция.

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

Но в CL и Scheme,например, это так просто не решается.

(define-syntax-rule (at-least-two a ...)
  (let ([c 0])
    (let/ec return 
      (when a (set! c (add1 c)) 
        (when (= c 2) (return #t))) ... 
      #f)))
monk ★★★★★
()
Ответ на: комментарий от terminator-101

at-least-two — это «обычная» функция.

Тогда что у неё в качестве аргументов? Если считать, что куски кода, то в синтаксисе Scheme это будет

(define (at-least-two . args)
  (eq? 2 (for/fold ([c 0]) ([x (in-list args)]
                   #:break (eq? c 2))
              (if (x) (+ c 1) c)))]))

(at-least-two
   (lambda () (= 2 4))
   (lambda () (= 1 1))
   (lambda () (= 2 2)) ; тут выходим
   (lambda () (= 3 2))
   (lambda () (infinit-loop)))
monk ★★★★★
()
Ответ на: комментарий от monk

let/ec

это call/cc?

Решение все равно не эквивалентное. Ты же не сможешь передать свой at-least-two в качестве аргумента, правильно?

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

Ты же не сможешь передать свой at-least-two в качестве аргумента

Туда где ожидается функция — естественно. Так как функция должна получать в качестве аргументов значения, а не куски кода. Вариант с функцией Интерпретация vs компиляция (комментарий)

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

Тогда что у неё в качестве аргументов?

А fexprs не вычисляет свои аргументы, примерно как макросы, или аргументы в tcl или sh

В данном случае — списки, но квотирование не нужно.

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

это call/cc?

Можно и без call/cc

(define-syntax-rule (at-least-two e ...)
  (let ([c 0])
    (for ([l (list (lambda () e) ...)]
          #:when (l)
          #:break (= c 2))
      (set! c (add1 c)))
    (>= c 2)))
monk ★★★★★
()
Ответ на: комментарий от terminator-101

ы же не сможешь передать свой at-least-two в качестве аргумента, правильно?

Могу, конечно: (syntax-local-value #'at-least-two) и хоть запередавайся.

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

Алсо, оно на newlisp проще исключительно из-за формы doargs. Если в схемке сделать такую же - будет один в один решение.

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

Ну, например, в javascript, picolisp, newlisp. Есть языки, короче

Это те недоязыки которые не осилили лескическую область видимости для переменных? Динамические переменные eval и в CL видит.

А в js:

function z() { var x=105; return function(){ console.log(x) }; }
var p=z();
p() // 105
function s() {eval('p()')}
s() // ReferenceError: x is not defined

Ну и кому ты тут втираешь?

picolisp, newlisp

В приличном обществе такие слова не произносят.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

которые не осилили лескическую область видимости для переменных

В них во всех есть лексическая область, в js — по-дефолту.

не осилили

А тебя не настораживает, что абсолютно все быдло-яп с лексической видимостью?

Ну и кому ты тут втираешь?

Во первых, в твоем примере нет никакого ReferenceError. Ты где проверял? Во-вторых, где ты там нашел доступ к текущему окружению?

terminator-101
() автор топика
Ответ на: комментарий от anonymous

хоть запередавайся.

Да? А не подскажешь, во что раскроется вот это?

(define (test the-macros) (the-macros (user-input)))
А главное, когда?

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

Да? А не подскажешь, во что раскроется вот это?

А с чего бы оно должно раскрываться куда-то? Это обычная аппликация функции к аргументам. Будет вычислена в рантайме, точно так же как в любом интерпретируемом ЯП.

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

А как теперь заставить newlisp раскрыть эту форму

Там ничего не раскрывается. Это обычная функция, только ленивая.

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

Да? А не подскажешь, во что раскроется вот это?

О чем и речь. Язык с фекспрами = язык с обычными функциями. Фекспры никак не повышают выразительность языка. С другой стороны, макросы - повышают. По-этому макросы строго выразительнее фекспров.

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

Нет, обычная функция в рантайме.

Ты же утверждал, что макрос можно передать в качестве аргумента, так-же как и функцию. Если это обычная ф-ция, откуда там возьмется лень в рантайме?

terminator-101
() автор топика
Ответ на: комментарий от anonymous

Язык с фекспрами = язык с обычными функциями

С ленивыми функциями. В чем ленивые функции уступают по-твоему макросам, в плане выразительности?

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

Ты же утверждал, что макрос можно передать в качестве аргумента, так-же как и функцию.

Ну да. Макрос - это и есть обычная функция. Язык с макросами от языка без макросов отличается тем, что мы можем вызывать обычные ф-и не только в рантайме, но и в компайлтайме. В языке с фекспрами обычные ф-и можно вызывать только в рантайме. По-этому фекспры менее выразительны.

Если это обычная ф-ция, откуда там возьмется лень в рантайме?

Оттуда же, откуда она берется в newlisp.

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

С ленивыми функциями.

Нет, лень тривиально реализуется в любом строгом языке.

В чем ленивые функции уступают по-твоему макросам, в плане выразительности?

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

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

Макрос - это и есть обычная функция.

Ты упоролся.

Оттуда же, откуда она берется в newlisp.

Еще раз объясняю. Это обычная функция, а не макрос. Она исполняется в рантайме.

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

Ты упоролся.

Нет. Макрос - обычная функция, которую можно вызвать в компайлтайме, не более того.

Еще раз объясняю. Это обычная функция, а не макрос. Она исполняется в рантайме.

Ну вот. Что тебе неясно, если ты сам прекрасно ответил на свой вопрос?

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

Что-то я не вижу там сравнения макросов с фекспрами. А почему «why macros» в вакууме, это так же как «why monads» в вакууме.

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

Что-то я не вижу там сравнения макросов с фекспрами.

Там написано для чего применяются макросы и, в частности, объясняется, что юзкейсы не сводятся к лени.

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

Нет. Макрос - обычная функция, которую можно вызвать в компайлтайме, не более того.

это спец форма, а не ф-ция.

можно вызвать в компайлтайме, не более того

Ты забыл добавить, что нельзя в рантайме. А это и есть основной отсос.

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

это спец форма, а не ф-ция.

Чем макрос отличается от функции?

Ты забыл добавить, что нельзя в рантайме.

почему нельзя? Можно. С каких пор обычные функции нельзя использовать в рантайме?

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

Какие нах обычные. Ты о макросах говорил.

А макрос - это обычная функция, которую можно вызывать в компайлтайме.

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

Ты понимаешь вообще что такое макрос?

Коненчо. Макрос - обычная функция, которую можно вызывать в компайлтайме. Все.

Временем жизни,епт.

Ну так у нее время жизни до окончания работы программы. Иначе нельзя было бы засунуть форму с макросом в евал.

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

Например, компиляция регулярного выражения в NFA, с оптимизацией.

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

Приведи пример юзкейса макроса, который не сводится к лени.

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

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

Объясни, на кой лысый тебе генерить код в рантайме? Макросы нужны для преобразования кода, а это всегда медленно или очень медленно. Медленный рантайм не нужен, всю тормозню надо переносить во время компиляции. Те же регулярные выражения, например, надо компилировать сразу, статически, а не тратить на это время в рантайме.

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

Ну так у нее время жизни до окончания работы программы. Иначе нельзя было бы засунуть форму с макросом в евал.

Там, скорей всего, идет перекомпиляция в рантайме. После раскрытия макроса, он перестает существовать.

terminator-101
() автор топика
Ответ на: комментарий от anonymous

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

Все что там перечислено — сводится

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

А как свести любую спец форму? потому что это синтаксис, который не должен вычислять свои аргументы.

Бред. Аргументы могут быть вообще невычислимыми (те же регулярные выражения). Что за чушь ты несешь вообще?

Сведи компилятор регулярных выражений к лени. Не переводи тему до тех пор, пока не осилишь.

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