goose

Вопрос новичка: «выполнимые» и «невыполнимые» списки

Странный, возможно, вопрос: где определяется, выполняется ли список на месте, или нет? К примеру, можно ли рассмотреть конструкцию

(define (blah x) (...))

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

(define '(blah x) '(...))

не верно? Нам ведь нужно взять тело функции как есть, в виде списка, и связать его с именем "blah". В чём я заблуждаюсь?
Пожар в голове
  • xsbos

Вызов лямбда-функции из списка

Приветствую! Изучаю Scheme (среда DrScheme, язык mzscheme) и никак не могу разобраться, как вызвать лямбда-функцию из списка (например, первую)

Т.е. пусть есть список
(define lst
  '(
    (lambda (x) (+ x 1))
    (lambda (x) (+ x 4))
    )
  )

((car lst) 3) ; ошибка!

Подскажите, пожалуйста, как это делается
Vash
  • udpn

MIT-GNU Scheme newbie problem

Доброе. Установил интерпретатор от MIT. Дабл-ЛКМ по иконке. Открывается Edwin. Что нужно в нем нажать, чтобы наконец начать интерпретацию? Можно ли этим редактором открыть файл, созданный в другой программе, как это сделать и какая у файла должна быть кодировка? Видел кто-нибудь нормальный юзер мануал на английском или русском? Стоит ли перейти на другой, более вменяемый интерпретатор Scheme?
бездна
  • yoschi

COM-объекты в PLT-Scheme

Приветствую!

Два вопроса к тем, кто пользует MysterX в PLT-Scheme.

1) Есть ли способ остановить процесс, запущенный при создании com-объекта приложения? Нечто навроде vlax-release-object из автокадного VL. А то ведь он остается висеть в памяти даже после полного выключения программы.

2) Программы, в которых используется COM-технология довольно часто падают - хоть из DrScheme запускай, хоть откомпилированую. Причем, никаких общих признаков нет - то нормально работает, то вырубается безо всякой видимой причины со стандартным виндовским сообщением вида "PLT Scheme GUI application - обнаружена ошибка. Приложение будет закрыто". С чем это может быть связано?

PLTScheme - (current-milliseconds)

Простой вопрос, наверное.

есть такая процедура в MIT Scheme , называется (runtime).

Типичное использование (display (- (runtime) start-time))

Я у себя держу PLT Scheme, там этой штуки нет. Зато есть (current-milliseconds)

Фишка в том, что (display (- (current-milliseconds) start-time)) внутри моего кода всегда выдает 0. Иногда почему-то 16.

В чем грабли, об которые я уже полдня натыкаюсь?

под катом код (упражнение 1.20 из SICP)
Collapse )
Снусмумрык

Изменение пространства имен символа

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

Вот пример кода:

(define (some-function a-symbol)
  (define z 11)
  (eval a-symbol))

(some-function 'z)


Естественно, в данном случае интерпретатор отрапортует об ошибке, поскольку с символом z, передаваемым в some-function не связанно значение. Вопрос в следующем: как мне сделать именно так как хочется :), тоесть, чтобы внутри функции передаваемый символ связать с новым пространством имен.

