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?

Petr
  • 62,528
  • 13
  • 153
  • 317
  • 1
    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. – CommonsWare Jun 20 '13 at 19:40
  • 2
    Search or ask here: https://groups.google.com/forum/#!forum/frege-programming-language – Landei Jun 21 '13 at 11:19
  • 1
    Please observe that you'll need to build your own JDK6 friendly frege compiler, here are some hints https://github.com/Frege/frege/wiki/Frequently-Asked-Questions – Ingo Jun 22 '13 at 13:26
  • 1
    Marimuthu has made available a downloadable frege jar for Java6 here: https://dl.dropboxusercontent.com/u/55737110/fregec-java6-3.21.140-gc9dfb09.jar (as of June 2013) – Ingo Jun 29 '13 at 12:31

5 Answers5

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.

Ingo
  • 36,037
  • 5
  • 53
  • 100
  • This answer is outdated now, see https://ingo60.gitbooks.io/frege-quick-reference/content/modules.html#_integration_with_other_jvm_languages – Janus Troelsen Apr 17 '16 at 13:59
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".

JesusFreke
  • 19,784
  • 5
  • 65
  • 68
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.

user31708
  • 630
  • 5
  • 11
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.

  • 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. – Erik Kaplun Jan 22 '16 at 13:08
  • 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.) – Boyd Stephen Smith Jr. Jan 27 '16 at 03:09
  • 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. – Erik Kaplun Jan 27 '16 at 08:25
  • 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.) – Boyd Stephen Smith Jr. Jan 29 '16 at 16:18
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();
    }
}
Michael Chav
  • 441
  • 5
  • 15