如何在安卓系统上运行Frege程序?

27

我对使用函数式语言编写Android应用程序非常感兴趣,尤其是接近Haskell的语言。 Frege似乎是一个不错的选择。我发现有人已经做出了这样一个概念验证应用程序,但我找不到它的源代码或类似的内容。

所以我的问题是,如何在Android上运行Frege程序,它有多难并且可能会遇到哪些问题?


1
我的猜测是,它会让人想起使用Scala编写Android应用程序所需的工作,因为两者都编译为JVM字节码。 - CommonsWare
2
在这里搜索或提问:https://groups.google.com/forum/#!forum/frege-programming-language - Landei
1
请注意,您需要构建自己的JDK6友好的Frege编译器,以下是一些提示 https://github.com/Frege/frege/wiki/Frequently-Asked-Questions - Ingo
1
Marimuthu在此提供了一个可下载的Java6 Frege jar文件,链接为:https://dl.dropboxusercontent.com/u/55737110/fregec-java6-3.21.140-gc9dfb09.jar(截至2013年6月)。 - Ingo
5个回答

6
我看到的主要障碍是目前无法将Frege源代码编译为实现某些接口或扩展另一个类的Java类。相反,从Frege模块生成的Java类只是您定义的静态方法和其他内容的命名空间。因此,要创建一个不止微不足道的Android项目,仅从Frege调用Java将不足以解决问题,这相当容易,还需要从Java调用Frege。换句话说,您需要字面上的完全互操作性。当然,这是可能的,但必须说代码生成并不是为了方便从Java使用而设计的。我还没有做过Android项目,因此我不确定需要多少胶水代码。最后警告一下:Gabriel Riba之前的工作是使用较早版本的编译器完成的。甚至有一个链接到支持JDK6的Frege分发版 - 请不要使用该版本,它与更近期的版本不兼容。如果您仍然愿意尝试,请通过上述提到的Google组获得每种可能的支持。如果有人制作并记录了一些“规范”的方法来实现这一点,那将太好了。

这个答案现在已经过时了,请查看 https://ingo60.gitbooks.io/frege-quick-reference/content/modules.html#_integration_with_other_jvm_languages - Janus Troelsen

3
如果您想完全使用Frege编写应用程序,那么会更加棘手。您需要为Android API编写包装器,因为FregeAndroid包装器似乎缺少一些文件
但是,如果您想在Java中编写UI,并调用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,因此您可以使用从Java调用Frege的旧方法。我没有尝试过使用Frege 3.24,但如果您想尝试,您需要使用新的方法

唯一真正棘手的部分是得到一个可以构建Frege代码的build.gradle。我从Frege邮件列表中Andreas Ländle发布的片段开始,然后将其完善为完整的build.gradle。我无法使Proguard工作,因此生成的APK包含整个frege.jar。这会使应用程序有点臃肿,并且需要打开Multidex,但除此之外似乎没有问题。

另外,请注意我的示例项目需要 API Level 21 或更高版本,因为 Frege 需要 ForkJoinPool,而 Android 只在 21 及以上版本中才有。


3

我对Frege不熟悉,也没有尝试在Android上使用Scala或其他JVM语言。

那么说了这些,如果我要尝试类似的东西,以下是我可能采取的步骤来尝试弄清楚如何使其正常工作:

  1. 在Frege中构建一个简单的基于命令行的HelloWorld类型应用程序,该应用程序可以通过例如`java -jar HelloWorld.jar HelloWorld`来运行

  2. 对HelloWorld.jar运行dx,然后尝试从adb shell使用dalvikvm在Android设备上运行该示例,即`dalvikvm -cp blah.dex HelloWorld`

  3. 找出如何在Frege中引用/使用Android sdk提供的android.jar中的类

  4. 在Frege中构建一个简单的POC Activity类,并手动从中构建一个classes.dex文件

  5. 在Java中构建类似的POC应用程序,并使用现有的Android工具构建一个apk

  6. 替换apk中的classes.dex,重新签名apk,然后查看是否可行

  7. 如果您已经成功完成这些操作,则可以继续开发更好的Frege构建方案,使用aapt编译资源并最终从头开始构建完整的apk。


如果你想在Android上尝试Scala,请使用Scala-IDE;它有针对在Android上使用Scala的特定文档。 - Boyd Stephen Smith Jr.

2

如果有人仍然感兴趣,我在这里写了一篇关于它的博客文章(链接)。您需要设置gradle构建以将Frege代码编译为Java并将其放入Java源路径中。然后,您需要子类化activity并定义一些自定义包装器。

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();
    }
}

链接已经失效了,你能否请检查一下? - Petr
我会重新上传。这里有一个更近期和有用的贡献:https://github.com/mchav/froid - Michael Chav

2
根据快速网络搜索和一些来自frege编程语言邮件列表的结果,我了解到似乎不可能创建一个仅使用Frege的Android应用程序。
相反,您需要使用其他支持Android的编程语言,并将其用于调用您的Frege代码。生成这样的“存根”可能可以自动完成,但我没有看到现有的工具可以实现。
此外,还存在与Frege生成的Java代码以及Android的Java编译器相关的问题,但使用retrotranslation工具似乎相对容易解决。

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

我也希望有一种具备参数多态和特定多态的参照透明、强类型语言可用于进行Android开发。虽然目前还没有这样的语言,但我推荐使用Scala进行Android开发。

仅供参考,Scala今天已经具备了参数多态和特定多态,就像Haskell/Frege一样,尽管语法略微不太好看。 - Erik Kaplun
Scala不是引用透明的,+Erik Allik。除此之外,它符合我的标准,即使有“奇怪”的特别多态性。(老实说,Haskell的类型类系统很好,但也有点奇怪。) - Boyd Stephen Smith Jr.
没有强制引用透明度的意思。是的,我希望大部分使用Scala类型类语义,但使用Haskell的语法,这也是我认为Haskell正在发展的方向。 - Erik Kaplun
不需要使用“enforced”限定符。如果语言中存在不是引用透明的表达式,则该语言就没有引用透明性。(例如Scala)。 - Boyd Stephen Smith Jr.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接