LINUX.ORG.RU

[scheme vs lisp] Область видимости переменных.


0

2

Здравствуй, ЛОР!

У меня есть нубский вопрос. В scheme существует исключительно статические (а не динамические) области видимости переменных, а в common lisp динамические и статические. Есть ли преимущества только одной видимости переменных, как в scheme?


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

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

С другой стороны, динамические переменные могу обеспечить более высокий уровень гибкости, и вообще, динамические переменные одна из самых прикольных фишек CL ;)

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

Т.е., как бы, можно написать такой код на CL который нельзя написать на схеме вообще? Или на схеме, «фишки» завязанные на динамические переменные, реализовать можно, но с большими усилиями?

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

> Т.е., как бы, можно написать такой код на CL который нельзя

написать на схеме вообще?


Неправильная постановка вопроса, что значит нельзя написать вообще? Я не понял, что именно вас интересует ((

Динамические переменные это улучшенный вариант глобальных переменных, без свойственных им (глобальным переменным) недостатков и они могу (должны) рассматриваться как неявные аргументы. Вообще, вот: http://lisper.ru/articles/cl-vars

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

Какая разница можно или нельзя? Искаробки их нет, вот и весь разговор. «Можно реализовать» - это крайне слабый довод, это значит, что, скорее всего, никем и никогда это релизовано и использовано не будет.

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

>можно написать такой код на CL который нельзя написать на схеме вообще?

Это теоретический или практический вопрос? Если вопрос теоретический, то любой код на CL можно переписать на схеме.

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

dmitry_vk ★★★
()

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

Да, зато в интерпретаторе на коленке динамическая область видимости реализуется просто, а статическую надо аккуратно делать.

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

> Динамическая область видимости это ужасно,

приводит к трудновылавлиаемым ошибкам


Это вы на основе собственного опыта говори (какого?)? Или там, решили абстрактно порассуждать? Практика как-бы ваши выкладки не подтверждает.

Да, зато в интерпретаторе на коленке динамическая область

видимости реализуется просто



Бу-га-га, вы, очевидно, совершенно не в теме.

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

Или на схеме, «фишки» завязанные на динамические переменные, реализовать можно, но с большими усилиями?

Динамическую видимость переменных даже в PHP можно сделать, в Scheme тем более:

(define-syntax binding*
  (syntax-rules ()
    [(_ () exprs ...) (begin exprs ...)]
    [(_ ((x y) bnds ...) exprs ...)
     (let ((tmp x))
       (set! x y)
       (begin0
         (binding* (bnds ...) exprs ...)
         (set! x tmp)))]))

(define *foo* (void))

(define (bar)
  (+ *foo* *foo*))

(binding* ((*foo* 333))
  (display (bar)))

binding без звездочки тоже делается легко, но кода будет побольше.

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

>Динамическую видимость переменных даже в PHP можно сделать, в Scheme тем более

У вас неправильный биндинг. Он как минимум не thread-safe, в отличие от CL'ных динамических переменных.

Да, зато в интерпретаторе на коленке динамическая область видимости реализуется просто, а статическую надо аккуратно делать.

А в компиляторе - строго наоборот.

Динамическая область видимости это ужасно

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

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

А так? (binding* не менял):

(define-syntax-rule (define-thread-local var)
  (begin 
    (define storage (make-hash))
    (define-syntax var
      (syntax-id-rules (set!)
        ((set! var val) (hash-set! storage (current-thread) val))
        (var (hash-ref storage (current-thread) (void)))))))

(define-syntax binding* 
  (syntax-rules () 
    [(_ () exprs ...) (begin exprs ...)] 
    [(_ ((x y) bnds ...) exprs ...) 
     (let ((tmp x)) 
       (set! x y) 
       (begin0 
         (binding* (bnds ...) exprs ...) 
         (set! x tmp)))])) 
 
(define-thread-local *foo*)  

(define (bar) 
  (+ *foo* *foo*)) 
 
(binding* ((*foo* 333)) 
  (display (bar)))

tarc
()

В схеме есть fluid-let, правда, это нестандарт. Есть он, насколько я понимаю, во всех схемах, которые используют макроэкспандеры на базе psyntax (http://ikarus-scheme.org/r6rs-libraries) и не только в них.

Про fluid-let можно прочитать тут: http://www.scheme.com/tspl3/control.html#./control:s43

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