Hacker News new | past | comments | ask | show | jobs | submit login
Functional Go Programming Language (github.com/eobrain)
89 points by psibi on July 10, 2014 | hide | past | favorite | 35 comments



>Why a new language? The goal of Funcgo is to combine the readability of the Go language with the semantics of Clojure [...] Clojure is difficult to read for programmers unfamiliar with Lisp syntax.

So funcgo is really just Lisp without parentheses... again.


Yep, fundamentally Funcgo is just Lisp without parentheses. Or put it another way, it is Lisp with more syntax. The fact that Lisp has so little syntax is beautifully elegant from a mathematical point of view, but that is I believe at the expense of readability, at least for programmers coming from other programming traditions. Of course readability is somewhat subjective and I understand that for long-time Lisp programmers, Lisp is perfectly readable.


Compared to code that's very regular, like say Java, Lisp might be less readable, but IMHO Lisp is in general more readable than other languages as soon as your code is more than a sequence of simple non-nested assignment and method calls.

Nested function calls in Java have more punctuation than nested calls in Lisp, and the Lisp ones are generally better indented and thus more readable. It doesn't help that even after 10 years, Eclipse indentation is still absolute crap (aligning method arguments, anyone?), while Emacs got it right back in 2000 (or way before).


How does it compare to Dylan, which seemed to be very much the same approach?


