Interview with Kostis Sagonas: On Erlang Tools, Type Systems, and How HiPE Compares to JIT

I’m pleased that we have a fascinating interview with Kostis Sagonas – leader of the HiPE team, one of the creators of Dialyzer, and a speaker at the SF Bay Erlang Factory. This is a bit longer than normal but absolutely worth the read. We cover Erlang’s unique type system, Java’s JIT vs Erlang/OTP’s HiPE, tools such as Dialyzer, and why we will have a future post on Language Creators who have never used a debugger in their language. As usual I transcribed a Skype call so feel free to submit errors and I’ll correct them in the original for the next day or so.

EI: Maybe it’s a good place to start to just have you go over a quick background on yourself. I know your history just from looking at your personal website, but anything that you wanted to kind of say, particularly about how you got into Erlang would be really helpful.

KS: Ok. So, I’m in academia and I’ve been in academia I guess for 20 years now. So when I was an undergraduate student I got fascinated by programming languages and Prolog. It was pretty hot at that time so I chose to do my thesis work, PhD work, on implementing extensions of the Warren Abstract Machine for Prolog.

EI: Ok.

KS: So, I was very interested in the implementation of high level languages, the declarative languages. So then I found a position in Sweden as an assistant professor. There was a very exciting project here in the department on, during the high performance Erlang compiler. So, since my interest was in implementing declarative languages and Erlang had a lot of similarities with Prolog I said, “This is for me,” so I led that group.

EI: What do you like about Erlang? What, what was interesting to you about it, originally?

KS: It was interesting because it was, it was a language that had potential to succeed in some areas where Prolog did not materialize its full potential. So it was, a very down-to-Earth language, it, even back then had an interesting user base in industry. It was “for real,” so to say.

EI: Right.

KS: And well, there was local industry supporting it and we seemed to have an implementation that was the most advanced implementation apparently at the time. The compiler back then wasn’t really mature, but we could with effort become part of the Erlang distribution. I think HiPE has been part of Erlang/OTP since 2001 or 2.

EI: Did you have a hard time convincing Ericsson, at the time, to add HiPE to, to the language or to the platform, or? What was the response when it was suggested to add it?

KS: So, I think Ericsson has been very, very positive for what we are doing at Uppsala university from the start. So they have been extremely supportive. On the other hand, I think that they are a bit, I think that the word is ‘conservative’ since they do not have the expertise to, be supporting the compiler they were a bit reluctant to announce it or to announce it as a supported component to their customers. They were extremely happy having it, HiPE the compiler in the distribution as an experimental addition at first, and then as a component that, is on the same status as many other applications that exist in OTP.

I think that they are still a bit reluctant to say that they’re, that’s supported. Basically because they don’t have the expertise or anybody working at OTP who understands the guts of the compiler.

The OTP team has been supportive from the start and for the last 3 years now. The HiPE compiler is being used more and more. It’s actually being used every time you use dialyzer for a big set of files. It automatically compiles a lot of key files for dialyzer to native code. There have been a lot of projects that I know that are using HiPE. Especially in France, they seem to be an active community there that is using HiPE all the time. So it’s, it’s I think has come to the point that it’s mature enough to be used in many applications that require the extra speed that HiPE gives them.

EI: Right. Well, it seems it’s become quite popular just from talking to people in the community. Also I have a few developers at Inaka (which is my consulting company) and they’ve been quite happy with it in terms of performance. So, I’m curious, when you started HiPE, was this was sort of an academic project, was it sponsored by Ericsson or was there a connection to Ericsson, or was it totally separate research project only?

