Hacker News new | past | comments | ask | show | jobs | submit login

I can't help but feel like the Roc team has an attitude of "imperative programming for me, but not for thee".

And now they are doubling down on that by moving from "OCaml meets C++" to "C, the good parts"!

If FP isn't good for writing a compiler, what is it good for?






Roc couldn't be optimized for writing the Roc compiler without sacrificing some of its own goals. For example, Roc is completely memory-safe, but the compiler needs to do memory-unsafe things. Introducing memory-unsafety into Roc would just make it worse. Roc has excellent performance, but it will never be as fast as a systems language that allows you to do manual memory management. This is by design and is what you want for the vast majority of applications.

There are a number of new imperative features that have been (or will be) added to the language that capture a lot of the convenience of imperative languages without losing functional guarantees. Richard gave a talk about it here: https://youtu.be/42TUAKhzlRI?feature=shared.


It still feels kinda weird. Parsers, compilers etc are traditionally considered one of the "natural" applications for functional programming languages.

There are plenty of compilers written in memory safe languages, including the list of self hosted ones linked from the gist describing the rewrite.

>but the compiler needs to do memory-unsafe things

sorry, but why?


I am also skeptical.

A compiler is a function from source code strings to binary bytes. Writing out instructions to do memory-unsafe things is not in itself a memory-unsafe activity.


I believe the main reason is for achieving the best possible performance. Someone closer to the compiler could give more detail.

It's not just the lang but the std lib too

https://www.roc-lang.org/faq#rust-and-zig


> If FP isn't good for writing a compiler, what is it good for?

Summing the Fibonacci sequence I guess.


FP is bad for computing the Fibonacci series unless you have the compiler optimization to turn it into a loop (as seen in imperative languages).

To be fair, most practical FP languages have that, but I never saw the appeal for a strictly functional general purpose language. The situations where I wished one could not use imperative constructs are very domain specific.


other FP languages bootstrapped onto themselves IIRC

According to [1], they want to use a systems-level language for performance.

[1] https://www.roc-lang.org/faq#self-hosted-compiler


"The split of Rust for the compiler and Zig for the standard library has worked well so far, and there are no plans to change it."

I assume that statement will need updating.


At this point it feel like the are just playing with languages.

I mean, the language doesn't even have a version number yet. We should expect them to still be exploring the design space.

"Unix system programming in OCaml"

https://ocaml.github.io/ocamlunix/ocamlunix.html


That's an interesting point, and something I thought of when reading the parser combinator vs. recursive descent point

Around 2014, I did some experiments with OCaml, and liked it very much

Then I went to do lexing and parsing in OCaml, and my experience was that Python/C++ are actually better for that.

Lexing and parsing are inherently stateful, it's natural to express those algorithms imperatively. I never found parser combinators compelling, and I don't think there are many big / "real" language implementations that uses them, if any. They are probably OK for small languages and DSLs

I use regular expressions as much as possible, so it's more declarative/functional. But you still need imperative logic around them IME [1], even in the lexer, and also in the parser.

---

So yeah I think that functional languages ARE good for writing or at least prototyping compilers -- there are a lots of examples I've seen, and sometimes I'm jealous of the expressiveness

But as far as writing lexers and parsers, they don't seem like an improvement, and are probably a little worse

[1] e.g. lexer modes - https://www.oilshell.org/blog/2017/12/17.html


OCaml allows mutation via reference cells.

I know that, and obviously you can write a recursive descent parser in OCaml

But I'm saying there's nothing better about it than doing it in OCaml vs. C++ or Python -- it's the same or a little worse

IMW it's natural to express the interface to a lexer and parser as classes -- e.g. you peek(), eat(), lookahead(), etc.

Classes being things that control mutation

But objects in OCaml seem to be a little separate dialect: https://dev.realworldocaml.org/objects.html

When I debug a parser, I just printf the state too, and that is a little more awkward in OCaml as well. You can certainly argue it's not worse, but I have never seen anyone argue it's better.

---

Culturally, I see a lot of discussions like this, which don't really seem focused on helping people finish their parsers:

https://discuss.ocaml.org/t/why-a-handwritten-parser/7282/7

https://discuss.ocaml.org/t/good-example-of-handwritten-lexe...

I also use lexer/parser generators, and I like that there are more tools/choices available in C/Python than in OCaml.


Huh? The whole point of Roc is to let you easily put both imperative and functional code in the same project through Roc's platform system.

You get to decide what part of your code should be imperative, and which should be functional.



So why is it a non-goal of Roc to be implemented with this approach?

Have you not read the post? Because compile times. Rust has awful compile times. If it didn't, I'm sure the Roc team would have stayed with Rust.

Yes, I read the post.

I don't understand why the goal is not to (eventually) implement Roc in Roc, maybe with a dash of something else for the "platform".

Roc is pitched as a general purpose functional programming language with great performance.

How does a compiler not fall under this category?


Roc is pitched as having great performance for a GC'd language, that is, on par with Java, Go, C# instead of Ruby, Python, JS. The Roc compiler team are looking for C, C++, Rust, Zig kind of performance. Roc will, by design, never reach that kind of speed.

Go's compiler is written in Go, and is known to compile very quickly. I'm not sure I understand why Roc needs to be even faster than that?

We already have many great GC'd functional languages at that performance level.

I first learned about Roc from this talk:

https://www.youtube.com/watch?v=vzfy4EKwG_Y

That's a niche that is not currently filled (well, maybe MLTon) and that has me very excited! I'm sure I'm not alone here.


As an FP fan, I agree. This is disappointing.



Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: