I haven't really written very much in the past six months or more, and while I think I've done cool things and learned about cool things,
Let me take that back. I haven't written anything in a sustained sort of way that wasn't for work. Hell, even what I've been doing for work has been smaller and more tactical. Unfortunately you don't write books, or book-like-objects as small tactical approaches.
So I've been trying to figure out how to get back to that. It's about rhythm more than anything. If you approach time management for log-form rationally, there's never enough time, so you have to make time, and trick yourself into writing and figure out how to make a little progress on a regular
As someone who definitely tends towards binge writing (and who doesn't) remembering to write a little bit on a regular basis is hard and nearly counter intuitive. So as I've been attempting to restart the writing habit, I've been thinking about what I've done in the past that's worked to keep up the momentum and work on projects. I've uncovered:
Even more important, I think, than reestablishing a habig of writing regularly, is restablishing the practice of reading regularly. I often get hung up on the fact that I don't think I'm a very fast or very through reader. But reading is quite inspiring, and I often find that the more I read, the more I want to write.
So I've been reading the Vorkosigan novels, and it's been great.
I like having some record of my progress, and I've taken different approaches to tracking progress, mostly using word counts, over time.
When you're writing longer pieces, particularly in editors that don't reflect word counts or page numbers in the interface, it's easy to loose context for how much progress you're making.
Way back when, I used to record the current page and word count for all of my projects in a note boot, and this developed into a rather incurable tick to mash a few keys down every few sentences to check the word count. Then, three years ago, I wrote a script to check the word count of all my projects on a regular interval.
I stopped really using it about a year ago, because the script handled different branches (in git) of the same project really poorly, and there wasn't a good way to hack that in.
So I recently rewrote this program, and I rather like it. I'll post more about it soon.
To do writing one definitely needs to spend a serious amount of time in front of a computer typing. Unless you really like notebooks and pens, there's no other way to get things written.
But you can't take this to the extreme: if all you do is sit in front of your computer and stare at cursor waiting for inspiration to strike. As people we need different kinds of focus, and different kinds of experiences, on the small scale, to keep the generative impulses functional.^creative-muscles
Reading voraciously, as above, is a key part of being able to write effectively, but other kinds of activity are also useful. When I'm not writing, my first instinct is to try and find more time to write, but sometimes--often--what I need more is more time for things that aren't writing: exercise, reading, and so forth.
I've started to do yoga, as I've written before, a few times a week. I need to also remember to set aside time for other non-writing activities: more exercise, walks, dinners with friends, dates with my email backlog, etc.
Onward and Upward!
than creative muscles. Writing isn't always creative, but it is, like any other kind of production, work, and always requires energy and effort.
I've been a big fan of fabric which is a Python tool for deployment orchestration: deploying a new release of an application, uploading files, deploying new configurations to a group of hosts in a cluster. Before fabric, the options were either to write fragile shell scripts that often didn't do a good job of handling multiple hosts, or use more heavy weight configuration management tools, which had a lot of overhead and bother.
Fabric is great. Make a python module called "fabfile," write
idiomatic Python, stick anywhere, and then you can call functions in
that module using the
fab command. And it includes a lot of helpers
for interacting with groups of hosts and dealing with remote and local
resources that is designed for takes into consideration common
contemporary application development.
For a while, I basically thought that fabric, or tools like it would completly obviate the need for shell scripting
I think there are two major problems with using fabric as a framework for general purpose scripting:
Global state can get messy.
This isn't only an issue with Fabric, but I think the fab
solution isn't great here. Fabric has this
envy object that you
can import and then use to track the settings or set custom
"global" data values. It's better than having actual global data,
maybe, but you end up having to use it too much, particularly it
for communication between different related operations and you end
up using tasks and global state to run-time configuration.
There's no real overriding abstraction to guide code organization.
In a lot of ways
fab scripts are just a way of writing a large
number of scripts within a single code base and a command line
interface for specifying different entry points. It would be nice
to be able to express relationships between tasks, or centralize
the registry of tasks in some of non-adhoc.
I actually don't think that these are problems with fabric, itself, but I think it's probably the case that we need a few different kinds of tools and patterns to help support the authorship of useful and maintainable shell scripts and build systems.
a good, usable, non-procedural way manage argument parsing.
In python, I like
argprase and think it works really well, so I'm
not saying we need some set of tools to actually parse the arguments
that people input on the command line. But I think when you're
writing a script,
argparse is too low level, and pretty soon there
are a few hundred lines of declarative code, and you still have to
connect this up with the actual code, which leads to maintenance
headaches and all sorts of dumb errors.
a good framework for expressing multi-stage tasks and their dependencies and relationships.
This may basically be waf, but I think we can do something similar. I made an attempt at this with buildcloth but I think I ended up with something that's too much of a (meta) build automation tool, and not enough of a general purpose paradigm for organizing code to perform related tasks in a clean, modular, and well organized sort of way.
These aren't fabric specific problems, or Python-specific problems, of course. But they are particularly relevant to Python moderatly sized Python code bases in general and most fabric implementations that I'veb seen. Maybe Python and fabric make writing useful code easy enough that we start to see complexity problems earlier than we would otherwise. Not sure.
As you may have been able to guess at this point, I am somewhat burdened by a large and somewhat overgrown fabric-based project, that needs refactoring. Thankfully, matters are not critical, but I do want to figure out the right way to solve this kind of problem before I start hacking.
At work people often ask for more "best practices" guides. In some ways this is sign of success: they're no longer begging for fundamental reference material and descriptions of basic use. Nevertheless I almost always wince:
"Best practices" carries an implicit sense of guarantee along the lines of "if you adhere to the best practices, then you won't run into problems," which is sort of difficult to assert with confidence, and is really a product design issue, not a documentation issue.
It is really hard to make one-size-fits-all recommendations.
Best practice-guides don't address actual needs of users, or actual solutions to real problems, because they generalize problems and solutions beyond the point of re-usability.
This isn't to say that it's difficult or impossible to give recommendations, and indeed documentation is the best way that the purveyors of software have to to shape practices. However, the documentation should guide users towards better practices everywhere and isolating recommendations into certain types of documents is probably counter productive.
Onward and Upward!
As part of my project to learn common lisp, or at least write more common lisp as part of my day to day work and life, I've
This is a total rip off of this blog post, with a few minor changes:
I hacked some
makefile goodness so that it will automatically create
binaries for all
.lisp files, and means that you can drop a script
in the directory and not have to edit the makefile to get the magic
TARGETS := $(subst .lisp,,$(wildcard *.lisp)) all:$(TARGETS) %:%.lisp @echo [build]: creating $@ @buildapp --load $< --entry script:run --output $@ @echo [build]: created $@ clean: @rm -f $(TARGETS)
(cl:defpackage #:script (:use #:cl) (:export #:run)) (cl:in-package :script) (defun run (argv) (format t "hello world~%"))
As an aside, I also updated the buildapp aur package.
Common lisp scripts.
The ability to integrate writing lisp into your existing Linux/Unix workflow and processes.
Not having to think about packaging or build architecture for trivial operations.
~40+ meg executable.
Only one source file per script.
See the rhizome archive for more posts.