Использование Lisp или Scheme для настройки времени выполнения программ Java - PullRequest
11 голосов
/ 28 мая 2011

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

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

Мне было интересно, может ли крошечный модуль чтения конфигурации Lisp быть лучшим вариантом, когда файл для чтения - это не файл свойств, а программа на Лиспе, которая затем оценивается для создания окончательной структуры данных, представляющей конфигурацию. Минимальный набор функций в библиотеке времени выполнения позволил бы манипулировать строками и, возможно, даже вызывать JVM. Просто подумайте о «создании URL на основе текущего имени хоста».

Я не заинтересован в полном движке Lisp с наворотами, а просто в маленькой библиотеке для этой цели, которая может быть вложена даже в небольшие программы без большой банки, содержащей движок Lisp.

Так существует ли такая библиотека?

  • Малый размер
  • Просто нужно прочитать файл + eval и возможность прочитать полученную структуру данных из основной программы Java
  • Небольшая библиотека времени выполнения Lisp
  • Скорость имеет меньшее значение.
  • Активно поддерживается.

Предложения


Редактировать 2012-01-20: Первоначально я счел всех кандидатов нежелательными, но решил использовать это как упражнение Maven на стороне с выпуском jscheme 1.4 1998 года . Проект на https://github.com/ravn/jscheme-1998


Edit 2012-12-11: Оказалось, что уровень интеграции 1035 * между программой, интерпретируемой в Scheme, и программой Java на хосте был более важным, чем я изначально думал, и что мне нужно в проекте чтобы иметь возможность предоставлять классы с аннотациями JAX-WS во время выполнения, что я не мог сделать с JScheme, но я мог сделать с Groovy. Идея небольшой библиотеки конфигурации, которая позволяет фрагменты кода в библиотеках, все еще остается в силе, но в итоге мне понадобилось больше, чтобы она была полезной.

Ответы [ 4 ]

8 голосов
/ 28 мая 2011

Хорошим, гораздо меньшим решением является встроенная схема для Java.Из многих реализаций я нашел и протестировал JScheme .(API выглядит нормально: http://jscheme.sourceforge.net/jscheme/doc/api/index.html)

Простая основная программа на Java:

import jscheme.JScheme;
import jscheme.SchemeException;
import java.io.*;
public class SchemeTest {
    public static void main(String[] args) {
        JScheme js = null;
        try {
            js = new JScheme();
            js.load(new FileReader("config.scm"));
        } catch (FileNotFoundException e) { return; }

        System.out.println("Message: '" + js.eval("msg") + "'");

        // Values
        int answer = (Integer) js.eval("answer");

        // Function calls
        System.out.println(js.call("countdown", 42));
    }
}

И пример config.scm:

(define (countdown x)
  (define (loop x acc)
    (if (= x 0)
      acc
      (loop (- x 1) (+ acc x))))
  (loop x 0))

;;; config variables
(define msg "Hello from JScheme!")
;; tail calls are optimized as required
(define answer (countdown 42))

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

  • хорошая интеграция с JVM
  • очевидно полная реализация схемы
  • маленький размер(572 кБ)
  • быстро, несколько легко вызывается из Java

Обновление эталонного теста : этот код выполняется за 0,13 секунды времени.во времена Clojure это довольно быстро.

8 голосов
/ 28 мая 2011

Я знаю, что вы хотите небольшой размер и время выполнения.Схема является обычным выбором для легкого встраивания и будет моим первым выбором.Но у меня нет информации по этому вопросу.Мой второй выбор - Clojure :

  • Не так уж и мало;jar составляет ~ 3 МБ
  • Избыток для простого чтения конфигурации, но дополнительные функции можно безопасно игнорировать
  • ~ Легко вызывать из Java: Вызов clojure из java
  • Полный, отличный доступ к JVM
  • Может вызвать небольшую дополнительную нагрузку при запуске, которая может быть слишком большой (см. Ниже)
  • Теперь, когда я попытался воспроизвести функциональность примерас Clojure я чувствую, что Clojure не очень подходит для таких сценариев (rc и т. д.).Clojure 1.3 устранит некоторые из этих штрафов при запуске, но я не знаю, сколько будет улучшений скорости

Соответствующий код с использованием Clojure :

import clojure.lang.RT;
import clojure.lang.Var;
import clojure.lang.Compiler;
import java.io.FileReader;
import java.io.FileNotFoundException;

public class ClojTest {
    public static void main(String[] args) throws Exception {
        try {
            Compiler.load(new FileReader("hello.clj"));
        } catch(FileNotFoundException e) { return; }

        System.out.println("Message: '"+ RT.var("user", "msg").get() +"'");

        // Values
        int answer = (Integer) RT.var("user", "answer").get();

        // Function calls
        System.out.println(RT.var("user", "countdown").invoke(42));
    }
}

с hello.clj, являющимся:

(ns user)
(defn countdown [n]
  (reduce + (range 1 (inc n))))

(def msg "Hello from Clojure!")
(def answer (countdown 42))

Выполнение time java ClojTest на некоторое время дает в среднем 0,75 секунды. Скомпилирование сценария с помощью Clojure имеет довольно много штрафов!

6 голосов
/ 28 мая 2011

Попробуйте SISC , это довольно маленькая (300 КБ) реализация схемы без наворотов. Склеить его с помощью Java тривиально, а скорость выполнения для впечатляющего интерпретатора впечатляет.

3 голосов
/ 28 мая 2011

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

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

Возможно, по этой ссылке можно будет использовать более раннюю (1998 г.) версию JScheme, которая содержит всего около 30 тыс. Jar-файлов: http://norvig.com/jscheme.html

В противном случае, возможно, можно что-то написатьеще более минимальный в нескольких сотнях строк Java ... вероятно, это всего лишь проект выходного дня, учитывая, насколько маленьким является ядро ​​Scheme.Следующая страница очень интересна, если вы хотите написать мини-интерпретатор для Scheme: http://archives.evergreen.edu/webpages/curricular/2000-2001/fofc00/eval.html

...