
Eta – A powerful language for building scalable systems on the JVM - psibi
http://eta-lang.org/
======
chubot
FWIW the demo snippet is a toy and not the real quicksort, which is in-place,
rather than copying the list / creating garbage at every step.

Ironically it says "A powerful language for building scalable systems on the
JVM" but this literally doesn't scale as quicksort does.

[http://stackoverflow.com/questions/7717691/why-is-the-
minima...](http://stackoverflow.com/questions/7717691/why-is-the-minimalist-
example-haskell-quicksort-not-a-true-quicksort)

[https://wiki.haskell.org/Introduction#Quicksort_in_Haskell](https://wiki.haskell.org/Introduction#Quicksort_in_Haskell)

This is related to the "Genuine Sieve of Eratosthenes", which is also an
imperative algorithm and NOT a functional one:

[https://www.cs.hmc.edu/~oneill/papers/Sieve-
JFP.pdf](https://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf)

This brings to mind the slur "Haskell (Lisp) programmers know the value of
everything but not the cost".

~~~
petters
I saw that quicksort code when I looked at Haskell back in 2002. Why is that
still used as an example?

I have seen in-place quicksort in Haskell and it is not pretty.

~~~
nine_k
The example is simple and expressive, it's relatively easy to understand even
if you don't known the language. It gives you the idea of the expressive
power.

It's not performant, though, and should not be considered a real quicksort
implementation. So it's not showing you the cost of this particular
abstraction.

~~~
rahulmutt
"Relatively easy to understand even if you don't know the language" <\- We
have empirically verified this by showing code samples of quicksort side-by-
side in Java, Scala, Clojure, and Eta to ~100 programmers who had no
experience with functional programming at an exhibition. Eta won, followed
closely by Scala (people just love their curly braces!). One person liked
Clojure because of "it looked like English" and no one liked Java. For this
reason, we have posted it on the landing page. We have made no claims that
it's the most performant nor that it's the fully correct quicksort (accounting
for uniques) - the whole point was to highlight the expressiveness.

~~~
hota_mazi
The fact these people were picked at a conference is already very strong
confirmation bias.

Pick 100 random (really random) programmers and I'm betting a lot more of them
will feel more comfortable with the imperative version over all the others.

~~~
nine_k
Pick 100 random programmers in 1970 and most of them would be more comfortable
with GOTO-based programming, for variety of reasons, including performance.

"Whenever you find yourself on the side of the majority, it is time to pause
and reflect. (Mark Twain, ~150 years ago)"

~~~
kaeluka
> "Whenever you find yourself on the side of the majority, it is time to pause
> and reflect. (Mark Twain, ~150 years ago)"

That seems to be exactly what hota_mazi is saying.

~~~
nine_k
Not that I'm objecting! I'm commenting. Sometimes stating the obvious helps
trigger that "pause and reflect" thing.

------
moomin
For people new to the party, this looks great. For those who had been
following the GHCVM project, it's a horrible disappointment.

Basically, this project used to be a fork of the Haskell compiler to support
the JVM. Now it's a fork of the Haskell compiler that may or may not be
compatible for your use case depending on their opinion of GHC's features.

~~~
willtim
I don't think it is necessarily a bad thing if they remain Haskell 2010
compliant and use pragmas for their own extensions. I certainly would like to
see features like extensible records and variants; and this is unlikely to
happen anytime soon in GHC, as the focus seems to be dependent types.

~~~
rahulmutt
This is exactly the direction we're going. I'm a big fan of extensible
records/variants. We'll be supporting the GHC 8 extensions that are orthogonal
to the type system refactoring like Strict, StrictData, etc. pretty much
everything other than TypeInType.

~~~
willtim
Exciting stuff! The JVM really needs a modern statically typed functional
language.

------
swlkr
The website is exactly what a programming language website should be. Syntax
and features front and center.

------
jfe
i feel like each "new" general-purpose language project is just nipping at the
boot-heels of the much bigger problem of constructing large-scale systems that
can be fully understood by a few (2-3) people.

VPRI's research has shown that one important method for constructing large-
scale systems that can be understood by small teams is to have a pipeline of
problem-specific languages that express major portions of the system. they
were able to reduce LOC for a typical OS with networking and graphics by 3 or
4 orders of magnitude.

general-purpose languages can't compete with DSLs in terms of expression, and
yet we keep inventing them. i think our lack of imagination is starting to
show. compilation and language design will need to become much more common-
place if we expect to continue scaling up.

a tower of babel in computing is _healthy_ , no matter how much employers want
us to be easily-replaceable cogs in an IT machine.

~~~
nine_k
(1) This language has been invented long ago; its name is Haskell. Eta is a
JVM backend / target for it.

(2) A good general-purpose language is good at creating pseudo-DSLs, also
known as abstractions or APIs. This can include customized syntax, but usually
it's not a brilliant idea. DSLs using the common syntax are quite prevalent in
Lisp / Scheme / Clojure, or in Ruby. Haskell is reasonably good at creating
DSLs, much better than e.g. Java.

------
virtualwhys
Awesome,

Haskell <> JVM with Eta[1]

Scala <> Native with Scala Native[2]

One language to rule them all. Personally am rooting for both becoming a
success, though Eta may have the easier path given that it can piggy back on
the JVM, while Scala Native will have to, for example, come up with a
plausible GC solution (i.e. matching JVM's world class GC is a tall task to
say the least) along with porting myriad Java/Scala libs to native.

[1] [https://github.com/typelead/eta](https://github.com/typelead/eta)

[2] [https://github.com/scala-native/scala-native](https://github.com/scala-
native/scala-native)

~~~
lmm
I want purity without laziness - I think that's the ideal combination. So I'm
most excited for Idris (which has both JVM and native backends).

------
psibi
This is the relevant github repository:
[https://github.com/typelead/eta](https://github.com/typelead/eta)

And this is the blog post from the co-founder of Typelead (the company behind
Eta) discussing about it: [https://blog.typelead.com/https-blog-typelead-com-
introducin...](https://blog.typelead.com/https-blog-typelead-com-introducing-
typelead-14c4a1bf2df#.7zt3riywq)

------
taylodl
Why do we need this? We've already had Frege
([https://github.com/Frege/frege](https://github.com/Frege/frege)) filling
this role for roughly three years now. Seems to me the DRY principal doesn't
just apply to personal projects but to public works as well.

~~~
psibi
This might be helpful:

* [https://github.com/typelead/eta/blob/master/docs/source/faq....](https://github.com/typelead/eta/blob/master/docs/source/faq.rst#how-is-eta-different-from-frege)

* [https://github.com/typelead/eta/issues/3](https://github.com/typelead/eta/issues/3)

~~~
paulddraper
tl;dr Freda uses a modified version of GHC and doesn't have a lot of commonly
used extensions.

~~~
dualogy
I'd hope Eta "just" focuses on compiling GHC's core (not Core) intermediate-
representation STG (or C--) into Java bytecode: then, no need to forever catch
up re-implementing the ever-evolving language extensions, _plus_ this just
gets you all the desugaring / Core-to-Core optimization/simplification
roundtrips, custom rewrite-rules, type checking / verification etc pp from
GHC. In fact no need for any great checks and verifications, "just" (probably
highly intricate in the end) a series of code format transformations.. in
theory ;) GHC's various intermediate representations are pretty brilliant and
thus I think should be leveraged as much as possible when it comes to new
compilation targets and transpilation. Fun fact, seems as of 2002 there was
for a while an STG-to-JVM backend.

Now there's issues with this approach too! You'd end up with a massively
convoluted set of mappings of Haskell's factory defaults to the JVM's. We're
talking the equivalents of `Prelude` module, `base` package, the RTS (garbage
collector and much more.. ouch!), and for each and every individual instance
deciding where to draw the line between Java's built-ins' semantics and GHC's
would be a massive challenge.

What's with GHC's existing LLVM backend, does LLVM not have their own Java
byte-code backend(s)? (OTOH, additional major dependencies always kinda
bite..)

~~~
rahulmutt
Eta in fact only deals with STG code -> Java bytecode transformation. I agree
that the intermediate transformations are brilliant, so I am very careful
about playing around with the frontend bit of the GHC codebase. Eta currently
implements almost all of GHC's primitive operations faithfully. I have taken
extreme care in preserving semantics. In some obscure cases though, I just
gave up since there are no platform-independent ways of implementing certain
things (like vectorised instructions).

~~~
dualogy
Now that's awesome to hear! Can't wait to give this a go for making an Android
app on the next occasion that pops up

~~~
rahulmutt
GHC 8 will take some time. The current position is to prioritize those new
extensions which start creeping up in Hackage libraries. There were
significant changes to the codebase in 8 and I want to wait until it's
stabilized. Eventually, yes.

~~~
dualogy
I thought most extensions "just provide sugar" and are gone by the STG stage..
guess not =)

~~~
rahulmutt
No, you're right. I just don't want to swap out the frontends right now
(again, stability). I'll definitely be cherry picking bug fixes and non-
pervasive changes once I get a solid test/benchmark suite setup.

------
omaranto
Looks like they don't acknowledge it on the landing page, but this is probably
an implementation of Haskell, or of a dialect of Haskell.

~~~
omaranto
Oh, while the landing page doesn't mention Haskell, the documentation does (it
says they don't use the name Haskell in an attempt to avoid the "26 years of
psychology and perception that was built around the language").

~~~
acjohnson55
That seems like wishful thinking. Anyone who knows anything about Haskell
recognizes it on-sight. Anyone who doesn't will probably find it fairly
radically different from what they're used to in a programming language, and
not realize that it comes from a deep tradition with lots of community
support.

~~~
usrusr
I can sympathize with the reasoning behind the rebranding. "A new language on
the JVM (which happens to be Haskell)" has a slightly different spin than
"Haskell on the JVM". The latter sounds like it is targeted at Haskellers
looking for new runtime choices, whereas the former is quite suggestive of
moving Haskell a considerable step closer to the comfort zone of a certain
group of non-Haskellers.

Unfortunately, the "(that happens to be Haskell)" part is completely left out
on the entry page. This gives a terrible first impression, because it seems
like if someone would be trying to bootleg those 26 years that went into
Haskell and sell them of as their own achievement. The documentation does a
reasonable effort to set this straight, but the aftertaste from the first
impression remains.

------
lacampbell
I'm interested in what the trade off between "lazy by default" and "Eager by
default, with some great lazy data structures you can use" is?

Often programming language support for streams will feel a little second
class, and I'd love to have something as first class seeming as Haskells lazy
list - but that's a minority of the time for me.

~~~
rahulmutt
Given the recent interest in reactive programming, people will probably like
the built-in support for streams via lazy lists in Eta.

------
kaykay
There is a bug in the code, unless the input is expected to be a set instead
of a list.

I believe the right implementation should be something like:

    
    
      main :: IO ()
      main = print $ quicksort [1, 123, 42, 90, 1, 23, 24, 12, 3]
      quicksort [] = []
      quicksort (x:xs) = quicksort left ++ [x] ++ quicksort right
          where left  = [ y | y <- xs, y < x ]
                right = [ y | y <- xs, y >= x ]

~~~
rahulmutt
Thanks for the fix! It's up on the site now.

~~~
seagreen
Have you considered replacing the example entirely? A toy program that looks
good but is terribly nonperformant is exactly what I'd put up if I wanted to
make a Haskell-style language look bad.

~~~
rahulmutt
Performance of a tiny code sample is not why people select one language over
another. If that was the case, no one would be using anything besides assembly
or C. Even in other languages, you'll use an abstraction heavy implementation
for the benefit of long-term maintenance and code evolution and then
performance optimise the bits that can pack a punch. Performance optimisation
in any language looks ugly be it C or Haskell.

~~~
codygman
> Performance of a tiny code sample is not why people select one language over
> another.

It's not how people _should_ choose a language, but I'd wager it plays a non-
trivial part even if only from laziness alone.

We have to remember we aren't marketing to perfect* developers but more to the
average if an aim is mass adoption.

*Perfect as in follows general programming best practices. Following best practices is not always best. Not trying to make a value judgment here.

------
danielam
There's a bug in the quicksort implementation example (it assumes all values
in the list are unique).

~~~
eklavya
Also in the STM example, they only ever read sender's balance and never the
receiver's balance.

~~~
rahulmutt
Great catch! I've pushed the update. Should be fixed soon.

------
ww520
Looks similar to Haskell.

Edit: Darn, I'm stupid. It's a port of Haskell to JVM.

------
pyrale
That's great news !

I'm quite disapointed by the decision regarding GHC8, though. Overloaded
record labels adresses a problem which the community was quite annoyed with,
for instance.

~~~
rahulmutt
Don't worry. Solving the records problem is a high priority item for Eta. We
might solve it in a different way than GHC 8, so that's where the 'dialect'
part comes in.

------
danidiaz
I don't really mind if Eta ends diverging from Haskell in the particulars but
remains Haskell-like à la Purescript.

I'm curious about how the jvm will behave in regards to laziness and
typeclasses (MTL-like libraries, in particular).

~~~
rahulmutt
The benchmarks I've run are extremely promising, and Eta is sometimes
competitive to GHC after warmup. GHC's aggressive optimisations with -O2 +
Oracle JVM's JIT seem to be a very powerful combination. I have avoided
publishing the results because I still need to spend more time looking at the
numbers and understand why was so fast in certain cases (check up on any
mistakes I've made). I'd rather take the time to report proper benchmarks
rather than hype unverified results.

------
benol
Does it come with a debugger of any kind?

I think this is the biggest gap in the Haskell ecosystem right now. Every time
I try to write something in Haskell, I remember I cannot "talk to my program"
easily and just give up.

~~~
rahulmutt
You can use JVM debugging tools and with a guide on how to interpret the
results for Eta (or a tool that does the mapping to Eta source code for you),
debugging can be pretty awesome. The implementation was specifically designed
to re-use the JVM Thread stack as much as possible so that you can get stack
traces and figure out the source of the error. You'll get stack traces similar
to other JVM languages like Scala and Clojure. See [http://eta-
lang.org/docs/html/eta-user-guide.html#debugging-...](http://eta-
lang.org/docs/html/eta-user-guide.html#debugging-stack-traces) for an example.
You can use tools like slf4j-ext as java agents and get nice traces - it's how
I debug the Eta runtime.

------
cle
How is this "scalable"? What does that mean?

------
omaranto
The quicksort example seems oddly named, I would have called it "unique" or
"removeDuplicates".

If you change one of the inequalities, say ">" to ">=", then it does sort
(without removing duplicates). It still wouldn't feel fair to call it
"quicksort" because it isn't in place.

------
sandGorgon
Awesome! built in Bangalore - [http://typelead.com/contact-us/index.html#our-
office](http://typelead.com/contact-us/index.html#our-office)

The stock image on the about-us page threw me off. Great going guys!

We have already been sold on Kotlin... but Eta looks interesting.

------
preordained
Hmmm...could get me back into Haskell (cough--mean Eta). I always hated the
Haskell environment. A nice to work with port to JVM could inject some life
back into that interest. There was Frege, but it just seemed fringe at the
time...we'll seem if this has any steam behind it.

------
MaxLeiter
Has a gitter and slack but no IRC?

------
nnq
This makes me wonder again: is there any such language but for people wanting
an _eager_ (not lazy) Haskell?

(and I don't care for it to be JVM. but I do care for it to be be Haskell...
OCaml is not Haskell and has too many weird dark corners imho)

~~~
speedkills
Idris

------
geff82
When you write about this new language, you'll be on the no-fly list soon :)

~~~
abiox
i guess i haven't been watching the news much... why?

~~~
sampo
[https://en.wikipedia.org/wiki/ETA_(separatist_group)](https://en.wikipedia.org/wiki/ETA_\(separatist_group\))

------
blunte
If they had any marketing sense, they would start by telling me why it's
better than Clojure. I'm sorry to offend the Scala guys, but if you want to be
the best JVM language, you need to improve on Clojure.

~~~
zzalpha
I hope what you're really saying is that they need to do a better job of
marketing to folks not already familiar with Haskell or similar ML-derived
functional programming languages.

And that's probably true.

As for specifically competing with Clojure... frankly, who cares? The two are
so different as to render such a comparison fairly useless: Lisp-y
s-expressions versus ML-style syntax. Strict Hindley-Milner-style type system
vs Lisp-style dynamic typing. Lazy evaluation versus strict. Pure versus
impure. The list goes on and on.

Clojure is an interesting language, no doubt. But your response would seem to
imply it's the end-all and be-all of programming languages, and given how
subjective such an assessment would be, it strikes me as a fairly vacuous
claim...

~~~
blunte
We are talking about the JVM. And as such, the existing competitors are Java,
Scala, and Clojure. Scala had promise, but many significant users discovered
warts on large projects. And on top of that, Lisp is not only sexy (rationally
or irrationally), but Clojure has a lot of intellectual momentum. Further, we
have Clojurescript for nodejs. It is the one to beat.

So if someone is going to sell me on a better JVM language, they need to at
least give me a pro/con list vs Clojure. While HN might disagree, the market
(people who work in companies that live for revenue, not VC) will agree in my
interest for that comparison.

~~~
lenkite
I looked at Clojure but the lack of static types and thus losing the benefit
of refactoring always put me away. Out of curiosity - how do you safely
refactor Clojure code ? Safe Refactoring offered by type safe languages is
such a major aid to redesigning code that it has become difficult for me to
work in dynamic languages for any large code bases.

~~~
_halgari
I've been a full-time Clojure dev for about 4-5 years now. And the number of
times you have to refactor (in the traditional sense) Clojure code is pretty
rare. And the reason is that Clojure leverages it's use of immutable data
structures, namely hash maps.

So let's say I have a function that needs :name and :addr and it adds a new
field calls :name+addr. Now in most (all?) statically typed languages I would
have to say that this function takes a "name and addr" and returns "name,
addr, and name+addr". So I have a type conversion, right? If the time comes
that I need to modify these types, I have to do some sort of refactor.

In Clojure we'd just take a hash map and add a new k/v pair to the hash map we
get. Any hash map will work, as long as it has the proper entries, and we'll
just add a new entry to that. So if the time comes that I want to call this
function with a "company" instead of a "person", it just works, as long as I
have the proper keys. And to help check this sort of stuff we do have spec
([https://clojure.org/about/spec](https://clojure.org/about/spec)).

TL;DR -- my belief having programed in both static and dynamic languages is
that deep refactoring is primarily driven by the inflexibility of static
types.

------
ibejoeb
One of these must need some division...

    
    
        feet2Meters :: Feet -> Meters
        feet2Meters (Feet ft) = Meters $ ft * 0.3048
    
        meters2Feet :: Feet -> Meters
        meters2Feet (Meters m) = Feet $ m * 0.3048

~~~
twic
No, in Haskell, if it compiles, it works.

------
hyperpallium
Seems 99% written in haskell/eta itself, with a little c.

So, the compiler won't run on the JVM... if it did, there could be haskell dev
on-the-device for Android...

~~~
rahulmutt
There are plans to make the compiler self-hoisting once it's more stable. The
little bit of C used is just to turn on an option in the GHC runtime for
profiling purposes. That would be replaced with some Java code to turn on an
option in the Eta runtime if it were self-hoisting.

------
catnaroek
I'd like to know if the most scalable technique for reasoning about program
data works: structural induction!

Is Eta strict or lazy?

~~~
rahulmutt
Lazy. I think we have enough strict JVM languages.

~~~
catnaroek
What a pity. There are several strict JVM languages, but there aren't enough
of them with compound values, i.e., unencumbered by pervasive use of object
identities when manipulating compound data.

~~~
rahulmutt
Laziness by default does not mean you can't have strict primitive types, which
Eta does. Moreover, if you ever want to avoid object references in
performance-sensitive contexts, you can allocate off-heap memory and work
directly with that via the Ptr mechanism (which is backed by
DirectByteBuffers). GHC 8 recently got compound values with an extension
called UnboxedSums. It would be tricky to implement on the JVM though in Eta,
but not impossible.

~~~
catnaroek
In a lazy language, a strictness annotation doesn't change the type of the
annotated thing - bottom still inhabits that type.

On the other hand, in a strict language with a laziness monad, the difference
between, say, `foo -> bar` and `foo lazy -> bar` (ML syntax) is as clear as
daylight. The types tell you what's going on.

~~~
aseipp
OTOH, most of the things I actually use laziness for in Haskell do not fall
into the `foo lazy -> bar` category, because they involve things like floating
out IO actions or renaming things, and in fact, changing the type makes them
_more_ cumbersome e.g.

    
    
        if x then error "bad" else thing
    

to

    
    
        let z = error "bad" in if x then z else thing
    

Which isn't a valid transformation in any strict language. This general idea
is pervasive in the code I write, where the act of binding something is
immaterial to its evaluation. I think we use this style a lot more than we
give ourselves credit for in Haskell. You can of course wrap this in a thunk,
and some of the usage style can be approximated by a monadic type. But this is
all just really cumbersome and annoying to do pervasively. It's the best
benefit I get from laziness, to structure code this way. You also end up
duplicating a lot of strict-vs-lazy code either way you pick, since "crossing
the streams" is generally either forbidden by the type system (in your
example) or you need the different implicit characteristics (like in Haskell).
It's not really clear to me this is a win overall.

I'm not opposed to strict languages, but IMO, I think if you want a strict
language, you're better off just forgoing the whole thing, and using lambdas
(thunks) where needed for small delays, and a good macro system to define
control structures for everything else rather than trying to shoehorn laziness
into your types or whatever. Random thunks you occasionally need aren't really
the benefit. Being able to decouple definition from evaluation is.

~~~
catnaroek
In any language, not just a lazy one, “let x = v in t” is beta-equivalent to
“t[x:=v]”, whenever “v” is a beta-equivalent to a value in the language. Of
course, in a call-by-need (or pure call-by-name) language, every term is a
value. In a call-by-value language, some terms are not values (and this is a
feature).

------
Rapzid
This looks really cool. How are the language services coming along? Can we
expect something on par with F#'s?

------
hacker_9
I really don't understand the need to squeeze as much functionality as
possible out of as few lines as possible, that the code makes no sense no
read. How am I supposed to parse the cryptic beginning example which shows the
2048 game being played? It looks like a ton of stuff has just been hidden way,
which is fine for the example but likely all falls apart when you try to add
something new to the game.

~~~
justusw
I don't think the code in the 2048 example is complete, it is just some GUI
boilerplate. I would love to see the rest of this.

~~~
rahulmutt
You can, see
[https://github.com/rahulmutt/eta-2048](https://github.com/rahulmutt/eta-2048).
The whole point of that example was to demonstrate that you can build
nontrivial things with Eta right now. Just have to deal with Java FFI
boilerplate which requires some patience without any IDE support.

------
mistaken
I'd personally just support Frege more instead of reinventing the wheel.
[https://github.com/Frege/frege](https://github.com/Frege/frege)

~~~
nine_k
These are different beasts. Frege does not do the GHC extensions. Eta seems to
reuse much of the GHC's frontend transformations, while Frege is built from
the ground up.

------
andrzejsz
Does anybody knows about syntax highlighting support?

~~~
rahulmutt
Throughout eta-lang.org we use a custom syntax highlighter we developed for
CodeMirror (used in the playground) and Pygments for the static code examples
throughout the docs. We will translate these to other platforms like Emacs,
Vim, Eclipse, IntelliJ, etc. once IDE support is better.

------
TurboHaskal
What an unfortunate name.

~~~
dualogy
Your nickname just made my, er, moment..

~~~
desireco42
Wouldn't notice if you didn't say it :) Tx

------
eta
nice

------
eta
wow

------
the_duke
Yay, Haskell on the JVM.

Again.

------
general_ai
Java's hunger for memory, combined with Haskell's unpredictability wrt memory
allocations due to laziness. What could possibly go wrong.

------
popobobo
Yet another JVM language. YAJVML

------
agounaris
Its amazing that if you put down all the languages that consider themselves
powerful and scalable you somehow reach what religion is...everybody thinks
their god is the only one, and if one indeed exists all the rest are wrong by
default!

Technology is fair and there is a reason why haskell is not used apart from
niche or academic projects. If you want to use jvm to deliver functionality
for your users just a "boring" technology. No user, never, cared about the
programming paradigm.

~~~
platz
> haskell is not used apart from niche or academic projects

While haskell doesn't have as wide adoption as the top languages, your comment
is not true. Even facebook uses haskell for fighting spam.

> If you want to use jvm to deliver functionality for your users just a
> "boring" technology

You're entitled to your preference, but I assume you'd say the same about
about Clojure and Scala then, since, after all, everyone should just be using
Java?

