I've upgraded my code on every Arc release since arc0, and it's been easy.
This may sound overly simple compared to building a translator, using namespaces or modules, or writing in layered API's, but in practice this is what quickly results in working code for me: in my source code file, I merely arrange my definitions so that definitions that depend on other definitions always appear after the definitions that they depend on.
For example, if h uses g and g uses f, I write out the definitions with the lowest level code appearing in the file first: f, then g, and then h.
(On occasion I'll have mutually recursive functions; those I'll just put next to each other in the source code file. And when I have multiple source code files, I follow the same principle: I ensure that I can order the source code files so that later files depend on code in earlier files, but no earlier files depend on code in later ones).
Now it is simple to upgrade the code in my source code file to a new version of Arc: first I get f to work, then I get g to work, and then I get h to work.
Each step is quick: most often the function doesn't need a changes to work in the new version of Arc, and if a change is needed it's just a tweak.
No massive monolithic all-at-once conversion needed.
And there's no pressure. My code still works with the previous version of Arc that it is running on. So I can convert over to the new version at my leisure. When I'm ready.
Even if someone wrote a translator, I wouldn't use it myself. It would add an extra layer of complexity (if I have a bug, is it in the new version of Arc, or in my code, or in the translator?), and I wouldn't need it.
Updated with a bug fix: my code to work with both Python's byte strings and Unicode strings was doing neither successfully.
In this new version Arc strings are always converted to a Python Unicode string u'...'; I'll probably add a function to generate a Python byte string '...' at some point.
The Python code currently generates ugly Arc strings with every character escaped; I'll fix that when I have some more time.
What is the difference between minimal and minimum in this context?
One of the things I like about Lisp is that it makes it easy (or at least easier) to write code transformation facilities like this.
I can imagine other code contraction facilities might be possible, giving suggestions of what might be options, even if they weren't correct all the time. I often notice a pattern in my code that I start to write a function or macro to extract, and then discover that it is already available in arc.arc.
I don't use atomic myself. But I find that enabling the back-end thread slows down the UI threads. I've been struggling to create a simple program to illustrate this.
In fact, wrapping parts of my UI threads in atomic actually makes them more responsive[1]. I think it's because instead of getting 200 thread switches with their associated overheads, a single thread runs to 'completion'.
[1] You're right that throughput may go down, though I try to eliminate IO in atomic blocks. But latency is more of a concern to me than not wasting CPU. It's not the end of the world if new data takes a few seconds longer to make it to the index, but a few seconds in the front-end can make or break the user experience.
"vector-set-performance-stats!" in http://docs.plt-scheme.org/reference/runtime.html returns the number of thread context switches that have been performed, so you might try calling that at the beginning and at the end of an UI operation so you can see how many thread switches happened in between.
There shouldn't be a way to interrupt an atomic operation, because then it won't be atomic.
Your elegant solution to make kill-thread atomic is a good one, if the "killed" thread is in fact guaranteed to be terminated instantly... I'll have to look into it to see if I can find out.
There shouldn't be a way to interrupt an atomic operation, because then it won't be atomic.
An interruptable atomic is basically a transaction that can be rolled back. If it gets interrupted nothing is changed. Probably doesn't make sense to run it from anywhere but kill-thread and similar operations.
To restate my original point: reasonable semantics for atomic are that threads inside atomic can't be killed. How to kill long-running atomics is a separate issue, needing a lot more engineering.
Not sure if MzScheme's kill-thread is guaranteed to kill a thread "instantly"? If not, then you have a race condition: you schedule a thread to be killed, but it maybe has just enough time to enter an atomic block before it dies.
But you're on the right track though. We actually don't want to kill a thread in the middle of an atomic... in your very first example, (thread:atomic (while t)), it would be a bug if kill-thread did break that loop. The whole point of "atomic" is that the operation completes before other threads see the result.
So the desired behavior is if a thread is "killed" in the middle of an atomic block, it should finish the block (and release the lock in the normal way), and then die.
The MzScheme documentation web site is down at the moment so I can't look now, but if I recall there is some kind of break or signal mechanism in MzScheme that might help.
In the Arc server, I moved creating the request object out of 'respond (http://awwx.ws/srv-misc), so that 'respond is now being passed the request object and does the usual Arc srv action to respond to a request: look to see if there is a defop etc. defined for the request path.
Now I can extend respond to implement my own ways of responding to requests: I can easily have my own way of choosing which action to take (I can have http://myserver.com/1234 display the "1234" item page, for example), or implement my own kinds of defop's.
Curved quotes (“...”) bug me a little because of the way tools like Microsoft Word and Wordpress automagically curve people's quotation marks either as they type or as they publish. Usually, this would just result in a flagrant syntax error, but with your syntax it would have a slightly more subtle effect.
I almost didn't care to mention it. After all, if people are going to compose/publish code in places where prose is expected, they'll get bitten one way or another. For instance, really strange characters might be displayed as question marks, or a random ":o" might turn into an emoticon. But I was amused to find a curved quote code mishap within a day, just by accident: http://www.flashcoder.net/blog/?p=100
The quotes you use in the MediaControlEvent package result in a
syntax error in Flash if I copy from browser to Flash.
Rather than:
“headControl”
should be:
“headControl”
Automagic curved quotes on a coding blog. Priceless. (I'm one to speak. I think my blog has the same problem.)