27

我对用函数式语言为 Android 编程很感兴趣,最好是接近 Haskell。弗雷格似乎是一个不错的选择。我发现有人已经做过这样的概念验证应用程序,但我找不到它的来源或类似的东西。

所以我的问题是,如何在 Android 上运行 Frege 程序,它有多难,最终的障碍是什么?

4

5 回答 5

6

我看到的主要障碍是,目前无法将 frege 源代码编译为实现某个接口或扩展另一个类的 java 类。

相反,从 frege 模块生成的 java 类只是静态方法和您定义的其他内容的命名空间。

因此,要制作一个非常简单的Android项目,仅仅从frege调用java是不够的,这很容易,而且还从java调用frege。换句话说,从字面上看,您需要完全的*互*操作性。

当然可以,但必须说代码生成并不是为了方便从 java 中使用而设计的。

我还没有完成一个 Android 项目,因此我不确定需要多少胶水代码。

最后一个警告:Gabriel Riba 之前的工作是使用早期版本的编译器完成的。甚至还有一个指向支持 JDK6 的 frege 发行版的链接——请不要使用那个,它与更新的版本不兼容。

如果您仍然愿意接受它,您将通过上述 google 小组获得一切可能的支持。如果有人制作并记录了一些“规范”的方式来实现这一点,那就太好了。

于 2013-06-22T13:59:54.130 回答
3

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

话虽如此,如果我要尝试这样的事情,我可能会采取这些步骤来尝试弄清楚如何让它发挥作用。

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

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

  3. 弄清楚如何从 frege 中的 Android sdk 提供的 android.jar 中引用/使用类

  4. 在 frege 中构建一个简单的概念证明 Activity 类,并从中手动构建一个 classes.dex 文件

  5. 在java中构建一个类似的概念证明应用程序并使用现有的android工具来构建一个apk

  6. 替换apk中的classes.dex,退出apk,看看是否有效

  7. 如果你做了这么多工作,那么从那里,你可以为 frege 编写一个更好的构建故事,使用 aapt 编译资源并最终“从头开始”构建一个完整的 apk。

于 2013-06-20T20:36:27.597 回答
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,但如果你想尝试,你会使用新的方式

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

另外,请注意,我的示例项目需要API 级别 21或更高级别,因为 Frege 需要ForkJoinPool,而 Android 仅在级别 21 及更高级别中具有此功能。

于 2016-10-09T16:34:12.653 回答
2

从我可以从快速网络搜索中收集到的所有内容,包括来自 frege-programming-language 邮件列表的一些点击,它看起来不像是仅 Frege 的 Android 应用程序是可能的。

相反,您必须采用其他支持 Android 的语言并使用它来调用您的 Frege 代码。生成这样的“存根”可能会自动完成,但我没有看到这样做的现有工具。

Frege 生成的 Java 代码和 Android 的 Java 编译器也存在一些问题,但这似乎是使用逆向翻译工具相对容易解决的问题。

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

我还希望有一种引用透明、强类型的语言,它同时具有参数多态性和临时多态性,可用于进行 Android 开发。虽然缺少这一点,但我推荐使用 Scala 进行 Android 开发。

于 2013-06-27T14:57:55.943 回答
2

对于仍然感兴趣的人,我在这里有一篇关于它的博客文章。您必须设置您的 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();
    }
}
于 2016-11-27T18:15:04.187 回答