Hacker News new | ask | show | jobs
by evincarofautumn 5084 days ago
C++ is a powerful language, but with awful syntax and semantics that can discourage experimentation. Since I started using Haskell just over a year ago, my C++ code is much improved—because I can figure things out quickly in Haskell, then translate them to (somewhat write-only) C++. That I think is a large part of what people mean when they say “Haskell makes me a better programmer”. Not only is it a good language in its own right, but it also helps you prototype software that you need to implement in another language for reasons other than language power.
2 comments

"C++ is a powerful language, but with awful syntax and semantics that can discourage experimentation."

Then you should try out D. Bartosz Milewski in fact has been involved in D development for a long time. It certainly makes it easier to apply a lot of the FP techniques.

I have experimented a little bit with D, and really like some of the things in the standard library, but Haskell is already serving as my replacement for C++. D is a viable alternative to C++ for most purposes, though.

I’m actually working on a compiler for a high-performance functional language, to serve in those cases when I would want to go back to C++…

I'm working on-and-off on something similar, would you excuse a few questions?

Is it statically typed? Do you have ADT support and/or an object system? GC / refcounting or manual memory management?

How are you implementing bind() and currying in a compiler? I'm targeting x86 and my approach is to make little stubs on the heap that push a single parameter, then i can throw them around as ordinary function pointers (lambda lifting every single parameter rather than looking up things through environment pointers at runtime). The problem with this is that i end up with a huge amount of small fixed-size objects on the heap, which is a little less than ideal but at least i can write a special allocator for that case.

EDIT: Upon a little background reading (and your illuminating february blog post on concatenative languages) i realise you're probably referring to Kitten, in which case i'm not sure any of my current questions are remotely applicable.

I am moving from dynamic to static typing. Unfortunately the `compose` primitive has a rank-2 type in the general case, so you need explicit type annotations for many higher-order functions. I am supporting ADTs, which are basically identical to quotations under the hood. There will be an object system in the standard library once I figure out a good object model. Memory management is done through plain old refcounting. Some programs may benefit from waiting for the next push before deallocating popped values, but I have yet to profile to find out.

As you may have realised, currying doesn’t really apply to concatenative languages because they lack application. The analogue of partial application is deferred composition, i.e., just concatenating quotations:

    [1] [+] compose  [1 +]  =
I’ve been working on the language actively, but haven’t pushed code lately. Do watch the repo[1] if you’re interested, though, and link me to yours. I also think I know you from #esoteric or something? My memory sucks and I haven’t been on there lately.

[1] https://github.com/evincarofautumn/kitten

You had me until "somewhat write-only." Sounds like you are poisoning your code-base with square functional pegs in round C++ holes...
Hardly. Given a choice between complex imperative code and complex functional code, I’ll take the latter. It’s just that the resultant C++ is somewhat brittle and not as thoroughly verified as the Haskell version. I would say the same thing if I wrote something in Coq, proved it correct, then ported it to Haskell.