В plt-scheme достаточно много различных функций по работе с пространствами имен. Можно их создавать, выбирать и т.д. Самым, кажется, связанным с данной темой является следующий пример:

  (let ((ns (make-base-namespace)))
    (parameterize ((current-namespace ns))
      (define z 11)
      (eval '(define z 14) ns)
      (display z)
      (newline)
      (display (eval 'z)))))

но тут я наталкиваюсь на другую проблему: получается что (define z 11) и (eval '(define z 14)) действуют в различных областях имен. Т.е., как я понимаю (parameterize ((current-namespace ns)) ...) действует только для оператора (eval ...) ?
Но мне хотелось бы именно совместить определенный символ в текущем контексте (при помощи (define ...)) с передаваемым в качестве аргумента функции символом. Подскажите пожалуйста как можно (и можно ли) подобного достичь?

Спасибо заранее.

Обратные функции

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

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

В данном примере мы вычисляем логическое значение, является ли Y суммой X и 5.
А теперь вопрос на засыпку, а кто сказал, что данные должны обязательно передаваться от вершин к корню? Почему бы нам не поменять направление в некоторых ветвях, например так.

Присвоить Y значение, равное сумме X и 5. Или еще лучше вот так.

Присвоить X такое значение, чтобы его сумма с 5 равнялась Y.
Во всех языках программирования операция присвоения нового значения переменной и операция логического сравнения - это две совершенно разные операции. Обычно обозначаются либо разными символами (в C++ это = и ==), либо разными функциями. Хотя по сути это одно и то же! Мы просто в одном случае спрашиваем, а равны ли X и Y, а в другом случае утверждаем что X равен Y. Т.е. логически это одна и та же операция, только направление движения данных отличается.
Конечно, далеко не все функции обратимы как операция сложения, но все-таки это было бы очень удобно. Например операция andmap и map в каком-то смысле одинаковые, только опять же данные движутся в другом направлении. В одном случае мы спрашиваем, а будет ли истиной какое-то выражение для всех значений списка, а в другом случае мы утверждаем, что некоторое выражение является истиной для всех значений списка.
А если взять и абстрагироваться от конкретных направлений, а просто взять и объявить некоторую формулу, например "X+5=Y". Вот имеется такая взаимосвязь переменных. А потом эту формулу использовать по своему усмотрению, в одном случае мы присваиваем Y значение суммы, в другом случае мы присваиваем X нужное значение, а в третьем мы просто хотим проверить истинно ли данное выражение.
Короче, я от слов к делу. Я немного поэкспериментировал на эту тему и вот что получилось.

#lang scheme
(define (sv! f v) (keyword-apply f '(#:value) (list v) '()))
(define (gv? f) (apply f '()))
(define-syntax-rule (g? x) (lambda () x))
(define-syntax-rule (s! x) (lambda (#:value value) (set! x value)))
(define-syntax-rule (defun fun x y value getter setter)
(define (fun x y)
(lambda (#:value (value 'novalue))
(if (eq? value 'novalue)
getter
setter))))
(defun summ x y value
(+ (gv? x) (gv? y))
(sv! x (- value (gv? y))))
(defun eqv x y value
(= (gv? x) (gv? y))
(if (eq? value #t)
(sv! x (gv? y))
#f))

(define x 56)
(define (formula x y z) (eqv (summ x y) z)) ;запоминаем формулу x+y=z
(sv! (eqv (summ (s! x) (g? 5)) (g? 9)) #t) ;вычислить x такое, чтобы x+5=9
x ;возвращает 4
(sv! (formula (s! x) (g? 3) (g? 10)) #t) ;вычислить то же самое с использованием формулы
x ;возвращает 7
(gv? (formula (g? x) (g? 5) (g? 12))) ;вычислить логичекое выражение x+5=12
;возвращает ИСТИНУ
Кстати, у нас получилась определенная ленивость. Например выражение
(sv! (eqv (summ (s! x) (g? 5)) (g? 9)) #f)
не будет изменять значение x, т.к. мы передаем #f.
По-моему идея, запихнуть результат обратно функции в ж..., довольно интересна и стоит размышлений :)

(no subject)

как насчёт того, чтобы писать Flash анимацию прямо внутри PLT Scheme?
если ли кто заинтересованный в этом деле?

(no subject)

работаю в PLT Scheme  с sandbox-ами
надо сделать, чтобы можно было многократно прерывать работу sandbox-а, передавая наружу некое сообщение, которое бы обрабатывалось и закидывало некое сообщение обратно вовнутрь sandbox-а.
я пробовал с помощью обработки ошибок (вызывал raise) и "продолжений", но делать это многократно (больше одного раза) не получается - продолжения перестают работать
как такое сделать?
1100-870

define_syntax

Недавно начал изучать SICP, не бейте слишком строго.

Хотелось бы понять почему в SICP авторам как-то удачно удается обходится без define-syntax и явно определенных force и delay? В R5RS это не работает, собственно, натолкнулся на это, когда пытался сделать бесконечные потоки (streams) по методе, описанной в SICP.

(define (cons-stream a b) (cons a (delay b)))
(define (integers-from n) (cons-stream n (integers-from (+ n 1)))
(define natural-numbers (integers-from 1))

в R5RS немедленно заходит в бесконечный цикл. На самом деле надо писать
(define-syntax cons-stream (syntax () (cons-stream a b) (cons a (delay b)))).

Это что-то, похоже, связаное с порядком вычисления. В идеале бы хотелось еще понять, зачем было это изменение ;).