Swift for targeted code generation

I have a setup for code generation that I love, but is now moribund. I will describe the aspects that are great and I would like to know what swift might offer for solving this problem. From what I've read there is some support for scripting in addition to incremental compilation, so that is promising.

My current solution uses the Dart programming language. With dart there are now a few implementations of the language - one for web, one for flutter and another vm for console work. My stuff is all console vm. I say my setup is moribund because all my code is written in Dart 1 and the recent move to Dart 2 has killed it for me. While the language is still awesome IMHO, my m.o. for using it no longer works because version two of the language moved to an ahead of time compilation approach.

I made a decision early on to model items I want to generate code for in the Dart language itself - rather than in json, xml or some data language. My thinking was so often I want to transform models that it did not make sense to even deal with json to dart every time I want to make a change. Plus, by modeling my data in the language I get the intellisense. So, if I’m targeting c++ I model classes, templates, members, statics, consts etc and then at a higher levels of abstraction implementation files, header files, build scripts - etc. The dart libraries supporting those models, once written don’t change too frequently. The issue with Dart 2 is startup time for running a code generation script went from under 1 second to over 8 seconds which killed the workflow. So prior to 2 I could generate 20 files in less than a couple seconds and now its over 10 seconds. Similar issue for testing. The language has support for snapshots which is great for scripts run repeatedly, but does not help my situation because I create my models in the language directly and therefore every change is a “recompile”. Currently there is no real support for “incremental” compilation with the snapshots (e.g. no way to just compile the one script that has changed and patch it in to preexisting snapshot(s)).

Some features I love in current (Dart 1) setup is:

  • Fast turnaround since language was in scripting space - make change, save and less than two seconds all files updated
  • Great support for string interpolation “class ${className} …”. I’ve used template libraries in other languages and I’m ok with them but have no strong attraction to them and don’t mind piecing together all text in code. String interpolation makes it easy.
  • They have this nice syntax called cascades that turns any set of chained method calls into a kind of fluid API automatically. So - a small sample showing fluid declaration, guided by intellisense (in vscode), which defines a C++ class that has template parameter and two members:
        class_('change_tracker')
        ..descr = '''
  Tracks current/previous values of the given type of data. For some
  algorithms it is useful to be able to examine/perform logic on
  current value and compare or evalutate how it has changed since
  previous value.'''
        ..template = [ 'typename T' ]
        ..customBlocks = [clsPublic]
        ..members = [
          member('current')..type = 'T'..access = ro,
          member('previous')..type = 'T'..access = ro,
        ],
  • Excellent libraries for xml, json, yaml etc. One use case is to read xml from protocol schema definitions and generate library support.
  • Excellent error identification (type related) from the IDE before even running the code.

So, I don’t know much about swift yet and am willing to learn new paradigms if they are good for this problem. I have no need for Windows but would like assurances that a decent solution here would just work out of the box on either mac or linux.

What are your thoughts on swift for this problem?

You might run into problems with this in Swift land. Swift is usually a compiled language. It does have a REPL and script-like execution mode (via shebangs). But the startup time for those scripts hasn't been the best compared to true scripting languages like Python or JavaScript. Also, it's tricky to create multi-file Swift "scripts".

Swift has pretty good support for string interpolation.

Another area you might run into trouble with. JSON and XML shouldn't be too much of an issue, but others might be harder to find good libs to do.

This has improved a huge amount since Swift first came out. Both Xcode and CLion/AppCode do a decent job of being Swift IDEs. And with the coming LSP service coming, this should become more uniform across IDEs.

1 Like