Personally I find the name misleading. Something like 'Jo' makes more sense to me (not that I'm advocating it as a pretty name).


how about Gojure


"Jo" seems it is hard to search for. "Gojure" is already taken by another Github project.

I also considered "Clogure", but someone already had that too.

Keep the suggestions coming!


If I remember correctly, the "C", "L" and "J" in "clojure" stand for "C#", "Lisp", and "Java", respectively; since Clojure is a Lisp that runs on either the C# (.NET) or Java runtimes.

So maybe a good name would be replacing the "c" with "g": Glojure. Doesn't seem to be taken by any other project, and it has the potential for some nice "glow" logos.


I like Glojure. I am not sure if it is worth the hassle of changing the name, but I registered glojure.org just in case I decide to do so.


Folang?


Glad to see a language taking inspiration from go. Are other targets (ie a cpython style native interpreter) being considered?

I'd love to see a scripting language with go's type system (and concise syntax for declaration, type inference and built in collections) but support for operator overloading and the ability to link in external shared libraries. Basically I want python+numpy (ie external C/fortran numerical code wrapped with pretty operator overloading and a repl) but with go style syntax and pointers.


There's a wealth of numerical code in C++. Calling into C is pretty straightforward, but with C++ it's a complicated choice between Swig, sip, shiboken, BoostPython, ..., or hand-writing your language bindings to C++ code in extern "C".

I'd like it if it also made it easy to tap into C++. It's probably a very complicated problem, which is why it's unsolved.


Funcgo can readily call Java code, so it supports numerical programming or linking in C++ code to the same extent that Java does.


I've no immediate plans for another target for now – there is a lot of work still to do just targeting Clojure and making sure the toolchain is easy for programmers, both server-side and client side. As regards typing, Funcgo has type inference using Clojure's type-hinting and it can use all of Clojures immutable collections as well as the standard Java mutable collections. As for operator overloading, it's not there yet, but I just I added a user story (https://github.com/eobrain/funcgo/issues/18) to my backlog to allow function names to be operators (like in Scala). However it won't really be operator overloading because the underlying Clojure only allows overloading by arity, not by type.


Very cool and thanks for the response! I'll need to experiment with this + a clojure matrix math library at some point.

I'm new to the clojure ecosystem but it looks like https://github.com/mikera/core.matrix could be worth trying.


Update: The new 0.4.0 release of Funcgo supports limited operator overloading: https://github.com/eobrain/funcgo/blob/master/doc/reference....


I've toyed with this idea a bit (compiling a more familiar language down to Clojure).

This project in particular gives some of the benefits of Clojure (JVM, expressive language, immutability), but I don't see any easy way to add new constructs to the language like macros without modifying the compiler itself. Can you modify the grammar that is fed to Instaparse at runtime?

That being said, the current branding and name confused me initially. I was expecting a full Go to Clojure compiler, but it appears that this is mainly a language that has similar syntax to Go which compiles to Clojure, which is still very cool, just different.


I do not plan to add to Funcgo the ability to easily create macros. Inspired by Go's philosophy, I want to limit the scope of the language to keep it somewhat simple. Funcgo however can use macros, so a sufficiently motivated programmer can write macros in Clojure and use them in Funcgo.

Thanks for the feedback on the impression the name and branding gave. I'll try to change the main pages to make clear that Funcgo is not full Go, and is a fairly thin layer on top of Clojure.


> a sufficiently motivated programmer can write macros in Clojure and use them in Funcgo

The Clojure "syntax" is best for writing macros, whereas the Funcgo syntax is best for writing, and later easily reading, other code. There's nothing wrong with writing code in two languages, one at a higher level up the abstraction stack than the other.

I tried putting such a C/C++/Java/C#/JS/Scala/Groovy/Go/etc-like syntax atop Clojure last year (called "Grojure"). After many iterations, I found each iteration became thinner and thinner, and the functionality more and more aligned with Clojure's. I didn't publish my last attempt because it had evolved into a much simpler 3-step application:

1. lex the tokens, which had different syntax to their equivalents in Clojure

2. define the prefix and infix operators, in their precedence hierarchy, including syntax for function calls

3. define the syntax for the statements, which mapped almost directly to macros which did the processing

The macro linking all three steps together fed the output from step 3 into step 1 to enable interpolated strings. The operators in effect were defined by an enveloping statement, and could be changed in the syntax. If I'd tried another iteration of Grojure, I would have probably merged that step into the 3rd, and used your incanter/infix macro to process them, reducing it all to two steps. And perhaps some of the lexing of step 1 could have been replaced by the Clojure 1.4 tagged elements.

Despite going through all this, I'm still left with a sense of how unnatural it is to read S-expressions whenever I see Clojure or Lisp code, and think the two syntaxes idea (lisp for macros, C/Go for the rest) could be the solution.

But there was one possible snag specific to my/your situation I came across. Grojure, like FuncGo, is atop 2 or 3 other languages:

* Grojure/FuncGo sits atop...

* Clojure, which sits atop...

* Java/the JVM, which is written in, and using JNI can call software written in, ...

* C and/or C++.

I had the idea of only enabling my equivalent of FuncGo to access one layer only below. So one would need to use Clojure to write not only the macros, but also functions to wrap all Java/JVM functionality required at the Grojure/FuncGo layer. I never got around to implementing that because in the end I decided 3 layers was a layer too many. Hope you work your way around this issue.


Glad to hear someone else has been thinking about this.

Interesting idea to use macros to implement the mapping from the Go syntax tree. Presumably, these macros would implement the same kind of logic that my codegen module implements (mapping from the Go syntax tree to Clojure text). https://github.com/eobrain/funcgo/blob/master/src/funcgo/cod...


What do macros have to do with being functional? It might be better for a functional language to have that, but it doesn't have to have such a facility.


Macros have nothing to do with being functional, but macros are one of the major advantages of Clojure, and ideally there would be similar functionality in a language based on it (though not necessary).


Funcgo author here. Thanks for all the interest and comments. I'll respond individually to the comments.


Thanks all. I created a new FAQ page for Funcgo, seeded with the questions and answers from this forum. https://github.com/eobrain/funcgo/blob/master/doc/FAQ.md


Maybe it would be cool to improve upon flex/bison/jison and make it easier for everyone to create or modify the programming language of their choice with platform plugins that let people connect their own programming language to the platform of their choice (JVM, .Net, straight up compiled into a binary). I'm really mostly thinking about syntax of the language really, but you could go further and customize the typing system and how scopes work and go all the way down the rabbit hole as much as you want. As long as the underlying base system is there, and it runs on the things you want it to run on, it would be fine.

Basically: Custom language -> some intermediary form which would probably end up having some restrictions on language design -> to the thing you want it to run on.


make it easier for everyone to create or modify the programming language of their choice with platform plugins that let people connect their own programming language to the platform of their choice

Clojure is specifically designed to be "hosted" on another programming language. Also, it has facilities that let you create your own control structures and otherwise make it easy to create a DSL. (Domain Specific Language)

This basically gives you: Custom language -> some intermediary form which would probably end up having some restrictions on language design -> to the thing you want it to run on.


I cannot say enough good things about Instaparse, which is a flex/bison/jison for Clojure. It's amazingly feature-full and very fast. I could not have built Funcgo without it. Big kudos to Mark Engelberg.


So, javascript?

Scala has been ported to javascript so I think that basically implies most of the languages targeting the JVM could also be.


well, the JVM is used in that way. So is the CLR in .Net.

But it sounds like you're implying another level of abstraction / interface that would be shared between the CLR and JVM etc.


Frankly, IMHO this combines the worst of two worlds: go's non-lispy syntax and clojure's ... dilatoriness/slowness & fragility of its tooling. I'd much prefer a clojure (or rather scheme) that compiles to go.


Interesting work. One question: How does the user keeps track of the source location (source map)?


I have plans to implement source maps https://github.com/eobrain/funcgo/issues/19 when targeting JavaScript

I have not yet figured out the best way to do something equivalent when targeting the JVM.

This is one of several toolchain issues. In addition to stabilizing the language itself, getting a smooth toolchain is the biggest thing left to do before a 1.0 release of Funcgo.

(Though it is worth noting that Coffeescript, an analogous language, got widespread adoption before tackling the source location issue.)


Go is targeted for developers happy with boring imperative programming and the team does not seem to be willing to add the required support to do otherwise.

Personall I rather use a proper multi-paradigm language instead of bandaid tools.

Congratualtions on the work, though.


Funny, I find functional programming to be boring and full of lots of constraints to keep you from blowing off your foot, whereas imperative programming is exciting yet dangerous.


They missed a trick calling it 'funcgo' instead of 'gofunc'; just think of the tag line:

    gofunc yourself




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

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

Search: