-
Notifications
You must be signed in to change notification settings - Fork 145
Frequently Asked Questions
If it cannot be done with Java, then it cannot be done with Frege either. Otherwise, the answer is "most likely". Remember, writing Frege code is just a more convenient way to write Java code.
JDK7 is the official development platform, it is choosen because it has the fork/join packages which are used for parallelization and because the compiler of JDK-6 has severe bugs.
If you absolutely need Java6, read on.
It is possible to make oneself a JAR that runs under JRE-6 and creates Java6 compatible class files. However, due to the bugs mentioned above, most programs will still only compile if you have a Java7 compiler! The compiled classes, can be run with JRE6 when the JAR is in the classpath.
Here are the steps to follow, based on the "Re-Compiling the Compiler" section of the Getting Started page. You must still have JDK-7 to do this.
-
Using JDK7 under UNIX, compile the compiler with:
make runtime fregec.jar
-
Make the compiler for JDK-6:
make fregec6.jar
The compiler built that way can be run with JDK-6 or JDK-7 with the following command:
java -Dfrege.javac="javac" -jar fregec6.jar -target 1.6
However, to avoid compilation errors, javac
must still be a Java7 compiler!
Whatever you compile this way will be good for JRE-6, and can be run with:
java -cp fregec6.jar:... some.module.Main
From the fregec6.jar
and any compiled code, you can also build a standalone application in the same way as with fregec.jar
.
Sure. Use the tool of your choice. Here is an example, using ProGuard:
-
The configuration file for ProGuard
pg.conf
-injars build(**/*.class) -injars ../frege/fregec.jar -outjars application.jar -libraryjars /usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rt.jar -optimizationpasses 3 -dontobfuscate -keep public class examples.Mockingbird { public protected *; }
This assumes the classes of the application are below
build/
, the sibling../frege/
directory holds thefregec.jar
and the main class isexamples.Mockingbird
. The output will be inapplication.jar
-
Now run the following commands:
java -jar $HOME/bin/proguard.jar @pg.conf # adapt proguard.jar location! jar -ufve application.jar examples.Mockingbird # or whatever your main module is java -jar application.jar # will run your program
The size of the
application.jar
was well below 1MB.
Yes, it is possible. But you must set the Prefix
option in the Frege preferences to some string, for example my
. This will cause all Java packages generated by Frege to start with my
. This way, modules compiled in Eclipse cannot get confused with the ones in the fregec.jar
that is part of the plugin.
If you don't set the prefix, the builder will get severely confused. For example, it may recompile the whole thing on every change, because it thinks that the compiled classes are too old. Or it may think it is not necessary to compile something at all. Or modules get imported from the JAR, instead of from your bin
directory.
OTOH, it seems that Eclipse will not like the bin/myfrege
directory and removes it from time to time (on restarts, for example). This will then cause a full build, because the Frege builder sees that nothing is there.
Why does the Frege compiler generate Java code? All other JVM languages generate byte code directly!
This is a consequence of the way the native interface works. Consider this, for example:
data Bar = pure native com.foo.Bar where
pure native new :: Int -> Bar
pure native another :: Bar -> String -> Maybe Bar
This tells the compiler, among other things, that a Frege expression like
Bar.another (Bar.new 42) "foo"
can be compiled to a Java expression
new com.foo.Bar(42).another("foo")
and that this well typed expression yields a Bar
or null
.
Note that Frege code generation does not need to know whether com.foo.Bar
exists, nor does it need to check the method signature of the constructors to find a matching one. Those boring tasks are left to the Java compiler.
This is an all-or-nothing approach: even if we knew everything javac
could ever know about com.foo.Bar
, it would still not be enough information for the Frege compiler. For example, the fact that the method another
could return null
is not necessarily available from class files or JARs. Hence, instead of doing a half cooked job checking native declarations, they aren't checked at all. Rather, code is generated under the assumption that they are correct. If they aren't, you'll get error messages from the Java compiler.
This has the additional advantage that Frege is (almost) decoupled of Java and could in principle generate code in any OO language. Only the code generation pass needs to know a small subset of Java at all, and this is merely knowledge about the syntactical representation of some concepts and idioms common to most imperative languages. So, maybe one day we can generate JavaScript, C# or whatnot with only small changes to the backend. While in the case that the backend would generate byte code, we would have to throw it away entirely and start from scratch.
That being said, if you think that a JVM byte code backend would be somehow superior, just write one!
Home
News
Community
- Online Communities
- Frege Ecosystem
- Frege Day 2015
- Protocol
- Simon Peyton-Jones Transcript
- Talks
- Articles
- Books
- Courses
Documentation
- Getting Started
- Online REPL
- FAQ
- Language and API Reference
- Libraries
- Language Interoperability
- Calling Frege From Java (old)
- Calling Java From Frege
- Calling Frege From Java (new)
- Compiler Manpage
- Source Code Doc
- Contributing
- System Properties
- License
- IDE Support
- Eclipse
- Intellij
- VS Code and Language Server
- Haskell
- Differences
- GHC Options vs Frege
- Learn You A Haskell Adaptations
- Official Doc
Downloads