It depends.
Currently, it generates JVM bytecode for the JVM backend (which gets translated into Dalvik bytecode when targetting Android).
For the scripting languages that are to be introduced for v0.6, it will generate source-code.
In theory, it can. In practice, it won't.
Here's the deal: currently, Lux will only target languages which have some form of runtime compilation & loading/execution of code.
What do I mean?
Well, in JavaScript, I could potentially generate a string of JavaScript code, and then call the
eval function.
eval would simultaneously compile down my string, and then execute it.
Lux would need the same capability of every language it plans to target.
Most scripting languages offer that, because they have an
eval function, or an analogue for it.
In the case of the JVM, you can load arbitrary bytecode at runtime through the ClassLoader mechanism, so you just need to take care of knowing how to generate the bytecode itself, and then you're all set.
However, there has to be some mechanism to execute whatever you generated (be it bytecode or source-code).
This is necessary because of the way macro-expansion works, and me wanting to avoid the problem ClojureScript has had since it was introduced, where you can't write macros in ClojureScript because it has no way to execute the JS it produces, so it can't do CLJS-based macro-expansion, and must instead outsource its macros to Clojure.
For the JVM it's easy. If you've already got a blob of bytecode in your hands, you can just hand it over to the JVM and it will know how to execute it.
For other languages, it's not so simple.
The support for other languages has been added on top of the JVM-based compiler (the new one, which has been re-written in Lux).
That means that those languages must somehow be able to run on top of the JVM.
Lux currently achieves that by using a variety of open-source projects that implement interpreters for those languages, and using them as execution environments for the source-code it generates during compilation (Nashorn for JavaScript, Rembulan for Lua, Jython for Pyhon 2.x, JRuby for Ruby, Renjin for R, ABCL for Common Lisp, Kawa for Scheme and JPHP for PHP 5.x).
In the future, the plan is to compile the compiler itself into those target languages, in order to run the compiler in those platforms and stop relying on any JVM-based interpreters. But that is going to be work for v0.8, in the later half of this year.
To put things into perspective, there is an Erlang interpreter for the JVM called Erjang, which I wanted to use to port Lux into Erlang (a task I ultimately decided against, for reasons I won't get into right now).
Erjang takes BEAM bytecode, instead of Erlang source-code; so, if I had made the Erlang port anyway, Lux would have produced bytecode instead of source-code for Erlang.
So, ultimately, producing bytecode or source-code is more about which tools are available to me to support a particular language/platform at a given point in time.
It will be readable (in terms of indentation and structure), although the names for variables and global definitions will look very weird, as Lux is not really trying to maximize readability for humans, but rather how easy it is to treat a language as a compilation target.
The nicer the source-code output is expected to look, the harder it is to generate it, especially when you consider that every language has its own set of syntactic conventions which would need to be accounted for.
So don't expect Lux to produce idiomatic Python code, because all Lux wants is to produce code that will do what Lux needs it to do.
However, with that said, it's not going to be garbled or obfuscated code. No 1-character variable names. No unnecessary weirdness.
It is feasible. It's just not something I care about.
Maybe someone else could make it happen, if they decided to contribute to Lux.
Adding a new source-code backend should be about a week of part-time work.
Currently it would require adding a module with functions for generating the source-code for the target language, implementing core Lux syntax, implementing core Lux procedures, then host-language procedures, a module for host interop for the target platform (similar to how the Lux stdlib has a module for JVM interop), and adding tests for host-platform-specific features (there is already a comprehensive test-suite for backends that is re-usable/parameterizable and all back-ends must pass it, so you just need to worry about passing those tests, but don't need to implement them yourself).
However, when it comes to adding support for a bytecode language, it might take you a couple more weeks, but that's simply because debugging bytecode languages is just more cumbersome than source-code languages, because you can't just read the generated output on a text-editor sometimes (although there are good tools for reading JVM bytecode).
Nothing specially tricky about Lux, so long as the target platforms support something like
eval and doesn't disallow some of the features Lux depends on.
In particular, I considered compiling to Bash at some point, but ultimately decided against it because Bash has no notion of first-class functions.
There appears to be a hack that can sort of simulate them to some degree, but it didn't seem good enough for me; so I discarded the idea.
Regarding ELisp, that's another target I thought about, but I've shelved it for the moment because I'm not sure how much demand there would be for it.
For Whitespace and Viml; I'm not familiar enough with either to know whether they would make good targets for Lux.
Embedability was not an initial goal of Lux, but I've thought about it for a while and I'm pretty open to it.
I have dreams of implementing a documentation tool, a build system and even a text-editor for Lux after I'm done working on the main language, and all of them would involve using Lux as an embedded compiler/interpreter for doing a variety of things (compiling the program and then extracting documentation meta-data OR running build scripts written in Lux OR programming the text-editor ala Emacs).
Lux will also have its own
eval function in the future, after I'm done porting compiler code into stdlib, and make my own JVM bytecode-generation library in pure Lux, to stop depending on the JVM-only ASM library as I currently do.
So, Lux will definitely be an embeddable language in the future (hopefully when v0.8 rolls out at the end of this year).
Racket is probably the language I see the most as competition to Lux, as it is also a very ambitious piece of technology.
I've even considered the possibility of porting Lux to run on Racket, as a potential way to neutralize the threat

However, with that said, I'm not terribly familiar with Racket.
I've never used it for anything, nor have I studied it in depth.
Not for any bad reason; I've just been occupied with more pressing stuff so far.
But from what I've seen, I've got the impression that they're after many of the things I'm also after, but they're pursuing those goals in very different ways.
Like, for example, they seem to want to support other languages by having them get translated into Racket, whereas the goal for Lux is to translate it into the target languages.
So, in both scenarios you get support, but for opposite reasons and with different sets of trade-offs.
And I think there are other things in which Racket and Lux go in opposite directions when trying to achieve some goals.
I'm not saying this to imply that Lux does it better or that Racket does it better.
For some of these things, it might be a matter of perspective, or even taste.
But the decisions I make, as far a Lux's design and implementation, are always based on months of research, deep thinking, experimentation and checking out what others have done (and are doing), to try to come up with ideas that will hopefully stand the test of time.
Hopefully, I'm right about
most of them.