How to run Frege programs on Android?
Asked Answered
H

5

27

I'm interested in programming for Android in functional languages, preferably close to Haskell. Frege seems to be a good choice. I found that somebody has already done such a proof-of-concept application, but I couldn't find its sources or anything similar.

So my question is, how to run Frege programs on Android, how difficult it is and what are eventual obstacles?

Hannon answered 20/6, 2013 at 19:39 Comment(4)
My guess is that it would be reminiscent of the work needed to write Android apps in Scala, insofar as both compile to JVM bytecodes.Jansson
Search or ask here: groups.google.com/forum/#!forum/frege-programming-languageMismanage
Please observe that you'll need to build your own JDK6 friendly frege compiler, here are some hints github.com/Frege/frege/wiki/Frequently-Asked-QuestionsBroadbill
Marimuthu has made available a downloadable frege jar for Java6 here: dl.dropboxusercontent.com/u/55737110/… (as of June 2013)Broadbill
B
6

The main obstacle I see is that it is currently not possible to compile a frege source to a java class that implements some interface or extends another class.

Instead, the java class generated from a frege module is just a namespace for static methods and other stuff you defined.

Hence, to make a more than trivial Android project, it'll not be enough to call java from frege, which is quite easy, but also to call frege from java. In other words, you'll need full *inter*operability in the literal sense.

Of course, it is possible to do, but it must be said that the code generation was not exactly designed for easy use from java.

I have not done an Android project yet, hence I am not sure just how much glue code one would need.

One final warning: the previous work by Gabriel Riba was done with an earlier version of the compiler. There's even a link to a frege distribution that supports JDK6 - please don't use that one, it's not compatible with more recent versions.

If you're nevertheless willing to take it on, you'll get every possible support through the google group mentioned above. It'd be too great if someone made and documented some "canonical" way to achieve this.

Broadbill answered 22/6, 2013 at 13:59 Comment(1)
This answer is outdated now, see ingo60.gitbooks.io/frege-quick-reference/content/…Baculiform
B
3

I'm not familiar with frege, and I haven't tried to use scala or other JVM languages on Android.

That being said, if I were to try something like that, these are the steps I would likely take to try and figure out how to get it to work.

  1. Build a simple command line based HelloWorld type application in frege, that can be run with, e.g. java -jar HelloWorld.jar HelloWorld

  2. Run dx on HelloWorld.jar, and then try to get the example working on an android device from adb shell, using dalvikvm. i.e. dalvikvm -cp blah.dex HelloWorld

  3. Figure out how to reference/use classes from the android.jar provided by the Android sdk in frege

  4. Build a simple proof of concept Activity class in frege, and manually build a classes.dex file from it

  5. Build a similar proof of concept application in java and use the existing android tools to build an apk

  6. Replace classes.dex in the apk, resign the apk, and see if it works

  7. If you get that much working, then from there, you can work on a better build story for frege, using aapt to compile resources and eventually build a full apk "from scratch".

Barbiturism answered 20/6, 2013 at 20:36 Comment(1)
If you do want to try Scala on Android, use Scala-IDE; it has specific documentation for doing Scala on Android.Puton
G
3

If you want to write your app entirely in Frege, that will be trickier. You'll need to write wrappers for the Android API, because the FregeAndroid wrapper seems to be missing some files.

However, if you want to write your UI in Java, and call into Frege for your application logic, I have a sample project which shows how to do that.

My example project has this function in Frege:

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

which I then call from 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"));
    }
}

which looks like this

FregeActivity

My example project uses Frege 3.23, so for that you would use the old way of calling Frege from Java. I haven't tried using Frege 3.24, but if you want to try that, you'd use the new way.

The only really tricky part was getting a build.gradle that would build the Frege code. I started with a snippet posted by Andreas Ländle on the Frege mailing list, and then I fleshed it out into a complete build.gradle. I wasn't able to get Proguard to work, so the resulting APK contains the entire frege.jar. That bloats the app a bit, and it required turning on Multidex, but otherwise it seems to be fine.

Also, note that my sample project requires API Level 21 or higher, because Frege needs ForkJoinPool, which Android only has in level 21 and up.

Gordy answered 9/10, 2016 at 16:34 Comment(0)
P
2

From everything I can glean from a quick web search including some hits from the frege--programming-language mailing list, it doesn't look like a Frege-only Android application is possible.

Instead, you'll have to take some other Android-enabled language and use it to call into your Frege code. Generating such "stubs" could possibly be done automatically, but I did not see an existing tool for doing so.

There's also issues around the Java code generated by Frege and the Java compilers for Android, but that seems to be something that is relatively easy to work-around using retrotranslation tools.

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

I also wish there was referentially-transparent, strongly-typed language with both parametric polymorphism and ad-hoc polymorphism available for doing Android development. While that is missing, I recommend Scala for doing Android development.

Puton answered 27/6, 2013 at 14:57 Comment(4)
Just for the record, Scala has both parametric polymorphism as well as ad-hoc polymorphism available today, just as Haskell/Frege, albeit with a somewhat less nice syntax.Garderobe
Scala is not referentially-transparent, +Erik Allik. Other than that, it meets my criteria, even with the "wonky" ad-hoc polymorphism. (Honestly, Haskell's type class system is good, but it's also a bit wonky.)Puton
No enforced referential transparency you mean. And yes, I wish I had mostly Scala type class semantics with mostly Haskell's syntax, which is where I think Haskell's headed.Garderobe
No need to use the "enforced" qualifier. If the are expressions in the language that are not referentially transparent, the language doesn't have referential transparency. (Scala, for example.)Puton
M
2

For anyone that's still interested I have a blog post about it here. You have to setup your gradle build to compile the Frege code into java and put it into your java source path. Then you have to subclass activity and efine some custom wrappers

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();
    }
}
Megganmeggi answered 27/11, 2016 at 18:15 Comment(2)
The link is now dead, can you please check?Hannon
I'll put it back up. Here is a more recent and useful contribution: github.com/mchav/froidMegganmeggi

© 2022 - 2024 — McMap. All rights reserved.