2015-02-23 3 views
1

Возможно ли обновить программный код, пока он интерпретируется csi, интерпретатор куриных схем? Если да, то как?Изменение программного кода во время работы в схеме цыпленка

Чтобы я мог в интерактивном режиме изменить часть кода и сразу увидеть последствия этого изменения. Например, предположим, что я написал следующую программу:

(define (loop) 
    (print "Ciao") 
    (rest 1) 
    (loop)) 

(loop) 

(предположим, что (rest 1) имеет эффект приостановки программы для второй).

Если я запустил эту программу, прогиб csi, он печатает строку «Ciao» каждую секунду. Если я изменил строку «Ciao» на что-то еще, например, на «else», и я сохраню файл программного кода, тогда csi продолжит интерпретацию старого программного кода, поэтому я постоянно вижу строку «Ciao». В этом случае я хотел бы, чтобы при сохранении измененного кода с заменой строки «Ciao» на «else», csi продолжить работу по интерпретации, просмотрев измененный файл вместо старого. Так что я получаю в качестве результата некоторые «Ciao», а затем некоторые «else»: «else» начинает появляться, когда я заменяю «Ciao» на «else» в исходном коде.

ответ

2

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

(define (do-stuff) 
    (print "Ciao")) 

(define (main-loop) 
    (do-stuff) 
    (rest 1) 
    (main-loop)) 

(define (start) (main-loop)) 

Теперь вы можете постепенно развивать do-stuff, периодически оценивать новые версии для интерпретатора и призывая их, чтобы убедиться, что они работают, то в конце концов назвав start как только вы «уверен, что он поступает правильно.

Вы можете получить пробег из this similar question. Спросите нас о Common Lisp.

Как и в сторону, если вы используете Common Lisp и тиной, вы могли теперь сделать более или менее то, что вы предложили:

(defun do-stuff() 
    (format t "Ciao~%")) 

(defun main-loop() 
    (loop (progn (do-stuff) 
       (sleep 1)))) 

(main-loop) 

Запуск, что до начнет печать Ciao на отдельных линиях в вашем SLIME РЕПЛ. Если вы изменили do-stuff в

(defun do-stuff() 
    (format t "else~%")) 

затем ударил его с C-c C-c (связывание по умолчанию для slime-compile-defun), вы бы увидели ваш SLIME РЕПЛ начать печать else линии в полете.

CL-USER> (main-loop) 
Ciao 
Ciao 
Ciao 
; compiling (DEFUN DO-STUFF ...)else 
else 
else 
else 
else 
else 
; Evaluation aborted on NIL. User break. 
CL-USER> 

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

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

  1. Написать файл
  2. Run csi my-file.scm
  3. Редактировать файл
  4. Убить csi
  5. Run csi my-file.scm
  6. goto 3

и вы используете чтобы просто автоматизировать шаги с 4 по 6, вам понадобится внешний инструмент для этого. Взгляните на entr или hsandbox (последний не имеет поддержки схемы из коробки, но это не похоже, что было бы слишком сложно добавить).

1

Там нет единого способа сделать запущенную программу проверить его источник изменений, но вы, кажется, достаточно feratures доступен в Chicken свернуть свой собственный:

(use posix) 
(use srfi-18) 

(define (watch-reload! file) 
    (define (tsleep n) 
    (thread-sleep! (seconds->time (+ n (time->seconds (current-time)))))) 
    (define (get-time) 
    (file-modification-time file)) 
    (thread-start! 
    (lambda() 
    (let loop ((filetime '())) 
     (let ((newtime (get-time))) 
     (when (not (equal? filetime newtime)) 
      (load file)) 
     (tsleep 10) 
     (loop newtime)))))) 

Теперь все, что вам нужно сделать, это используйте watch-reload! вместо load, и он будет проверять и перезагружать каждые 10 секунд, если файл был изменен. Если вы сохраняете, когда файл недействителен, он перестает работать, пока вы не назовете его еще watch-reload!.

Возможно, у куриных программистов может быть лучшее решение.