Pre-released jars for 3.25
The Jars here reflect ongoing development for 3.25, and may be needed for going forward.
3.25.84 from Mar 18, 2019
Several small enhancements and pull requests integrated.
3.25.57 from Sep 22, 2018
Java.IO.Filetype is now
pure nativeas required in #367
jline2.14.6since earlier versions fail to determine terminal type on Ubuntu bionics
3.25.42 from May 10, 2018
Contains a fix for #357 that changes the Java signatures of some library functions.
Latest builds of Frege 3.24.xxx for Java 1.8 and higher
After some pause, many bugs of the 3.24alpha releases have been fixed and we have finally a compiler we can work with for future developments.
Note that Java 1.7 is still supported, however, people needing it are kindly asked to build their own. See https://github.com/Frege/frege/wiki/Contributing-to-Frege#recompile-the-compiler-unix
Frege is proud to utilize the jline library in its interpreter. Thank you, https://github.com/jline/jline2
- REPL runs better under Windows now
- compile java source code dependencies in
- The REPL is now included! Just run
java -jar frege3.24.400.jarfrom a command line.
Preliminary new compiler for java8
The preliminary jars here are intended for community members who develop tools like REPL, IDEs and Builders.
A public release is planned to appear in a few weeks, but there are still some minor bugs to fix, issues to resolve, documentation to write and cleanup to do.
Note that except for small programs, you'll need a JAVA 9 SDK if you want to target Java8, since the
javac in Java8 is broken.
The JARs with version numbers 3.24-7 are compiled for target 1.7 and allow Frege development with Java7.
It goes without saying that bug reports are welcome.
The JARs offered here should run with JDK9, as they contain the fix for #165
Also, if you want to build "master", you will need to use one of those.
From 3.23.343 on, we use Haskell lambda syntax. There are a few cases where previously valid syntax won't compile any more (in the whole standard codebase, there were 5 corrections to make). So please recompile your sources to make sure you're up to date.
From 3.23.365 on, we use Haskell class/instance syntax.
Unfortunately, this means that most of your non-trivial class and instance declarations will fail the syntax check. Please adapt and recompile.
Version 3.23.370 contains some patches to show instance and class definitions in the new syntax in the eclipse plugin and doc tool.
Because of the radical syntax change in 365, earlier versions have been removed.
Version 3.23.401 includes the change to Haskell variable names due to @danielkroeni . Unfortunately, this results in changed class names in the binaries, as we had to replace heading underscores with $ signs. This means that this version is not binary backwards compatible with earlier ones, so you have to recompile your sources once.
Finally, 3.23.422 fixes a bug in code generation that has gone unnoticed since February.
3.23.888 is (hopefully) the latest 3.23 release before switching to 3.24.
Please read the release notes for more information.
Please Note The JARs here will not run with JDK9. To run Frege with JDK9, use one of the preliminary releases under "Summer 2015".
Also, as of Aug 20, 2015 you can't build the master branch with those releases anymore.
See description in the wiki.
In certain cases it may be that code that compiled previously doesn't with the new compiler. Most of the time the reason is one of the following:
- lexical errors with no longer supported regular expression literal syntax
- lexical errors with operators
- errors that can be traced back to problems with precedence and/or associativity of operators.
You should be able to solve these after having read the aforementioned wiki page. Or just ask on SO or in the news group.
Please report other errors as issues.
There is also a corresponding version of the eclipse plugin ready for upgrade from the upgrade site, see the fregIDE tutorial. Unless indicated otherwise, you can update your frege IDE 3.22 installation by replacing the
fregec.jar with a more recent one from the 3.22.xxx series.
This is the final release of the 3.21 branch, and serves as fallback (just in case ...), it is also the starting point for the 3.22 releases that will result in an overhauled compiler.
The goals are thus:
- Scanner must not load classes. Because of this, precedence and associativity of operators will not be known to the parser.
- Parser will not: desugar do-blocks and list comprehensions, translate expressions to patterns and will not resolve applications with binary operators. A new source expression type will be needed for this.
- Benefit: Desugaring pass and instance derivation does not need to distinguish between expressions and patterns, which should reduce the support code by 50%.
- Desugaring happens only after import pass, together with name resolution. At this point, the symbol tables of the imported modules are known, which contain operator information n the associated symbols. This will solve also the long standing problem that operator names appear "global", i.e. you can't have two operators with the same name but different associativity and precedence in different modules, without the compiler choosing silently one of the associativities/precedences. Also, these properties can be documented/shown in the IDE.
- Every pass will be of type StateT IO Global. Most passes will not do IO, however. (Scanner, Import, and code generation, of course, must be able to do IO, as well as future plug-ins). Error messages are saved in the state and are printed at the end of the pass. (Trace output will use trace/traceLn, not IO)
- The monolithic big source files (like Transform.fr, that contains 4 different passes) will get splitted up.
- A better make facility will do a dependency analysis of the given source files and compile in parallel, if possible. We will cache the global state, not the annotations from the class files. The latter prooved to be buggy in the presence of certain changes: when B depended on A and A was changed, this loaded the old A.class, then compiled A, then tried to compile B. But in B's import pass, the old A class was still there, so compilation terminated with phantom errors: errors that went away by just restarting the compilation (because then, the new A.class could be loaded). This also makes the import independent with regard to the source of the global state of imported modules: if it was compiled or imported before, the available state can be used, and only if it was not imported before and not build in the same session will the class file get loaded and the global state reconstructed. This will make it possible to javac the produced java files in one go, which could again be faster than now.
a [Char] is now printed as string, like in Haskell.
forkOSare different now. The former submits a task in a fixed size thread pool executor which is provided by the runtime. The latter, as before, creates an OS thread.
In IDE mode, compiler will replace unresolved variables with
undefined, and will continue working, up to and including type check. This makes it probable that unrelated code (and in many cases also code near the error, as
undefinedshouldn't introduce type errors) can still get typechecked, and IDE features like content assist will be able to do better work.
(\it -> it.fooBar). This will typecheck if and only if: the argument type of the lambda is not a type variable and the type of the argument has a
foobaris a class operation. A successful type check will rewrite the lambda like
(\it -> T.fooBar it), where
Tis the type constructor of the type of
it. Later, a simplifying compiler pass will un-eta-expand the lambda, and the result is just
T.fooBar. This way, we can TDNR a function even if we have no actual syntactic argument it is applied to! This comes in handy in point free or monadic context:
letters = packed . filter _.isLetter . unpacked foolines sss = openReader sss >>= _.getLines >>= return . any (flip _.startsWith "foo")
The first example filters the letters of a string. The second one tells if a named file contains lines that start with
"foo". Apart form saving a few keystrokes, the
_.foobarnotation is immune against changes of the type name. Also, you do not even have to be able to name the type taht contains
Access to characters in strings doesn't work anymore with syntax
str.[index]. Use charAt. The syntactic sugar is only valid for arrays.
As of now, there will be just one downloadable file in a release. This is, of course, the frege jar.
All documentation is now kept on http://www.frege-lang.org
- Runtime Javadoc
- Frege Library (I am still looking for a nice way to have a searchable page, or at least an automatic index on http://www.frege-lang.org/doc/frege. Contributions and ideas welcome!).
- Language Reference
This release has the following enhancements:
- Quickcheck 2.6 ported from Haskell
- Quick, a tool to run Quickcheck properties of a module, or several modules. (If you try this on the fregec.jar, there will be 2 failing tests. No worries!)
- better documentation, especially for overloaded native functions
- native array support via JArray
- better Unicode support in the scanner, who used to ignore surrogate pairs. Also, everything that is not explicitly uppercase is treated as lowercase, as far as Frege is concerned. This means, you can now write variable names in scripts that do not have case (like Devanagari). Caveat: the scanner still does not recognize glyphs, that is, if I have a german keyboard, I can enter
äand it will be
U+00E4 LATIN SMALL LETTER A WITH DIAERESIS, which is a letter and hence acceptable in identifiers, but if one enters the canonical decomposition
U+0061 LATIN SMALL LETTER A + U+0308 COMBINING DIAERESISit won't be recognized as identifier part, becasue the scanner still operates on single unicode points, and the diaresis is not a letter, but a non-spacing mark. Arguably, improvements are possible here.
- Regex literals also are more Unicode-ish, they are being compiled with UNICODE_CASE; CANON_EQ and UNICODE_CHARACTER_CLASS flags.
- fixed a bunch of issues
- made the compiled code faster (and, unfortunately, at the same time bigger)
- added a head-strict cons operator
(!:). This means that in
x+3 !: ys, for example,
x+3is evaluated right away, while
ysis still lazy. List comprehension uses this, which often results in better code with less laziness overhead. If one needs to allow for undefined elements in the list, one must use map or the list monad.
- the type unsafe special native return type
[a]is no longer recognized. Use JArray to tell Frege that a Java method returns an array.
- cleaned up the handling of let bound functions. Until now, local functions that did not reference any local name from their outer scope were silently moved to the top level. This often resulted in more general types, though this is seldom necessary. From now on, if you want your local function to have a polymorphic type, you need to annotate it or write it as top level function right away. Unannotated let bound functions are thus never generalised by the type checker, which brings more consistency and often better code. Still, if the function doesn't use local variables from the enclosing scope, it might get moved to the top level so as to avoid inner classes. This is now also documented in the language reference and the "Differences to Haskell".
maincan now have type
[String] -> IO afor some type
ais not (), you need to annotate it, though. If the frege
IO Booland if it is run through the supplied
static void main(String args)java method (i.e. as command line application), the returned value will be used to determine the exit status, where
truesignal success. If main is not annotated and doesn't look like a function, it is assumed to be
IO (). Otherwise, if it has arguments,
[String] -> IO ()is assumed, as before.
- implemented several convenience functions of Haskell heritage:
getContentsand, as substitute for Haskell's
getContentsOfwhich operates on a Reader.
- improved type directed name resolution (TDNR). This means, that expressions of the form
xis an expression and
mis an identifier, will always (I hope!) be typeable, whenever the type of
xcan be determined at all. The non-globalised lets contribute here because there is more code where the type of
xmay get disclosed, but the algorithm I used up to now also had a flaw that prevented proper typing in some cases. The better TDNR also applies to the other syntactic forms that trigger it: