Show HN: Fo: An experimental language which adds generics on top of Go

  • I liked certain aspects of Go, but lack of generics was a deal-breaker for me. You approached it a way better than I (and many others) did. Instead of arguing on forums you started writing code.

  • For generics:

    How do recursive types and self-referencing types work? What about generic types that themselves require generic types? Can type constraints be applied? What do generics look like on interfaces? How about in slices? When compiled, are specialized functions written or is the code shared? How is runtime reflection for type params implemented?

    Also, oblig ref of a now-defunct lang on top of Go: https://oden-lang.github.io/

    Finally, good work, I hope it was fun! Don't take criticisms too seriously, they are good things (as opposed to silence) and par for the course on this site.

  • Author here. I've been working on Fo part time for 4 months. Feel free to ask me anything.

  • Nice work. But, serious question - When going with parameterized types I know from Haskell how you always end up needing one more language extension and always end up banging your head against the wall that separates types and values a little more. At least if you're not a math genius, but probably even then.

    And from Java I know that there's a pretty trivial example that showcases how its Generics implementation is unsound when mixed with inheritance.

    And I know that the Go maintainers have been hesitant for a long time because they didn't know a good version of Generics to add.

    So, is there any version that just works, and never leads the user down any rabbit holes? And that doesn't lead to ever increasing type boilerplate?

    Because I've been super happy ever since I decided that worrying about occasional usage of void pointers in C is just not worth my time. And where configurability is really needed, function pointers are totally fine - I don't think there is any need for static polymorphic dispatch (function pointers are probably even preferable, to avoid bloated machine code).

  • The only time I find I need generics is when I'm prototyping things and making lots of changes. Node, Ruby, & Python are great for this. In fact, PHP's associative array is really powerful/sloppy since it can be used as a list, hash/dictionary, iterable, or object.

    That aside, I don't think I've ever really been bothered by the lack of generics for actual work code.

  • Has anyone worked on Lisp-like macros in Go? Executing code at compile time to emit AST and compile it.. That is what I feel is really missing. Even with strictly a compile-time phase (no run-time macro evaluation) it could be quite useful.

    Starting with generics seem to lead down the dark path of C++ template metaprogramming..

    I would rather do something like

    type StrBox = MakeBoxType!(string)

    ...and have clean hygienic macros to generate my "generic". Syntax candy can be added to that to get generics...but starting with generics and only supporting that went really really badly for the C++ ecosystem.

  • This is suuuper cool. I've thought of doing something similar for a while, but I tried approaching it from the "generate Go" angle. I also found the Go syntax too tedious to write a parser for (because I've never written a parser before, nor any kind of compiler, so the learning curve was too steep). So I was just going to try to build a simple, expression-based language that compiled to (and interoped with) Go. Unfortunately, I ran out of steam because the learning curve was so steep.

  • You really missed the opportunity here to call your language Foo

  • C++ style (compiler) or Java style (boxing) implementation?

  • Is there any support for bounded type variables? Or plans to add them?

  • Should be called mofo.

  • Nice work!

  • Interesting, now all you need to do is add exceptions :)

  • Shouldn't it have been called Ho ?