I've used some very basic TXR for refactorings that were a bit beyond my IDE's capabilities, which gave me a taste of how powerful it could be. One thing that's slowed me down in experimenting with it is having to save the script, rerun TXR and refresh the output file each time I make a change. Do you have any tips for quickly and interactively building complex scripts?
Not in the TXR pattern language, I'm afraid! TXR Lisp has those interactive properties of just re-loading a module on-the-fly to redefine some functions without redefining the entire program, but the pattern language isn't interactive in that way.
This is from the ground up, pretty much, emanating from the way it is parsed in its entirety before being executed.
You can develop the logic in small pieces and test them in isolation on some sub-segment of the data, then integrate the pieces into a larger script with @(load ...).
Speaking of code refactorings, I also use it for that myself. When using it to interactively rewrite code, I invoke it in a pipeline out of vim. E.g. select some range of code visually with V, then "!txr script.txr -[Enter]" to filter it through. Vim deletes the original text and replaces it with the output. If the output is wrong, I hit u for undo to restore the original text. Then of course I have to fix script.txr and save it, and recall and repeat that filtering step just with ":[up arrow][Enter]".
To avoid refreshing the output file during development, don't have one; let it dump to standard output.
Something useful is that we can also monitor the first N lines of an output file that fit into the screen using the watch utility that is found in many GNU/Linux distros. Watch repeatedly executes some command that is given (once every 2.0 seconds by default) and splashes its output on a clear screen. If we "watch cat file", we can monitor the changing contents of file.
I didn't think of calling TXR from within vim, thanks I'll try that.
Watch could get me closer to the workflow I'm used to from web development where the browser auto-reloads whenever a change is made. Your mentioning vim (of which I'm not exactly a power user) actually prompted me to check if it had the ability to run a command on writing a buffer or to automatically reload a file when it changes. Turns out it does indeed have ways to do both these things, so that might be another way to achieve what I'm after.
An example of a more complex script is Tamarind: a CGI application in TXR which lets users log in with their IMAP/SASL credentials and edit their personal list of randomly generated throwaway e-mail aliases.
This is a CGI script that runs under Apache. It doesn't use any web framework; everything is there in the code: parsing URL parameters and form data, handling sessions and authentication, etc.
In early versions, I scanned the /etc/passwd file and authenticated users by doing raw crypt calls on the passwords. Then I upgraded to SASL authentication: sending tokens to "saslauthd" over Unix sockets. This is in
Then I added IMAP. That was an example of incremental development. I tested the IMAP code in isolation and then just planted it into auth.txr.
I was surprised because I was sure that would be done in Lisp; but the pattern language easily implements the IMAP conversation needed to authenticate.
I expected most of Tamarind to be Lisp; I'm surprised how much of it in general ended up TXR via a path of least resistance.
I actually tried running TXR from a Python web service so that I could work with it via a web interface, but running it with subprocess felt all wrong. It didn't occur to me to do it as CGI as it would have seemed far too ambitious for a beginner, but that looks surprisingly straightforward.