Expression Trees in Go?

978 views
Skip to first unread message

Igor Gatis

unread,
May 10, 2014, 10:23:18 PM5/10/14
to golang-nuts
TL;DR: will Go ever have support for "code as data" such as C# has with Expression Trees?

C# has this really nice feature called Expression Trees. Basically you can write code and it becomes available as data (in the form of an expression tree). Here is an example of expression trees using lambda:

class Foo {
  public string Name;
  public int Age;
}

Expression<Func<Foo, bool>> exp = foo => foo.Name != null && foo.Age > 21;

(for those unfamiliar with C# lambda, the above syntax creates a function which receives foo of type Foo and evaluates into a bool).

C# compiler will compile the code above doing all type checking but instead of generating actual binary, it will translate that expression into an object that represents the code. One can later navigate through that code translating it into, say, SQL:

... WHERE Name IS NOT NULL AND Age > 21

AFAIK, no other language has such feature. I wonder whether Go has any plans into that direction.

David Crawshaw

unread,
May 11, 2014, 10:27:56 AM5/11/14
to Igor Gatis, golang-nuts
Something very similar could be built as a library using the reflect package.


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

egon

unread,
May 11, 2014, 10:34:36 AM5/11/14
to golan...@googlegroups.com
Lisp comes to mind. Depending what is the end representation, you can get the source for a function in javascript as well (function(){ return "hello" }).toString().
 
I wonder whether Go has any plans into that direction. 

I doubt it will be added. There are too many different ways to extend a language and it's a major overhead needing to support all of them.

What do you actually want to accomplish? The "Expression Tree" is just one solution for some set of problems... there are always other solutions to problems.

+ egon

Konstantin Khomoutov

unread,
May 11, 2014, 12:46:56 PM5/11/14
to egon, golan...@googlegroups.com
On Sun, 11 May 2014 07:34:36 -0700 (PDT)
egon <egon...@gmail.com> wrote:

[...]
> > class Foo {
> > public string Name;
> > public int Age;
> > }
> >
> > Expression<Func<Foo, bool>> exp = foo => foo.Name != null &&
> > foo.Age > 21;
> >
> > (for those unfamiliar with C# lambda, the above syntax creates a
> > function which receives foo of type Foo and evaluates into a bool).
> >
> > C# compiler will compile the code above doing all type checking but
> > instead of generating actual binary, it will translate that
> > expression into an object that represents the code. One can later
> > navigate through that code translating it into, say, SQL:
> >
> > ... WHERE Name IS NOT NULL AND Age > 21
[...]
> What do you actually want to accomplish? The "Expression Tree" is
> just one solution for some set of problems... there are always other
> solutions to problems.

LINQ <http://msdn.microsoft.com/en-us/library/bb397926>

Konstantin Khomoutov

unread,
May 11, 2014, 1:19:33 PM5/11/14
to Igor Gatis, golang-nuts
On Sat, 10 May 2014 23:23:18 -0300
Igor Gatis <igor...@gmail.com> wrote:

> TL;DR: will Go ever have support for "code as data" such as C# has
> with Expression Trees?
[...]

Not on this level, but Go implements a Go parser in its own standard
library, and the packages comprising this support are modular [1],
including specific support for abstract syntax trees of Go programs
(see `go/ast`).

This gets you quite closer to LINQ -- if you are okay with playing by
Go's rules (note that Go is way more low-level than C#). You won't
have direct (compiler-level) support for turning a function (anonymous
or otherwise) into an expression tree but I can imagine at least two
ways to use this functionality:

* You can parse a user-supplied text into a syntax tree at runtime
and then feed the resulting AST into a specific driver which will
further transform it to match its respective data model or
use the AST directly (by using an evaluator).

* Employ "bootstrapping" where you implement a pre-compilation step
which takes some input and produces a file or a set of files with
Go code (or several versions of it -- for instance, targetting
different data access backends) which are then compiled normally.
Such a bootstrapping program is usually executed by calling `go run`
on it, which compiles the program, executes it and then throws it
away.

1. http://golang.org/pkg/go/

egon

unread,
May 11, 2014, 2:19:00 PM5/11/14
to golan...@googlegroups.com, egon
LINQ is also a solution, not a problem.

As an example "How can I do type-safe queries?" would be an engineering problem. A problem "How do I ensure that queries don't crash the system?" would be closer to a business problem. The business problems are usually the important parts in a system, how you exactly solve them,, less so. Starting with the business problem means you have a much wider range of possible solutions.

+ egon


Igor Gatis

unread,
May 25, 2014, 10:17:45 PM5/25/14
to golan...@googlegroups.com
I found another great use for code as data: bigdata processing. One could write code in go, serialize it, send it to a bunch of worker machines, deserialize and execute it.

This is what Apache Spark [1] delivers. It I like mapreduce but more lightweight, higher level and faster (and I guess at some reliability cost). Spark programs are required to be in written in Scala. There is also a Python version of Spark called Dpark [2].

It would be great to have Gopark. :)

1. http://spark.apache.org
2. https://github.com/douban/dpark

Igor Gatis

unread,
May 25, 2014, 10:21:58 PM5/25/14
to golan...@googlegroups.com
GoPark [3] is a toy but would become a really nice piece of software if go had support for code serialization.

3. https://github.com/mijia/gopark

Tamás Gulácsi

unread,
May 26, 2014, 12:59:35 AM5/26/14
to golan...@googlegroups.com
You can serialize code by serializing the AST of go/ast.
But you cannot deserialize into runnable (ok, an interpreter exist, but that's slow) code.

But the easiest serialization is source code - you only have to compile it.
You even could cross-compile on the master and distribute the binaries, if the nodes don't have go installed.

Reply all
Reply to author
Forward
0 new messages