I also looked into genetic algorithms / genetic programming back in the late 90's / early 2000s. It's not hard to come up with a language where every statement is syntactically valid (i.e. it does something, which may or not be what you want) and a fitness function (a way to evaluate a program to determine if it's closer or further away from a desired solution than other instances of a program).
LISP is good because a list can also be a program. Create a million lists at random, execute them all with your dataset, pick the best 50% or so, making sure that the fitness function also has a component that selects smaller programs over larger programs. Then cross-breed the programs (exchange parts of successful lists with parts of other successful lists). That's one iteration. Do a few million iterations and eventually you've got a program that does something like what you want.
The problems: it takes a LONG time to evaluate all the programs, and you might have to have some sort of timeout criterion to prevent endless loops. It takes a LONG time to do all the iterations you need to satisfy your fitness function. Once you've satisfied your fitness function enough, you have something that works for your test dataset - that might not handle all the data you throw at it. The more complicated a thing you want, the longer it will take. Not all problems can be solved with GP: you need a problem that lets you know when you're getting closer to a solution.
See it in action here:
http://alphard.ethz.ch/gerber/approx/default.html
(needs Java)