Thursday, November 29, 2007
Writing and Coding, Part 3: Artistic Expression
All right, I'll admit it. I've been putting this part of the series off. This is a huge topic, and the more I've thought about it, the less I feel I can do it justice in the time I have to prepare and the space I have to expound on it here. So instead of doing an in-depth exploration, I'm going to provide a very high-level overview. Put on your running shoes.
Artistic Expression
Programming seems to be a creative, artistic endeavor in two ways.
First, you have phenomena like perl poetry, where code is explicitly, consciously used as poetry. This is related to the school of thought that looks at programming's primary purpose being communicating algorithms to a person. Executing the code on a computer is secondary, a means of making sure you are correctly expressing the algorithm.
Aesthetics: De Gustibus Non Disputandum
Personally, I tend to having simple, regular syntax, even at the expense of having simple, regular semantics (although I like that to be simple also). This bias is evident in a couple of ways: First, I prefer Python to Ruby. Ruby's semantics are probably more regular (everything's an object vs everything's an object, but it may be a classic object and some things are sealed), but the few times I've attempted to learn Ruby, the syntax just seems a little irregular. Not in a bad way, necessarily, but enough that it's squelched what little motivation I've had so far to learn what is probably a fine language.
But that's beside the point. What I'm trying to illustrate is that people judge programming languages partially according to criteria that is strictly non-utilitarian. Having simple syntax doesn't make any difference in how capable Python is at building, say, web apps. (As I type this, I'm mentally constructing an argument that it does, but in general, I stand by this statement.)
Of course, the academic in me is wanting to step back and define terms now. What does aesthetics mean? Maybe it's time to step back, pull out some literary theory books, and see where this leads us.
Is there anything more dull than someone who is both a literature- and computing-geek?
Wednesday, November 28, 2007
The Kindle and Big Brother
Mark Pilgrim has an great post that draws correlations between the Kindle's DRM and Orwell's 1984.
The point here really isn't the Kindle. Amazon's e-book reader is just the latest example of such policies. (It may be breaking new ground, so to speak, in that it is an inherently connected device, and its DRM reflects that.)
Right now I'm reading (paper book) Rainbows End by Vernor Vinge. In that future world, privacy is virtually non-existent. DHS has monitoring devices in everything. Vinge explicitly says at one point that people had to adjust their quaint notions of privacy. (I don't have the book in front of me, so I don't know that he put it like that — quaint, and so on — but that was the impression that I got.
Britain and other countries are moving quickly toward a surveillance society. I remember several years ago, I was helping to chaperon a study-abroad program in England, and we warned the students that they should be careful about such things. In a previous term, a student was caught trying to buy drugs when a video camera installed in an alley recorded him.
I would imagine that the United States is moving in that direction. Certainly the current administration would like that. We already have cameras surveilling intersections for traffic violations. The sheer size of the US means that we probably won't be able to monitor everything. We'll have to find some scaled-down version of universal surveillance that only monitors high-risk areas.
Until the computers can watch us for ourselves. Then we can monitor everything.
Tuesday, November 27, 2007
Programming Fun
I just ran across a great post on Ruby being designed to be fun.
I don't program in Ruby myself, yet. I've attempted to learn it several times. I get started working through Programming Ruby, but I never get very far. I never have much motivation to pick it up. It seems to occupy a niche that is happily occupied by Python in my programming ecosystem. If another language is going to displace Python, it will probably be some form of lisp. In the end, what finally makes me set aside Ruby are aesthetic reasons I'll talk about more later (when I finish the Writing and Coding series I'm working on).
Of course, I also looked at Python once or twice before it clicked for me, so maybe there is some Ruby in my future.
Still, I think that it is great that Ruby is designed for fun. When I did finally "get" Python, I had just come out of bad experiences with two other programming languages: I had hit Perl's 1000-line limit; then I switched to Java. Java's great, but it's not fun. Python made programming fun again.
That sounds like I had just gotten out of two bad relationships when I met her.
And maybe that's what it was.
Monday, November 26, 2007
Playing Catch-Up
Things have settled down after the holiday, but I'm still trying to go through all the electronica that has accumulated in 120 hours of not touching a computer.
In the meantime, entertain yourselves by browsing the Most Unusual Books of the World (via Geoffrey Rockwell).
Tuesday, November 20, 2007
Happy Thanksgiving
Yesterday I said that I would return the to the writing and coding series today.
I lied.
Later this week, is Thanksgiving Day in the US. Originally, I was going to struggle through all the relatives and food and attempt to post anyway. I've decided not to.
While I'm gone, I'll leave you with this link: Kindling Openness and Impact. This touches on some of the issues I see with the Kindle.
If you are in the US, happy Thanksgiving. And to everyone, I hope the rest of your week is great.
Monday, November 19, 2007
Paradigm Shift
Amazon's getting ready to release an e-book reader, Kindle.
This sounds pretty cool. Too bad $400 is more than I want to sink into an reader. Robert Scoble points out that a lot of people aren't loving this device.
Whether it succeeds or fails, however, I think this device is fascinating, for the same reason I find the the current writer's strike interesting.
We have a traditional, risk adverse industry (publishing, music, TV, movies). A new, disruptive technology comes along (the Internet). Now, those industries have to figure out a new way to make money at what they do. Everything changes.
This is an old story.
The same thing happened at the invention of the printing press. Initially, the printers were the main ones making money. A publisher would buy a book from an author, and that was the end of the author's rights. The printer could publish the book. He could change the book. He could put his name on it.
Somehow, we went from there to today's situation: authors are paid a more or less fair percentage of the sales of the book, they are credited, they have some say in what changes get made to the book before publishing.
Today, we (publishers, studio executives, writers, and consumers) are trying to figure out how to make money at this. The old media probably aren't going away soon, but they are becoming less important. The new-fangled Internets are messing everything up.
Will the solutions that we reach now be the final ones? (Final here means until the next disruptive technology comes along tomorrow.) Maybe not.
That's what's interesting.
(Tomorrow, back to the writing and coding series.)
(Tomorrow, back to the writing and coding series.)
Sunday, November 18, 2007
Writing and Coding, Part 2: Self-Discovery
One reason people create things, art generally, but I'm arguing here that creation in itself of anything is an act of self-discovery.
People say that writing is an act of self-discovery. Journaling is writing for no purpose other than self-discovery. But even writing that is meant for public consumption also often helps the writer learn about herself.
Of course, the act of self-discovery—like creativity—is usually messy, and writers rarely let it out in public. I remember that for one class I wrote a lot of personal essays, a form that I really enjoy (hmm, a blog?). I would pick a topic to write on. I'd get started, heading in one direction. About half way through, I'd discover something about myself or about the topic I was writing on. Because of that revelation, the essay would take a sudden turn and head off in another direction. That was good; I counted on it, hoped for it.
But it made more work for me, because then I would have to fix the first half, make the whole essay go in the direction the last half did. Part of the essay would be thrown away, but in the end, I'd learned something, and the essay was much better.
I've heard about others who draft novels by throwing away the first, the second, and even the third drafts. That astounds me. Knowing how much work goes into a novel, I have trouble imagining throwing a draft away. On the other hand, it would probably make a better final product. I just wonder if more planning up front could take the place of making such drastic edits.
So when I write for self-discovery, I don't know where the work is headed, and I have to be willing to cut drastically, even throw out whole drafts. How does this apply to programming?
Supposedly, Richard Feynman had written on his chalkboard, "What I cannot create I do not understand." Part of the programming I do is to help me understand problems. I'm not by nature a detailed thinker. I prefer to stay in the clouds, thinking about things in an abstract way. Programming requires me to be specific, however, and to think problems through thoroughly. In solving a problem in code, I learn something about the problem and what it takes to solve it.
In learning to solve a problem this way, I often work my way to a solution gradually. I open up a REPL (lisp read-eval-print loop) or Python interactive interpreter. I open up a text editor. I go back and forth between the two, feeling my way to a solution.
Working this way is fun, but it is wasteful. As I'm doing it, I may attempt several solutions that have to be thrown away. And often, the code that results is a mess and has to be thrown away anyway. But at that point, I understand the problem and what it takes to solve it, and I can quickly write something much better.
That process sounds like what I did with the personal essays.
But I am learning something about myself on this? After all, I'm talking about self discovery in this posting, not problem understanding.
It can be. I should probably write another post focusing on this assertion, arguing just it, but the act of creating anything teaches us about ourselves, if we're listening. How do we interact with the environment we're changing? How is our approach different than other people's? Why is this problem interesting, not that one?
Friday, November 16, 2007
Writing and Coding, Part 1
When I named this blog, part of the reason I chose this name was because I enjoy both writing and coding, and I wanted to talk about both. I didn't want to start two blogs, however, and later abandon both. I would rather just abandon one. (There are already a few abandoned blogs with my name on them. No sense adding to that number without reason.)
The other reason is that I've always thought that there are similarities between the two activities, as well as big differences, and I wanted to explore these. A lot of people have written on these before or presented papers. This is just my take.
This is a complicated, many-faceted topic, so it will take me several days to discuss this. Here's the plan:
- Writing and Coding, Part 2: Self-Discovery
- Writing and Coding, Part 3: Artistic Expression
- Writing and Coding, Part 4: Test-Driven Writing
- Writing and Coding, Part 5: Ambiguity
- Writing and Coding, Part 6: Conclusion
Thursday, November 15, 2007
Expanding Short Stories
The other day, I mentioned that I was working on a short story I was calling "Voodoo Christmas."
As I was fleshing out the concept, I realized a number of things.
First, there are a lot of characters.
Second, it's not so much about Christmas as it is about the year after Christmas, so there's also a long expanse of time involved. I've even considered it spanning a year.
Third, it will just take a while to set up the plot, develop the characters, get things rolling, and tell the tale.
Allow me to introduce the novella/novel Voodoo Christmas.
Wednesday, November 14, 2007
Editing Lisp
In which I decide to start hacking in lisp, and that rocks my editing world.
The options for editing lisp in Vim are pretty limited.
Well, let's be precise. Vim is a pretty good lisp editor, when you compare it with almost anything except emacs.
There have been attempts to bring Vim up to emacs' level. There was a project to integrate ECL with Vim. It was part of a larger project, Slim-Vim to write a Vim interface to SLIME, the excellent emacs lisp development system.
Unfortunately, Slim-Vim is dead. Both of its primary developers have abandoned it. According to their farewell emails, one now develops lisp using a commercial IDE, and the other uses emacs and SLIME.
Generally, the advice for people like me is to suck it up and use emacs. You will be assimilated.
Others do still use Vim for lisp, and I still prefer Vim for actually editing lisp. I've done some crazy, complicated things to get it to integrate with a running lisp system. The version of lisp I usually use, SBCL, doesn't include readline in the REPL ("Use SLIME," they say), and using it without command history, etc., is painful. So I would start emacs and SLIME, and I would start Vim. I would open the file in both emacs and Vim. Editing would occur in Vim, then I would refresh the buffer in emacs and feed my changes into SBCL.
I know.
Suck it up. Use emacs.
Eventually, that will be how this story ends.
First, I'm going to try Cusp, an Eclipse plug in for lisp development. Aside from being a lot prettier, I'm not sure what it has over emacs+SLIME.
What do you use for lisp hacking? (If I get no answers, I'll assume everyone uses emacs.)
Tuesday, November 13, 2007
A Theory of Text Editors
When I started working with LINUX, I used GNU emacs. At the time, I was using some low-end hardware, even for the time. One day, I realized that my morning routine was to boot up, start emacs, and make a cup of coffee while I waited for emacs to wake up in the morning. That was insane. There was a lot I liked about emacs, but I needed something lighter weight. So I switched to Vim, and I still use it for all my editing needs.
Vim messes with your brain. Once you've internalized the keystrokes, you're ruined for other editors. In the past, I would sometimes think that I needed to enter the 20th century and try some other editor—Eclipse, jEdit, or something. I'd install whatever it was I planned on using and tweaked it out, but I only used it at most a day, and the entire time I'd be thinking, "I could do this so much more quickly in Vim." Finally, I'd switch back just to make myself shut up. Of course, to really test drive a text editor, you need to give it a few weeks, so I never gave any of these a fair shake.
I even tried viper once. This was a mode in emacs that used vi keystrokes and commands. I only used it about thirty minutes. It was too confusing. I remember the emacs keystrokes enough that I couldn't never quite decide whether I should use them or vi. I was less productive with it than I was with emacs by itself.
My theory is that there are two levels to text editing: High-level semantics and low level syntax. I'll be abusing both of these terms, so let me explain what I mean by them. If you're editing Java or C# or Python or Lisp, semantics involves the libraries you're using. What properties does a Button have? What arguments does socket.socket take? Which comes first in elt, the index or the sequence? Eventually, if you use the language and its libraries enough, these questions go away.
The other level is syntax. This involves editing at the character level: entering text, copying, pasting, moving, search-and-replace. This never goes away.
In my experience, most IDEs are great at the semantic level, but poor at the syntactic level. They will answer any questions you have about the libraries and the language, but if you have to a sequence of keystrokes 1000 times, it is painful. Usually possible, but painful.
On the other hand, Vim is brain dead at semantic stuff. At the syntactic level, however, once the keystrokes have branded themselves onto your brain, no other editor comes close. It tells you nothing about the objects, methods, or functions that you're using, but if you have to repeat something 1000 times, bang, you're done.
So what's the point?
Well, this posting actually started out as a discussion of editing lisp. It seems to have gotten derailed though. Lisp will have to wait for tomorrow.
Monday, November 12, 2007
Stalled Novel
Well, my novel's spinning its wheels right now. More precisely, I'm spinning my wheels instead of working on my novel right now.
I decided that I needed another wrinkle in the plot. I decided what it was, but I haven't been able to make myself work on it since then.
Instead of working on that, I'm taking a break. I've had some ideas for short stories, and I'm working on those. I'm tentatively calling the first one "Voodoo Christmas." Should be fun. I'll let you know if anything comes of it.
Sunday, November 11, 2007
Erlang Nostalgia
A few months ago, I wrote a system for controlling distributed processing using Erlang, but since then, I haven't really done much with Erlang.
Finishing up that series of articles on Erlang reminded me of what fun Erlang is. Looking at problems concurrently is interesting and fun, and while I'm not always fond of the language's syntax, I still enjoy hacking in it. I'll have to do more Erlang in the near future.
Something else for my to-do list.
Saturday, November 10, 2007
CarbonLisp Status
Just a short update today. I've started working on CarbonLisp again. I have a small lispish interpreter written in C#. It will be the first step in bootstrapping the lisp system.
Of course, I'm not sure when I'll get to work on it next.
Friday, November 9, 2007
Language Dreams
Continuing yesterday's quest to prove how strange I am, here is the story of another language-related dream.
When I was in school, one of my areas was medieval literature. I took a lot of Middle English (ME) courses (Chaucer and others), as well as several Old English (OE) courses (*Beowulf*; no comment today on the upcoming movie).
These courses, particularly the OE ones, are very time intensive. I became faster at translating OE the more I did it, but I never got enough practice to be very quick. I would spend hours a day translating a small passage for the next class. It consumed me.
And at night, I couldn't escape. Invariably, once or twice during the semester I would dream about OE. It was always the same dream:
A charcoal-gray background. Words in light gray with a slight halo. The words would speed by faster than I could read. Some of the words contained OE letters like thorns, eths, aesces. Other words were obviously ME. The two mashed together, interlocked with each other.
And they kept coming. Faster than I could read, they scrolled by, they never stopped.
It probably sounds like the dream had some emotional content, but it really didn't. There were just words without meaning or feeling. I don't know that these were bad dreams in themselves, but the fact that I had them both dismayed and amused me.
Thursday, November 8, 2007
Grammar Police
The other night I dreamed I was explaining grammatical rules to someone.
Actually, I was explaining how there are rules, rules, and rules.
There are rules that someone in the past made up and—if I abide by them at all—I pay attention to them only because other people would think poorly of me if I break them, and language is nothing if not conventional. Generally, all the big, bad grammar rules your teacher used to yell at you about fall into this category.
Then there are rules that are good, have basis, and I follow them sometimes. After all, rules are made to be broken.
Finally, there are real rules that, when you broken them, you're no longer talking English. If you're a native speaker, you've probably internalized these rules and breaking one just wouldn't occur to you.
When I woke up from my dream, I was explaining this to someone, and I pointed out that it didn't matter if you explained, for instance, why the rule about split infinitives is bogus. Those who like rules are going to insist that all these rules must be followed at all costs. Some people just can't handle the freedom, I guess.
(Of course, any discussion of faux grammar rules is incomplete without mentioning the phrase attributed to Winston Churchill (falsely): "This is the kind of pedantic nonsense up with which I will not put!" Unfortunately, this refers to ending a sentence with a preposition, not split infinitives.)
Against my better judgment, I ask: does anyone else here dream about grammar?
The resounding silence reinforces how strange I am,
Wednesday, November 7, 2007
Concurrent Thinking, Part 3
When I decided to dust off and publish the old post I had written, I wasn't expecting it to turn into a week-log series. And it's not. This is the last.
If you'll remember, gentle reader, I've been foreshadowing trouble. Today's the payoff. You'll remember that the reason I didn't just slurp the entire file into memory at one time and build lists from it is that I need to be able to process files that were much larger than would fit in memory. If the process reading the file can read all of it before the transformation process can handle much of it, or before the output process can write the output, the file will be read into memory in its entirety, more or less, and this entire exercise has failed. To imagine how this could happen, suppose the input comes from a local file, but the output is being written across a network. The input process could read all the file, and the transformer process could handle the data, but the messages would still pile up in the output process's mailbox, filling memory and bringing the system to its knees. Or suppose the transformation being applied involves a time-intensive computation. Its mailbox would fill up memory when the input process sends it the entire file while the first few messages are being transformed. Again, the system dies, horribly, horribly. I won't tell you how I solved this when it happened to me. Looking back, it was a nasty, nasty kludge that I only used because I was under time pressure. What I should have done was use the functional solution someone mentioned in a comment to Concurrent Thinking, Part 1. This solution involves having the input and transformation functions return a tuple with two values: data and another function. The new function will return more data and yet another function. Eventually, when there's no more data, the function will just return a flag indicating that. I won't rewrite the entire example from yesterday in this style, but the input function would look like this:
If you'll remember, gentle reader, I've been foreshadowing trouble. Today's the payoff. You'll remember that the reason I didn't just slurp the entire file into memory at one time and build lists from it is that I need to be able to process files that were much larger than would fit in memory. If the process reading the file can read all of it before the transformation process can handle much of it, or before the output process can write the output, the file will be read into memory in its entirety, more or less, and this entire exercise has failed. To imagine how this could happen, suppose the input comes from a local file, but the output is being written across a network. The input process could read all the file, and the transformer process could handle the data, but the messages would still pile up in the output process's mailbox, filling memory and bringing the system to its knees. Or suppose the transformation being applied involves a time-intensive computation. Its mailbox would fill up memory when the input process sends it the entire file while the first few messages are being transformed. Again, the system dies, horribly, horribly. I won't tell you how I solved this when it happened to me. Looking back, it was a nasty, nasty kludge that I only used because I was under time pressure. What I should have done was use the functional solution someone mentioned in a comment to Concurrent Thinking, Part 1. This solution involves having the input and transformation functions return a tuple with two values: data and another function. The new function will return more data and yet another function. Eventually, when there's no more data, the function will just return a flag indicating that. I won't rewrite the entire example from yesterday in this style, but the input function would look like this:
Here, input/1 opens the file and calls input_continuation/1. This returns a function, A. When you call A, you get the first block of data and a new function, B. B will return the second block of data and a function C. This happens until there is no more data, at which point the file is closed and eof is returned. This solution is very Erlang-ish, and it throttles nicely so it doesn't accidentally fill up memory. End of series.input(Filename) -> {ok, F} = file:open(Filename, [read]), input_continuation(F). input_continuation(F) -> fun() -> case file:read(F, 1024) of eof -> file:close(F), eof; Data -> {Data, input_continuation(F)} end end.
Tuesday, November 6, 2007
Concurrent Thinking, Part 2
So, briefly, the problem involves piping large amounts of data through a series of transformations, usually just one. In other languages I would use some form of lazy lists to plug together the input reader, transformations, and output writer. In Erlang, I decided to use processes.
One interesting thing about Erlang processes: If you squint at them just right, they act like classes do in other languages, just without inheritance. The processes communicate by passing messages, and those messages trigger the processes to perform predefined actions. This seems very like message-passing paradigm of object oriented programming.
Basically, one process reads the input and sends it to the transformer process, which in turn sends it on to the output process. Here's the pipeline I implemented in Python above (it has to be saved in a file named "erltransform.erl" to work):
Hmm. This is a lot longer, and it doesn't do as much. Erlang's libraries are OK, but the standard distribution doesn't have Python's batteries included approach. Since Erlang doesn't come with a library to read and write CSV files, this just reads a block of 1024 bytes, and it drops every other block. Some explanation: At the beginning of the code above, the input/2 function opens the input file, reads the first block, and calls input/3, which sends the data to the transformer PID and loops. When it reaches the end of the file, it closes the file, prints a message, and exits. The transform/1 function calls transform/2 with a flag indicating whether it should keep or drop the next block of data that's sent to it. Based on the value of this, it either sends the data on or ignores it. When it receives eof, it sends that on and exits. The output/1 function opens the file and sends it on to write_output/1. (Since both of these functions have the same arity, I had to give the second function a different name.) Output just writes the data it receives out and closes the file when told to. Finally, main/2 spawns all the processes, linking them together, then it gets out of the way. In this case, the messages being passed are simple: the data read, dropped, or written. Yesterday, I hinted that this approach got me in trouble. How? That, gentle reader, is tomorrow's episode. Stay tuned.-module(erltransform). -export([input/2, transform/1, output/1, main/2]). input(Filename, NextPid) -> {ok, F} = file:open(Filename, [read]), input(F, file:read(F, 1024), NextPid). input(F, {ok, Data}, Pid) -> Pid ! Data, input(F, file:read(F, 1024), Pid); input(F, eof, Pid) -> io:format("closing input.~n", []), ok = file:close(F), Pid ! eof. transform(OutPid) -> transform(OutPid, 0). transform(OutPid, 0) -> receive eof -> OutPid ! eof; _Data -> transform(OutPid, 1) end; transform(OutPid, 1) -> receive eof -> OutPid ! eof; Data -> OutPid ! Data, transform(OutPid, 0) end. output(Filename) -> {ok, F} = file:open(Filename, [write]), write_output(F). write_output(F) -> receive eof -> ok = file:close(F), io:format("closing output. done.~n", []), eof; Data -> ok = file:write(F, Data), write_output(F) end. main(InFilename, OutFilename) -> OutPid = spawn(erltransform, output, [OutFilename]), TransformPid = spawn(erltransform, transform, [OutPid]), spawn(erltransform, input, [InFilename, TransformPid]).
Monday, November 5, 2007
Concurrent Thinking, Part 1
Note: I originally wrote this back in June, but never finished it. An now, presenting part one....
Concurrency is the key idea to come to terms with in Erlang and the key tool that it gives you. It's the modeling tool to use when solving a problem.
I realized this when I was implementing a code transformation pipeline. The pipeline would go input to transformation to output. I wanted to be able to interchange any of those pieces, so I could read from multiple formats, transform the data in different ways, and write the data out in different formats. And it needed to be able to handle a lot of data.
On my first attempt, I approached the problem the way I might with Python: Input, transformation, and output are iterators which are just chained together. For example, the input would read CSV, the transformation would drop every other item, and the output would write it back to CSV::
Stay tuned tomorrow, when the hero attempts to use powerful Erlang concurrency and ends up hoisted on his own petard.
That's not very useful, but you get an idea of the problem and what I was trying to do. Using iterators/generators is nice here because I don't have to worry about too much input filling up memory. Also, I don't build a list I don't need or use. Unfortunately, Erlang doesn't have iterators. I thought I would use lists instead and work from there. I could have had the input function read everything into a list, the transformation function transforms it into another list, and the output function writes a list's contents to disk. It wouldn't have been pretty, but it would have worked. Part way through coding this, I realized that Erlang has a great solution to this: concurrency.from __future__ import with_statement import csv def input(filename): with open(filename, 'rb') as f: for row in csv.reader(f): yield row def transform(rows): rows = iter(rows) while True: rows.next() yield rows.next() def output(rows, filename): with open(filename, 'wb') as f: writer = csv.writer(f) writer.writerows(rows)
Stay tuned tomorrow, when the hero attempts to use powerful Erlang concurrency and ends up hoisted on his own petard.
Sunday, November 4, 2007
Plot Twists
Today's Sunday, it's late, and I still have a lot to do today. So you get the reward. Here's a toy. I don't know how useful it is, but it is fun to play with.
Plot Twist Generator
Saturday, November 3, 2007
Novel Writing
I mentioned NaNoWriMo a couple of days ago. I'm sure that at the end of this, many people who actually managed to turn out 50,000 words of precious, absolutely brilliant, ground-breaking, Pulitzer-winning material just want to see it in print. Lots of people will do that for you—or pretend to—for a price.
When you think about it, this is a situation ripe for someone to take advantage of. A writes a book. Convinced that it is the next Great American Novel, he or she sends it off to several publishers and agents. He doesn't hear anything for a while, but when he does, no one seems to share his opinion of his work. All say, "Sorry, not right for us." Finally, he finds an agent who guarantees results, but who wants a reading fee. That seems reasonable. Or he finds a publisher who charges him to publish the work, but points out that they will be in featured on Amazon and in a major national chain. Surely he'll recover the fee and be making more money than he ever dreamed of.
I've written one novel so far, and I haven't gotten any published yet (I haven't tried, since it was crap). So my credentials on this are thin. But I do know this: writing is hard. All stages of the writing process are hard. Writing is hard, editing is hard, getting an agent is hard, getting a publisher is hard (which is why people hire agents to do it), marketing your book is hard (which is why publishers help). There are no shortcuts. Talent helps. Being willing to look hard at your work and to take criticism helps. But perseverance, stubbornness, and sweat are critical.
The point? Be careful. You are probably fine, but many new writers aren't aware of what rubbish their work is, and many people are willing to feed them lies, take their money, and deliver nothing. Before you try to get published, do two things.
First, ask yourself why you want to be published. Do you want to hold a printed book in your hand with your name on the spine? Fine, self-publishing or print on demand (POD) is probably fine. But if you want to be read by strangers or make money writing fiction, the traditional publishing industry—while it has its problems—is your best chance right now. And face it, most people write to be read, being published is just a means to that end.
Second, do your homework. Visit Writers Beware. Hopefully, you'll be establishing a long-term business relationship with your agent. Make sure it's someone honest, someone good at their job, someone you can work with.
Write well. Be safe.
Friday, November 2, 2007
Django
For work, I've been moving some of our processes to be more database-centric. Databases themselves aren't that useful or interesting for the average user, who doesn't want to get grubby with SQL. I've been putting a web front end on things, and I decided to use Django to do it.
Before this, I had worked through the tutorial a couple of times, but I had never actually done anything with the web framework.
Overall, I really like it. It could use some brushing up in parts, but then it's not at the 1.0 release yet. And some parts are incredible. The admin interface deserves everything that's been said about it. Here you get a complete interface on your database tables for almost no effort. Incredible.
The main downside is my own insecurities. Am I doing this the best way? Am I structuring my code the best way. I've divided the project up into about half a dozen apps, based upon categories that make sense according to our processes, but which are ultimately arbitrary.
I should probably get on (IRC) #django and ask some questions. But if history is any indication, I will continue to stumble along on my own.
Thursday, November 1, 2007
National Blog Posting Month
No, this blog is not dead!
I've been considering changing the focus somewhat, and I've been busy with work and life (as usual).
But, this is National Blog Posting Month (NaBloPoMo). In honor of which, I've decided to join that and post here every day for a month.
I could have joined the larger, original movement, National Novel Writing Month (NaNoWriMo). I am still working on my novel—I'm sure I'll talk about that more soon—but I'm not taking part in that. I'm not that crazy.
Is anyone here taking part in either of these insanities?
Subscribe to:
Posts (Atom)