KS: So, when I started HiPE was in a bit of a, how do I describe this? So, there were two students at Uppsala University developing HiPE as their master thesis. Then it was a bit left on its own in some sense. Basically because the first, when I came in, the version of HiPE we had was based on JAM [ed- Joe's Abstract Machine]. This was at exactly the time that JAM was being obsoleted, taken out from the Erlang/OTP distribution, and BEAM was left as the only machine. So it was a time that BEAM started being the default, and probably the only machine back then. So I realized the danger there. We were going to be left a bit behind and so the first thing I did was to actually write the translation from BEAM to HiPE’s intermediate code presentation. It was actually my second program in Erlang I’ve ever written. The first one was – it’s still in the distribution, by the way, the first one – is the BEAM disassembler. It was really, really fun to write that program. It is still in a file (called beam_disasm.erl) under the compiler application

EI: So most people’s first program is factorial or something. So that’s that’s impressive. (laughs)

KS: So it was even more impressive because there was no documentation about the BEAM formats. So, I was just guessing what Erlang’s byte codes could possibly be. It was really fun, writing that program. And you can still see my code. I think it's still pretty good for being my first Erlang program!

The language, that I actually had no—I never read an Erlang book, believe it or not. So, I picked it up from just programming.

EI: Actually, I don’t know when the first Erlang book came out because the Pragmatic Programmer’s was quite a bit after that.

KS: Yes, yea, well, it, there had been an Erlang book back then, the first Erlang book, but it was very hard to find, even still back then. So, yeah-

EI: That’s funny. Actually just a couple more questions on HiPE. Did you, so it currently-

KS: Sorry, sorry, I did not actually answer your original question. So—

EI: Yes—

KS: So, actually, we the university and Ericsson were part of the same project, sponsored actually by research foundations back in Sweden, that was in Sweden at that time, called, NUTEK [ed: currently VINNOVA]. NUTEK was a foundation that was giving money to encourage collaboration between academia and industry. So most of the sponsoring of the HiPE system, came from NUTEK. Now there were some matching funds from Ericsson, but I think it was a small percentage in actual money. But Ericsson was actually sponsoring HiPE back then.

EI: So, that’s helpful, actually. The next question I have is that I’m sort of curious about the design decisions made, with HiPE. I don’t know a lot about compilation to native code from bytecode –

KS: Don’t worry, just shoot the question and, we’ll correct it.

EI: Well, I’m curious why you decided to use an intermediate format versus going directly to the native code and could you explain that and the reasons behind it? Because, you already had a virtual machine format so it’s kind of interesting.

KS: So, we actually use two different formats inside HiPE. There is an intermediate code presentation which is much closer to Erlang and then there is another RTL so-called Register Transfer Language which is quite similar to GCC’s RTL, but not the same. So the, need for the reason for these two representations has to do with the difference in the representation for Erlang terms in the intermediate code format all the terms are just like Erlang terms all the variables contain Erlang terms. In the RTL we use the explicit representation in memory, so they are tagged by use.

So technically that’s the big difference between these representations. So we start from the BEAM format which we just translate to some representation of our own. Mostly because we want to be doing some optimizations there. Now, BEAM does some of its optimizations while it compiles, and then it does some very heavy optimization when it loads the file.

EI: Okay.

KS: So you see the BEAM loader it’s actually a Turing complete piece of software there. It does magic when it loads the file.

EI: Right. And, actually I saw a post by you on the Erlang questions forum where you  someone asked you about  because I was going to ask you about this – LLVM and is that kind of a future direction and then I saw you wrote a response to someone where you mentioned that the BEAM loader is doing quite a bit of magic and that affects the reasons why you would use a particular format or not. So are there sort of design decisions, with the overall Erlang platform that maybe for historical reasons make the job of the HiPE compiler much more difficult than for instance something like the Java JIT.

KS: Absolutely. Absolutely. So, there has been so Erlang file use certain properties in writing Erlang programs more than others. So, one of them is this ability to do change the code at any point. This basically means that it’s very difficult to do global optimizations. To do inter-module optimizations. Even across functions it’s pretty difficult to do this sort of thing because you need mechanism also to undo this optimizations if a new version of the module gets loaded which violates the assumption you had before.

EI: Wow. Okay.

KS: Okay, so you need this. It doesn’t mean it’s impossible. Just means that it’s very very difficult.

EI: Right and how much of that is related to the thing that you just said in terms of optimizations is related to the lack of a static type system per se or—

KS: It’s not so much the lack of the static type system is the ability to then load something which is completely different that what you had before.

Now, the—of course if we had the perfect type information, a very strict type system, we could take advantage of it. But actually I don’t think even in this case we would be very, very careful because you could always load a new version of the module that violated the assumptions when you made the optimization. So, they value this sort of thing much more than some possible performance improvement that you could get.

EI: Okay, yeah, that’s very interesting.

KS: Yes. So, I always thought it was a bit weird to be loading just one module at a time. And one of the things that I many times thought was the ability to declare a set of modules as an application and then do this whole code loading at the application level as opposed to at the just-one-module level.

And my understanding is that most projects out there actually do it this way. They don’t just update a single module, they update a set of modules. But, in the language, actually, you can just update a single module.

EI: Okay.

KS: I think it’s a remnant from the time where machines were slower and it took considerably longer to update a whole set of modules.

EI: I see, that makes sense. It’s more a historical artifact than it is—

KS: I think it is more historical artifact. If one designed a new Erlang right now, I think it would make more sense to declare— to have a way of declaring certain things as an application and then loading them all at the same time.

EI: Right. What else would you change if you were to build New Erlang today? Kind of keeping in mind the similar goals of the immutability and message passing and some of the robustness of Erlang. What would you change with those constraints?

KS: It’s a very interesting question. So, I think I’m a guy that likes to do small changes at a time, as opposed to doing grand changes to the language. One thing that I would definitely do is I would be more aggressive in taking out certain remnants of the past from Erlang which are ugly; You carry a lot of legacy code and just support weird constructs that were added to the language once-upon-a-time and by now there are better ways of doing these things. For example there is still support for calling tuples of pairs of module name and a function name and calling that sort of thing with some arguments. This is an remnant of the period before Funs existed in the language. It’s still supported.

EI: I see.

KS: There are some other examples I can give you where some things that were basically a mistake are still part of the language.

EI: Interesting. So you would get rid of the module-function-argument syntax and just pass functions, as one example.

KS: Actually, it’s not the M/F/A syntax. It’s the module-function which you can then use as a Fun. Very few programmers use this. But, it’s still part of the language.

EI: Right.

KS: This is just an example, of course, okay? There are other things that are remnants of the past and they they don’t — they’re not removed from the language due to backwards-compatibility arguments.

EI: Right. Related to that — and I ask this question often of people — what do you think about the record syntax and would you change that? Do you think it’s a problem in the language?

KS: I haven’t been bothered by the record syntax so much as other people. Basically because I’m using records in a very disciplined way. So, these days whenever I go to use a record for some data structure I try to create a abstract data type, a module, that basically has a, in the Java jargon, getters and setters. And these are the functions that get exported from the ADT module. I even declare these data type as opaque because there is a type syntax for doing that sort of thing. And then I have dialyzer check that I’m not violating the opacity of this term anywhere else. So, records are great if you use them in this way. They are pretty nasty if you try to mix tuples where you explicitly pattern match on the representation, or use element, which is really really bad.

EI: Right.

KS: That’s really the problem.

EI: Very interesting. So, how often do you use parameterized modules, and what do you think about those? And I actually specifically asking because one of my developers asked me, he said “oh you’re going to talk to Kostis, you should ask him about why dialyzer doesn’t support paramaterized modules.”

KS: Actually, I think this is wrong. Dialyzer supports paramaterized modules. So we have support on this since, oh, two years ago?

EI: Oh, interesting, ’cause he told me he had some problems recently using it, so I’ll have to ask him—

KS: Now, it’s conceivable that there are some problems. But, in principle there is support for this.

EI: Okay.

KS: Now, there might be some bugs, obviously we have not verified dialyzer, it’s a very complex program to do that sort of thing. But, if there are any issues I think he should just send a bug report. There is support for that sort of thing. Now, I think parameterized modules are an interesting addition. People especially coming from a more object-oriented background, they find them are more familiar to them, the whole idea is more familiar to them. Personally, I’ve not written anything that used paramaterized modules, ever. I didn’t really feel the need for it. But, I think it’s a bit of a chicken and egg problem. As long as there are not that many users the Erlang/OTP Team is not so keen in making this official and as long as it’s not official there’s very little incentive to change all that to understand parameterized modules, which makes them even less popular, and you see that this is a bit of a vicious circle.

EI: Yes, right.

KS: But I actually have no strong opinion either in favor or against them.

EI: I found often Erlang developers are quite opinionated about them and don’t like them, and it’s very interesting. Well, let’s talk really quickly about a couple of HiPE questions and I want to talk a bit about dialyzer a bit more, and then talk about your talk at Erlang Factory and then we will be done. With HiPe I was wondering if you could talk a bit about comparing it to the JVM, to the JIT in the JVM and I don’t know if you saw my question three here about sort of, you know, how it compares with regard to the idea that there are these thousands of man-hours going into the Java HotSpot VM. Do you have any thoughts on that and how HiPE compares and how it fits into the world of bytecode compilers?

KS: So. At the end of the day the only reason to do native code compilation is to get performance. So, the performance that HiPE gives you is not limited due to the fact that we’ve not spent thousands of man-years to do optimizations. But it’s constrained by certain decisions at the language level.

It’s also constrained by certain decisions that the HiPE compiler has done. In HiPE you can take a single function and compile only that to native code. Now, obviously there is very little that you can do in these situations since you do not have global information to do global optimizations. So it’s actually this problem that doesn’t give performance that is say, an order of magnitude better than the BEAM compiler. On the other hand I’ve not been impressed with the speed-ups that the JIT or HotSpot Java implementations achieved. My experience is that they typically get between three and four times speed-up over the JVM code. And, it’s about the same speed-up that one gets from HiPE. So, if I have to code a number — now obviously it depends on the application but we get something like two and a half to three and a half times better speed than BEAM and BEAM is actually very well-engineered. So, I don’t think that by going to something like the JVM that you get so much improvement in performance. So yes, it may be many many thousands of man-years there, but I don’t think they were very well spent. I think Erlang/OTP has achieved that with fewer man-years.

EI: Right. That’s very interesting. So what’s the future for HiPE? Is it kind of done? I know it’s not your focus now.

KS: The last five years it hasn't been my main focus. But the things are slightly changing. Perhaps I shouldn’t be announcing this right now, but I do have a project with two students of mine and a colleague to have an LLVM backend for HiPE. The compilation through LLVM. Now, it’s very early in the process to say anything more than that. But, we’ll see what speed-up we get.

EI: Oh, interesting.

KS: So I hope I will have something more complete to say on this, perhaps in the London Factory. It will be very early to say something about it in San Francisco.

EI: That’s very interesting. Yeah, I saw in that post that you mentioned you had a few students researching it but then it sounded like they didn’t have time before they had to move on.

KS: Yeah, but it was also two years ago and LLVM was not so mature back then. So understanding is that currently there is a lot of effort around LLVM. And, we’ll see how this turns out.

EI: So, let’s talk then quickly about dialyzer. Do you find people reacting negatively because it sort of bolts a type system on top of Erlang, or do you find people like it? What’s the feeling in the community about it?

KS: I think you should ask somebody else about the feeling of the community but I think…

EI: (laughs)

KS: —because I’m obviously biased here. But I think dialyzer is an extremely cool idea. I’m obviously biased, I have to say this, but personally I do not see and disadvantage whatsoever in dialyzer.

Because, it’s actually not right that it imposes a type system on top of a language. On the contrary, dialyzer can be used without any type annotations whatsoever. So you can use dialyzer with your program as you wrote it, without a single type declaration or a single spec, and it will find bugs in your program just by typing dialyzer and giving it filenames afterwards. So I don’t really see any reason not to use it. Now, if you want to get the most out of dialyzer then you will have to supply some information, but you can supply as much information as you want or feel like. My personal view is that the types are very good for documentation purposes. So, I think there is an advantage in using types for catching some programming errors. What most people don’t realize is that you need a different type system for doing optimizations and for catching programming errors, and Dialyzer has taken the approach of using a type system only to catch programming errors. So the types that you can write are very very relaxed. Actually they are types that you cannot write in any other statically typed language that I know. You cannot say that something has a type of “any” in most other languages. So—

EI: Hmm, interesting. So it’s different than saying a type like a variant or Objective-C id. It’s essentially saying it can truly be any type.

KS: Yes, it can truly be any type. Or you can have arbitrary unions. You can mix without using any constructors. You can mix integers and floats. Integers and lists. Anything basically. So—

EI: That’s a good point. That’s quite different than any other types system I’ve ever used.

KS: It’s very very different than any other type system out there. And it’s actually something that I’ve not seen—the approach is something that I’ve not seen anywhere else. So it’s fundamentally a different approach than anything that has been tried out there for adding types to a dynamically typed language.

EI: Can you quickly explain for a non-academic what “success type” is and how that’s different than a normal type in another system?

KS: So, success typings try to approximate the set of values for which a function will return something; will not throw an exception.

EI: I see. Okay. That makes sense.

KS: So, they are trying to find—So, in typical type systems—Sorry I’m a bit slow here because I try to seek how to say it without being too technical.

EI: It’s mainly that I think this is really interesting because there’s not a lot of explanation of this out on the Web, so feel free to kind of say it in more technical terms.

KS: So the typical type systems want to guarantee type safety. Okay? Which means that they artificially restrict the users of functions in order to guarantee type safety. Now, Erlang is a dynamically typed language, alright, but it’s also a type-safe language. The only thing that can go wrong is that you get an exception during runtime. You are not going to get a segmentation fault because of using a wrong type. Okay? So, success typings try to find all information they can find about when a function will not throw an exception. That’s where the “success” comes from. When it will return, it will succeed in its evaluation.

EI: Okay. Perfect. Yeah, that’s helpful, and I saw at least a couple references to your paper —you wrote a paper on that, I guess, on success types. [ed - "Practical Type Inference Based on Success Typings"] and it’s on my reading list here. Where do you think dialyzer is headed? Is there any future development happening there?

KS: Oh, there is a LOT of development happening there. So, we have added some components recently to detect also concurrency errors that might exist. So there is already something in the distribution that detects race conditions you may have in Erlang. And we have another analysis that finds message passing errors, in applications. But one of the nice things about success typings is that you can make them stronger and stronger and stronger in each pass and you will see that dialyzer detects more and more errors as you are using a newer OTP version. We can do that sort of thing because we can improve on the inference, we can make it more fine-grained. So we have already some future additions that detects some really really interesting errors.

You will see this in I think a year.

EI: So it sounds like you’re working on things that won’t go into production use for quite a long time?

KS: One of the reasons for this sort of thing is that we are very conservative; so we want to guarantee that Dialyzer is never wrong; that it does not produce any false positives. So we thoroughly test every release. Also, we would like to, before we announce, before we put something in the OTP distribution, we want to eliminate all errors of that sort that exist in OTP itself. And that takes a bit of time.

EI: I see. That makes sense. So, some sort of “dog-fooding” the product before it goes out.

KS: Yes

EI: That makes sense. So, anything else you want to cover on Dialyzer or HiPE?

KS: There have been a lot of positive stories about Dialyzer users. I got a very very nice mail quite recently from a guy that I have a lot of respect for his programming ability. He’s working a company – I will not even mention the company. They have been using older OTP version recently and they switched to R14 just a month ago. And, he gave Dialyzer a run on his codebase. His codebase was around 50,000 lines of code and he was very positively surprised about the things that Dialyzer discovered. So, I think there is very little reason not to use Dialyzer these days, because it takes absolutely no effort from the programmer.

It takes effort to correct the results!

EI: That’s the thing! When we first ran Dialyzer on our product we were about to release, we found a lot of issues. So, we’ve had a lot of good results with it. Any thoughts on Reia or Effene or Lisp-Flavored-Erlang?

KS: I haven’t had the time to seriously look into them. I think science is (and this is not my quote but I will use it anyway) I think science — and you can extend that to programming—is like sex. It might have some practical consequences but that’s not the reason why we do it. Okay, so as long as these people have fun in developing these things, I think it’s great. So, they are interesting efforts and I think that the community should look into them. Now, my view is that not all of them will obviously survive, or they will be come so interesting that many people will be using them. But, it’s nice to be having a lot of other developers using Erlang as a target language.

EI: Right.

KS: Now, I would have liked to see some communities around these efforts and not being a single man’s project. But I guess people are just busy doing things, not only for fun but for money. The Erlang programming community is, these days, very successful in writing real applications, and they only do things like LISP-flavored Erlang or Reia

EI: Yes, exactly, it’s a hobby.

KS: It’s a hobby.

EI: As a final question, I thought it was kind of funny that in last year’s Erlang Factory, Joe Armstrong said he doesn’t, he’s never, used the Erlang debugger. And, it made me think –

KS: So actually, I’m in the same category. I’ve never used the Erlang debugger. I don’t know how to use the Erlang debugger. I really do not—I’ve never used this. I never felt the need in a language like Erlang, where the exceptions you get are so detailed you use anything but io:format for debugging.

EI: Interesting.

KS: Some of my students have used the debugger and they say it’s great. I’ve never used it. It’s amazing. So, although I don’t always agree with Joe, we are in the same team there.

EI: Okay. It feels like I should write an article called, “Erlang legends who have never used the debugger”. Or perhaps a comparison of major languages and whether or not you need to use the debugger to write in them. So, I guess related to that then, is there a tool that you think people should be using, other than Dialyzer, that they aren’t using right now?

KS: So, that’s exactly what my talk was going to be about.

EI: Okay! Well, you don’t have to reveal your whole talk but—

KS: No, I will not reveal my whole talk, definitely not. But I think that the era where one fired up an editor and then wrote a program, used a compiler to compile this program, and wrote some unit tests for this, is long gone. So, one needs more modern tools for development of programs. And a big part of my effort over the last seven or eight years has been to develop such tools. Dialyzer is one of these tools. I’m going to talk about half a dozen tools there, and there are some other tools that are in the pipe-line. Some of them are known to some parts of the community, some other ones will be revealed at the San Francisco Erlang Factory. I will not say more.

EI: Well that’s a good way to end the interview. I appreciate your taking the time, and I’m hoping to make it to San Francisco, so we’ll see.

KS: It’s actually going to be my first time in the Erlang Factory San Francisco. I’ve been to the London. And I think it’s great because it’s going to be many more Americans than Europeans there. It’s in Silicon Valley and it will be very nice to see the interest that exists around Erlang in the Silicon Valley community. So I’m really really looking forward to that trip. It so happens that these days I’m doing a lot of traveling, and especially my March schedule is a mess. But, I’m really really looking forward to going and spending as many days as I can in the Erlang Factory and in the University in San Francisco. I think it will be a very great event.

EI: Well, last year it was amazing so I’m looking forward to it. Well, thanks a lot Kostis.

KS: Okay. Sounds good.

Leave a comment