"Frege is thought as a substitute for this missing GHC port. While not derived from any existing Haskell implementation, it is more or less equivalent to Haskell 2010. Please see the wiki page that details the differences."
So now Haskell can produce native executable code, run in a JVM and as subset of it (https://github.com/faylang/fay/wiki) run in the browser. Now there is no excuse for me to NOT using Haskell ;)
A large part of why I like Haskell is the ghc-specific extensions. TemplateHaskell, OverloadedStrings, DeriveGeneric etc.. Standard Haskell is (imho) much more cumbersome without them.
Another difference not mentioned is given the use of recursion in Haskell and the JVM's lack of tail-call optimisation, I have to wonder how dangerous this is. I know Clojure has recur (I'm not a Clojure programmer) but unless Frege has something similar, I predict many an exploding stack.
What about tail calls for mutually recursive functions? My understanding is that Scala is not able to do tail call elimination in this situation. So the only situation where you can be sure that deep recursion won't overflow the stack is when a function is tail calling itself.
If Frege isn't able to do any better with mutual recursion then that might be a severe limitation on its utility. Scala users can work around the issue by writing loops manually. In a pure language, not so much.
As a programmer who's getting annoyed and tired of Java's boilerplate, I welcome this. I went from Haskell to Clojure to JavaScript.
I loved Haskell the language. What I don't is third party libraries are usually directly or indirectly (through a dependency) tied to an OS. I've heard, even on irc's #haskell, that it's hard to reuse code unless you're on linux. Coming from Java, this is a deal breaker for me.
Then I tried Clojure. I liked it, but I found it very challenging to refactor and mentally debug my code. I missed all the benefits of static typing. core.typed seemed like an answer, but when you compare it to other languages it seems to triple the verbosity which is a real turn off.
JavaScript (via CoffeeScript) is a pretty good middle ground, but immutable state is nearly impossible. If I get lazy, it's so easy to go back to a OO/procedural style and I don't like that. That probably does have its benefits, but not when you're trying to learn a new programming paradigm.
I know very little about Scala, but I get a terrible impression from it. Where Clojure is about simplicity, Scala seems to be about complexity.
Since I learned Haskell, I wished there was a way I could use it and have it "just work" when I decide to use a library. Frege may be the answer. I've heard of it a long time ago. My concern is that I'd be 1 of 3 people who'd be using it. But nothing's perfect.
> My concern is that I'd be 1 of 3 people who'd be using it.
This concern is probably well founded. :)
And yet. Remember, you get Java source code from the Frege compiler, and once you pack up your JAR with Proguard, say, nobody will be able to tell you didn't write it in Java. (Well, slightly exaggerated, but you could have used some obscure library, who knows?)
So, if you have a small project, or some Haskell project without too many GHC extensions you want for some reason on the JVM, give it a try.
Any data structures on the public API would have to be marshaled from whatever JVM language into fredge. Even sharing code between scala and java can be painful and obvious.
I'm confused as to how javascript is a good middle ground. What does it give you that Clojure doesn't? You do mention the fact that it encourages imperative code and loses immutability. How does it improve refactoring or debugging?
That's a fair question and I don't understand it myself. Perhaps it's because the Firefox/Chrome dev tools are so useful. Perhaps its because I understand what the errors are trying to tell me. In JS I usually have a good mental model of the data I'm dealing with. I didn't have that with Clojure. I didn't have it in Haskell either, but the Haskell compiler would immediately get in my face about it until I fixed it.
It's a real shame that FFI-dependent Haskell libraries don't build out of the box on platforms other than Linux. If you really like the language, have you considered some workarounds for this problem directly? It may be a lot easier to do a workaround than to switch to a new language entirely.
It sounds like multi-platform support is important to you, how do you intend to deploy your software? In many cases, you can get away with rolling up binaries and not worrying about trying to actually build the software on your target machine.
I tried to get it to work, but it's really hard. Imagine you barely know the language and you barely understand how binary libraries work in linux and you're getting these errors that you've never seen before. You ask for help but it seems like you're the 2nd person on the planet who's ever experienced this issue. You read the post of the 1st guy, but for some reason his solution doesn't work for you and you don't understand why.
Most people in #haskell told me to switch to linux which seems like a ridiculous solution. I documented my struggle as another HN comment you can read here: https://news.ycombinator.com/item?id=5615683
Most people in #haskell told me to switch to linux which seems like a ridiculous solution.
Yeah, that's really unfortunate. This problem will continue to persist as long as people keep switching to linux to avoid it or abandoning the language altogether.
How long ago was your attempt and how did you install Haskell itself on your system?
Scala is the most enjoyable language I've ever programmed in. Most of the complexity is superficial or shaped to the problem; there are a lot of features and they can be combined to make complex things, but each of them makes sense, and there's very little in the way of fiddly edge cases to memorize.
More than I could remember all of, but certainly Python, Java, C, TCL, Javascript, C++, ML, Perl, 6502 assembler. I've stuck my head around the door of Haskell, so to speak, but not written anything substantial in it; I haven't tried Clojure (I've never heard a reason to use it over Scala, and I've become very attached to powerful type systems).
It's interesting to compare this to CAL - an earlier Haskell-like language on the JVM that was a project of some of my former colleagues at Crystal Decisions/Business Objects back in the 00's: http://openquark.org/Welcome.html
I've worked quite a bit with CAL over the years and it has been used for some serious work. One of my big frustrations with it though has been the clunkiness of the Java interop, especially since this is one of the reasons you might choose to use a language on the JVM.
Looking at the Frege docs, I like the look of the way this has been handled - rather than using an FFI-style approach, things like Int, String etc map directly to Java types and Java classes can be used like ADTs, which would make life way, way easier.
Given the nature of the language calling Frege from Java is always going to be more complicated but it looks like they've done a nice "fluent" Java API for calling into the runtime.
Would be interesting to see how this performs relative to CAL, in terms of both speed and space.
Unfortunately it looks like you would have to build from source. The best place for that would be Rich Webster's fork - https://github.com/rdwebster/Open-Quark - which is the version maintained by Indicee.
I imagine the documentation is completely out of date.
Anyway, if you don't want to look at it, that's your loss - while I don't think CAL has much of a future a lot of work was invested in it by a very talented team and there is probably something to be learned from it.
I like some of the differences where it was not constrained by Haskell's choices, like splitting up the Monad, Applicative, Functor instances, and namespacing of accessors.
I also quite like the • for compose, with then some shims so that . works too if it's not being used for the namespacing.
Haskell can do it: there's a library with common Unicode operators[1] (including ∘ for function composition) and an extension allowing you to use Unicode syntax[2] (things like → in place of ->).
I've seen these things used, but they're not super common. People still worry about not being able to input Unicode symbols in their editor! I personally think this is absurd in this day and age. Naturally, it's very easy to do in Emacs; somebody even wrote a Haskell input mode[3].
Oh, nice! I setup XCompose to support rfc1345, so I have fast unicode input everywhere. I'm definitely going to experiment with that Haskell extension. I've done that manually before in ML with a preprocessor, but it was a nasty hack. A proper extension is much nicer!
EDIT: How many people still have trouble with Unicode input? Should I publish my XCompose solution?
It turned out that porting Haskell code was a nightmare when the (.) did not work yet. (You can't just replace each . with • unless you don't have any qualifed names.)
Today, it can be quite easy, in the best case you just Ctrl-C Ctrl-V
The conclusions of http://fregepl.blogspot.jp/2013/03/adding-concurrency-to-fre... lead me to believe that the author knows significantly more about Haskell than about either the JVM or concurrency. I hope that the language is able to attract a healthy number of contributors in those areas before it begins to accrete it's own idiomatic concurrency patterns.
The section on forkIO vs forkOS is interesting because the author does not mention implementing green threads atop the JVM. It would be feasible for Frege and its core libraries to use an implementation of "green threads" based on Promises or CPS under the covers in order to implement a concurrency model indistinguishable from Haskell's.
While it is true that the vast majority of JVM code you interact with is blocking and expects to own whatever OS thread it is running on, that could be treated as a concern of FFI, where untrusted/blocking code in Java land gets dedicated OS threads (similar to FuturePools/execution-contexts for scala Futures, or how you would manually isolate blocking code for Erlang or Go FFI.)
Additionally, the comment dismissing STM seems like an afterthought, because there are at least three JVM implementations (Clojure's, Scala's, and Multiverse)
But the main comment I was referring to was:
To do serious concurrent work in an JVM environment is
different and it will thus require different knowledge
... which suggests that the author isn't interested in supporting Haskell's idiomatic concurrency model atop the JVM, and is instead fine with the status quo of blocking code.
Cute name. I wonder to what extent the language has anything to do with Frege's work in logic. I mean Haskell's last name was Curry, and currying is a big deal in FP. Thankfully that wasn't named after Moses Schoenfinkel.
Actually, I've heard of German professors who used the word "Schoenfinkeln" instead of "currying". You sometimes get people who try to fight the English influence off at all costs ;)
If that's the case, maybe you should name if after Raphael Finkel. [1]
Disclaimer: I had the privilege of meeting Dr. Finkel here at university a few times before I stumbled across his name in Wikipedia and in the front of a book in the library. Totally not biased.
One of the things that make the JVM so cool is the easy interoperability of most JVM languages. It's good to have languages like Java (or Kotlin), Clojure, Frege and Erjang on the JVM, each with its own strengths. Each can remain relatively simple and consistent, and all interoperate and share libraries. This is far better than that "bastardized travesty" trying to be all languages at once, and ending up an incoherent mess, retaining little of the advantages of those simple languages.
I feel like most regular programmers could understand and benefit from using ML (or some similar language).
In Haskell, laziness kept the language pure while it was developing but now I'm not sure it should be the default. I like OCaml style opt in laziness.
For most people, they could get a lot of pretty vanilla typed functional programming language. Polymorphic type inference, algebraic data-types, pattern matching. That gets you really far.
There is Yeti (http://mth.github.io/yeti/), a JVM language from the ML family. I think it's close to a 1.0 release, and the compiler has been pretty reliable for a while now. I find it a delight to use.
As an analytic phil PhD dropout and a Haskell lover I can say with confidence that (a) Gottlob Frege (the philosopher) was awesome (I still want a 'morning star != evening star' tattoo) and (b) Frege sounds lovely too. I'd actually considered writing something similar.
What would you prefer? A language that doesn't need a runtime, like C? A language that has only one available runtime, like node.js? A language that has a choice of runtimes but there are incompatibilities between them like Python or Ruby? A language that has a choice of runtimes from a choice of vendors like Java?
MS are unique in calling their C library a "Runtime library". Commonly, a support system that does GC and other automatic management for managed languages is called a "runtime", and the various common functions available to C program are called a "standard library". The difference is that in C, you can write a program that uses none of the standard library at all, whereas a managed program will use the "runtime" for doing anything at all.
I'd like something running on the CLR. Not because I think the CLR is very special; just because I really like Haskell but I have to work within a large ecosystem of existing .NET code.
I've been playing with it some. It's nice, but I still prefer Haskell. I want to be able to separate pure from impure code, but F# doesn't seem to enforce that. (Unless I'm missing something?)
It doesn't. In fact, F# feels like it started off as a fairly pure functional language but some Microsoft PM said "it has to support every API in .NET" and so a lot of OOP stuff was bolted on the side. It feels like 2 different worlds in one language. You can easily get by never using the impure stuff but it's still there, taking up space.
F#'s design was almost completely handled by Don Syme, in MS Research Cambridge. It is highly unlikely some PM jumped in and insisted it must do things.
The OOP part is rather coherent; I'm not sure what's bolted on - any examples? In fact, things like object expressions do parts of OOP even better than Java/C#. Overall the syntax for OOP is rather concise and neat.
Having proper interop with .NET and hence the OOP is ... pretty key to making a successful .NET language. Otherwise you lose one major point of being able to use .NET libraries.
> The OOP part is rather coherent; I'm not sure what's bolted on - any examples? In fact, things like object expressions do parts of OOP even better than Java/C#. Overall the syntax for OOP is rather concise and neat.
I'm saying I'm not sure why the OOP exists at all. Someone else pointed at that OCaml has those elements as well, and maybe that's the reason. Just in my own use, I never felt the inclination to use the OOP at all, and their existence felt like this part of the language that I didn't understand, didn't want to understand, but was there nonetheless.
F# has its origins in OCaml which has the same set of properties (ability to write impure code and has an object system, albeit one that not many people use). F# replaced that object system with the .NET one.
If you're calling into question the portability of Java, then I can run the same bytecode on Windows, Mac, Linux, the browser (in theory) and, with a little transpiling, my Android.
If you're saying that that priority of decision drivers is backward, then I disagree:
If you want to develop a Windows app you start by saying "I want to develop something on Windows because my clients/customers run Windows". Then you work out how to do it on Windows.
If you start out saying "I want to write an app that does X" then you have the freedom to choose what balance of priorities affect you, including whether or not portability matters.
I believe he's trying to criticize Java for being owned by Oracle. The implication appears to be that alternative implementations are just compatibility layers for Oracle's technology like WINE is for Windows.
(For the record, I don't particularly agree with this. It seems like you could level the same criticism at nearly any language that has one person or stable group controlling it — for example, you could just as validly call Rubinius "WINE for Ruby".)
IIRC Harmony was scuttled primarily because of OpenJDK — Harmony's major corporate sponsor switched its support to OpenJDK, and shortly thereafter the Harmony committee unanimously agreed to put the project in the attic. I don't think Oracle ever actually went after Apache.
And building Twitter [1], and big-data next-generation databases [2], and android apps, and desktop apps, and big data [3], and as a platform for new languages (Clojure, Scala, Frege), and many more applications.
Really, the JVM can be used for anything that _computers_ can be used for, and it does so in a way that the code is runnable across all major platforms and still maintains a top-5 language performance spot, even beating C/C++ in some specific cases.
Why do you feel that the JVM is limited in its applications as a development platform?
If you say so, I see very few of these in production.
> and big data
Daemon.
> Why do you feel that the JVM is limited in its applications as a development platform?
You can't write cli applications in a JVM language because the start-up time is too slow. Which means you can't compose scripts that call Java apps.
This is not just 1 type of application, it's the most important type of application by far. It's fundamental to how Unix operates. With Java you can't write small applications that do one thing well, you have to write big applications that are going to run for a very long time.
This is useful for things like web servers and daemons, but otherwise it sucks. It's why I can't get excited about JVM languages.
> You can't write cli applications in a JVM language because the start-up time is too slow. Which means you can't compose scripts that call Java apps.
You're right. In the case of small, fast applications designed to be called as part of shell scripts, the JVM does suffer start-up costs. Some testing on my personal machine shows the JVM to be 2x to 8x slower than a comparable Ruby or Python script in startup time. [1] Depending on the script, that startup time may or may not acceptable, and if the script runs for longer than a second, which is entirely possible for anything that goes beyond the local machine, the JVM will get progressively faster.
> This is not just 1 type of application, it's the most important type of application by far.
This needs more explanation. I've used Unix for many years, and I've definitely bought in to its philosophy of small and composable; It's a philosophy that in many ways mirrors functional programming. However, in my opinion, the most important type of application varies considerably by person. For you, the small, single-purpose
applications may be what you use most.
And I agree, if you're programming for the Unix platform, the JVM would not be the best choice. Unix was built on C. A program that builds on that platform is probably a better choice.
But there are many more applications out there, and for any command-line program that operate in a time domain longer than 10 seconds, the JVM startup costs are mostly eliminated. This time-domain is very plausible for a command that operates on medium-scale databases or anything with network connectivity.
It's silly to completely dismiss an entire platform because it is not the absolute best choice for a single domain of programs.
I'm curious: What do you do where the short-lived, composable Unix functions are the most important programs?
I think we simply approach software different. I feel that small, composable applications should be the default, and I nearly always start off this way. I've been involved in projects from writing a specialized version of cp, ETL processes, to developer focused but consumer-facing web applications and the first interface I write to anything I do is as a small cli application that works well with standard unix tools.
When you embrace this philosophy it doesn't particularly matter how good a language's ecosystem is, you have all of unix to interop with. For example, I don't care if a language has a good JSON parsing because jq[1] exists and is probably faster and easier to work with than just about any language's built in tools, even better than JavaScript itself.
With JVM you can't participate in writing software this way. Everything must revolve around the JVM and it's ecosystem.
I'd even say daemons are a stretch. Having multiple JVMs running at once would crush a lot of systems.
The JVM and the Java ecosystem are basically all about long-running backend services. It's funny when you consider Java's roots as a simple language designed to enhance web pages.
Really? Plenty of apps run on the JVM (everything from enterprise apps to games to IDEs etc...). I'm no JVM evangelist (I use Haskell with the GHC), but this is just a false statement.
"Enterprise apps" generally means "enterprise web apps", not standalone, deployed applications.
I've never seen a AAA game written in Java. The non-deterministic GC is a dealbreaker as is the speed and space constraints of eg consoles.
The OP is generally correct: the JVM is a niche technology in a way. The Java ecosystem basically specialises in web apps and backend ESB-type stuff (shuttling data very quickly between heterogeneous applications). Of course, this is a very big, well-paying "niche" so it's not something to be afraid of.
Java doesn't need to have a non-deterministic GC. The Real-Time Specification for Java [1] has resulted in a number of JVM implementations designed for low-power, embedded devices; these implementations use a deterministic GC to provide hard real-time guarantees, and the devices they run on are less powerful than the game consoles from even a couple of generations back.
I would say compiled Scala runs well on the Dalvik VM.
All languages that do not need to generate (or load) class files at runtime should work well on Android. And that is because Dalvik does not run class files.
So then why don't we see more non-Java Android apps in the wild? We can only go off of open source apps, I've looked at quite a bit of those and have ran across only a couple that don't use Java.
So now Haskell can produce native executable code, run in a JVM and as subset of it (https://github.com/faylang/fay/wiki) run in the browser. Now there is no excuse for me to NOT using Haskell ;)
Thanks for bringing Haskell to the JVM!