Подтвердить что ты не робот

Как запустить программы Frege на Android?

Я заинтересован в программировании для Android на функциональных языках, желательно рядом с Haskell. Frege кажется хорошим выбором. Я обнаружил, что кто-то уже сделал такое приложение с доказательством концепции, но я не смог найти его источники или что-то подобное.

Итак, мой вопрос заключается в том, как запускать программы Frege на Android, насколько это сложно и какие возможные препятствия?

4b9b3361

Ответ 1

Основным препятствием, которое я вижу, является то, что в настоящее время невозможно скомпилировать источник frege для класса java, который реализует некоторый интерфейс или расширяет другой класс.

Вместо этого класс java, сгенерированный из модуля frege, представляет собой просто пространство имен для статических методов и других вещей, которые вы определили.

Следовательно, чтобы сделать более чем тривиальный Android-проект, этого будет недостаточно, чтобы вызывать java из frege, что довольно просто, но также вызывать frege из java. Другими словами, вам понадобится полная * inter * работоспособность в буквальном смысле.

Конечно, это можно сделать, но нужно сказать, что генерация кода не была точно разработана для удобства использования из java.

Я еще не делал проект Android, поэтому я не уверен, сколько кода будет нужно.

Одно последнее предупреждение: предыдущая работа Габриэля Рибы была выполнена с более ранней версией компилятора. Там даже ссылка на дистрибутив frege, поддерживающий JDK6, - не используйте эту, не совместимую с более поздними версиями.

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

Ответ 2

Я не знаком с frege, и я не пытался использовать scala или другие языки JVM на Android.

Говоря, если бы я попытался что-то вроде этого, то это шаги, которые я, вероятно, предприму, чтобы попытаться выяснить, как заставить его работать.

  • Создайте простое приложение типа HelloWorld на основе командной строки в frege, которое можно запустить с помощью, например, java -jar HelloWorld.jar HelloWorld

  • Запустите dx на HelloWorld.jar, а затем попробуйте привести пример, работающий на устройстве Android из оболочки adb, используя dalvikvm. т.е. dalvikvm -cp blah.dex HelloWorld

  • Узнайте, как ссылаться/использовать классы из android.jar, предоставляемые Android sdk в frege

  • Создайте простое доказательство концепции класса Activity в frege и вручную создайте из него файл classes.dex

  • Создайте аналогичное доказательство применения концепции в java и используйте существующие инструменты Android для сборки apk

  • Замените classes.dex в apk, отмените apk и посмотрите, работает ли он

  • Если вы так много работаете, то оттуда вы можете работать над лучшей историей построения для frege, используя aapt для компиляции ресурсов и, в конечном итоге, создавая полный apk "с нуля".

Ответ 3

Из всего, что я могу почерпнуть из быстрого веб-поиска, включая некоторые хиты из списка рассылки frege-programming-language, он не похож на Android-приложение с функцией Frege.

Вместо этого вам нужно будет взять другой язык с поддержкой Android и использовать его для вызова кода Frege. Создание таких "заглушек" возможно было бы сделано автоматически, но я не видел существующего инструмента для этого.

Также существуют проблемы с кодом Java, созданным Frege и компиляторами Java для Android, но это похоже на то, что относительно легко работать с использованием средств ретротрансляции.

https://groups.google.com/forum/#!topic/frege-programming-language/Ounzmu-oHJQ https://groups.google.com/forum/#!topic/frege-programming-language/8bkWorojiiY

Я также хочу, чтобы для разработки Android существовал ссылочно-прозрачный, строго типизированный язык с параметрическим полиморфизмом и ad-hoc-полиморфизмом. Хотя этого не хватает, я рекомендую Scala для разработки Android.

Ответ 4

Если вы хотите полностью написать свое приложение в Frege, это будет сложнее. Вам нужно будет написать обертки для Android API, потому что обертка FregeAndroid выглядит отсутствующие файлы.

Однако, если вы хотите написать свой UI на Java и позвонить в Frege для своей логики приложения, у меня есть образец проекта, который показывает как это сделать.

Мой пример проекта имеет эту функцию в Frege:

extraText :: String -> String
extraText who = "\nHello, " ++ who ++ "!"

который затем я вызываю из Java:

public class FregeActivity extends Activity
{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        TextView textView = (TextView) findViewById(R.id.txt);
        textView.append(FregeCode.extraText("Android"));
    }
}

который выглядит следующим образом

FregeActivity

В моем примере проект использует Frege 3.23, поэтому для этого вы можете использовать старый способ вызова Frege из Java. Я не пробовал использовать Frege 3.24, но если вы хотите попробовать это, вы можете использовать новый способ.

Единственная действительно сложная часть - получить build.gradle, который будет строить код Frege. Я начал с фрагмента, опубликованного Andreas Ländle в списке рассылки Frege, а затем я отобразил его в полный build.gradle. Мне не удалось заставить Proguard работать, поэтому полученный APK содержит весь frege.jar. Это немного раздувает приложение, и требуется включить Multidex, но в остальном это выглядит нормально.

Также обратите внимание, что для моего образца проекта требуется API-уровень 21 или выше, поскольку Frege нуждается в ForkJoinPool, который Android имеет только на уровне 21 и выше.

Ответ 5

Для тех, кто все еще интересуется, у меня есть сообщение в блоге об этом здесь. Вы должны настроить свою конструкцию gradle для компиляции кода Frege в java и поместить его в исходный путь java. Затем вам нужно выполнить подкласс и выполнить некоторые пользовательские обертки

data Bundle = native android.os.Bundle

data Context = native android.content.Context

data FregeActivity = native android.app.Activity where
    native getApplicationContext :: MutableIO FregeActivity -> IO (MutableIO Context)
    native setContentView :: MutableIO FregeActivity -> MutableIO TextView -> IO ()

data TextView = native android.widget.TextView where
    native new :: MutableIO Context -> STMutable RealWorld TextView
    native setText :: MutableIO TextView -> String -> IO ()

onCreateF :: MutableIO FregeActivity -> IO ()
onCreateF !this = do
    context <- this.getApplicationContext
    tv <- TextView.new context
    tv.setText "Hello, Android - Love, Frege"
    this.setContentView tv

native module type FregeActivity where {
    @Override
    public void onCreate(android.os.Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        final frege.run7.Func.U<Object,Short> res = RunTM.<frege.run7.Func.U<Object,Short>>cast(onCreateF(this)).call();
        frege.prelude.PreludeBase.TST.run(res).call();
    }
}