As for lojic's question about why not just use PLT Scheme? That's a very good question. Personally, I find Arc has a lot of negatives compared to PLT Scheme, and the only positive I see is the macro system isn't confusing like Scheme's. Arc also provides the excitement of exploring new territory, but I think I've about exhausted that.
What about the rest of you? Why use Arc instead of Scheme? (Maybe this should be a top-level question?)
The reasons I use Arc (well, not these days, due to incredible lack of time, but...) :
- excellent macro system (even if mzscheme seems to have a "dirty" defmacro too),
- the empty list is the false boolean,
- the syntax (particularily  and :) is really a great improvement,
- I never built webapps that fast (and with so much fun),
- my list is close to almkglor's, but he's before me in the leaders' list, and I'll never catch him, so I can't follow him on this point :)
Now, sure, PLT is an excellent language/environment. But it's waaaaay older, that helps. Actually, if today I was given the opportunity to program in a Lisp of my choice (for work I mean, not for fun), I'd use Arc for a basic webapp and mzscheme for almost everything else.
Ditto. I especially like the fact that, because there are so few people working on it, I actually have a chance at making a difference. Not a very big chance, since as yet I'm still a noob, but it's still something to hope for ;)
I thought it would be cool to be part of new Lisp community also, and it may eventually develop into that, but it's increasingly seeming like just a pet project of pg's that may or may not develop into something more. That's not a criticism - I think it was generous of pg to open source Arc and invite folks to participate, and he's been straightforward with his intentions. It's just a slightly different project than I expected initially.
I'm also a Lisp newbie. If I was already experienced in Common Lisp or Scheme, I might be more interested in investing more time with Arc to learn something new, but at this point, I'm simply looking for the best Lisp to learn. Given that I primarily develop web based software, you'd think Arc might be the one; however the ease of creating simple web apps is offset by the lack of other stuff I need and the question of long term viability.
So, learning PLT Scheme seems like a reasonable course of action because I expect I can bring most of that knowledge back to Arc if it gains more traction. Who knows, if developing web apps with PLT Scheme becomes too painful, maybe I'll just switch back to Arc and give it a few months of learning.
I agree with your comments, and those above, and I actually think it's a huge strength of this project and why I remain interested. I think way, way too much stuff in the software community is focused on DO LOTS OF STUFF RIGHT AWAY GET IT DONE YESTERDAY WAAAAHHHHHHHH FASTER FASTER FASTER!!! That may be the right way to start a company, but it's a really crappy way to build a "one-hundred year language".
I like the fact that this project is moving slowly, and that the community (from newbies like me to pros like Tilton) has time to try things and reflect, and not in internet time.
I'm 36. I've already learned and thrown away about 3 different major development ecosystems in my career. I accept that I'll continue to do that in order to pay my mortgage, but in my own time, when I'm actually programming for fun, I want to hitch my wagon to something that will actually have some lasting value. And Arc (or at least something very similar) is the best-looking option to me at the moment.
Yeah, there is a reason PG chose PLT Scheme. To begin with, coming back to arc will not be difficult. PLT Scheme has a lot of libraries and code samples. And it's mature and portable. The dialect is still actively being used and developed. All good reasons to use it.
Personally I've finished my website in arc, I just need to do one more move to the production web server. I'm going to leave it in arc and update it as the language is updated by PG / Community.
I think anyone looking for another language should consider common lisp and smalltalk. I've been coding in both recently and it's been a pleasure after I familiarized myself (again).
It fails pretty early, in ac.scm. If I use pretty much any of the built in "languages", it breaks claiming that "interaction-environment" is unbound. This is a function that's supposed to return the present environment, used as a parameter to eval in the REPL.
If I use the R5RS language, the interaction-environment function is defined, but it doesn't help because it breaks even earlier, at (require mzscheme) in as.scm, claiming that it doesn't recognize require.
After replacing all of the interaction-environment calls with calls to current-namespace, as recommended by another commend on this forum, the first thing that failed was 'set-car!'
The positive thing of Arc being implemented in top of MzScheme is that this way you can easily modify the core language and try new features without messing with assembly or virtual machines, but in the long run an independent implementation seems to me inevitable. Arc2c is moving this way and I think it will eventually abstract over C, maybe by targeting a general bytecode that can be translated to C, to assembly or interpreted by a VM (this is I think what SNAP is supposed to do).
I constantly see comments bemoaning the lack of progress in defining new language ideas in Arc. I don't say I agree 100% with this complaint, although probably the closest that the community has come to this is with hcase.
And of course pg gives library design the same status as language design -- or Arc does, by being so damned flexible. It's not as though Arc is standing still.
But really, the thing that's going to advance the language will be when we use Arc to make things! And that takes some time, and the things we want to make may not be all that important but they'll be interesting to us.
And so while Arc's built-on-PLT status is an obvious hindrance to winning language pissing matches, it means that little is preventing us from doing very interesting things. In fact, that's why FFI's have been such an exciting area of discussion; many of us were limping along with fun little pet projects in another language that wasn't ideal but that had a convenient interface to a couple of C libraries.
In my case, ruby has a good interface to Gosu (for smooth, fast, trouble-free operations on images, even big ones, abstracting away a good chunk of opengl use cases while still letting you use opengl where you want to) and chipmunk (for relatively pain-free 2D physics), and so I made a little screen-saver that has my photographs, mixed with random pg whodehouse quotes from drones.com, tumbling down the screen waterfall-style, and then set about cooking my own code. I got it down to under 100 lines with room for improvement.
(I was living in a fishing village in pacific south america for the last 6 months, with nothing but a $300 windows vista craptop a friend loaned me, so my projects were necessarily of the silly, one-off, only-until-the-surf-gets-good-again variety. I just got back a week ago.)
At the moment, I'm mulling over redoing the same project in Arc, and so my first step is figuring out how to use Chipmunk and Gosu in PLT Scheme. I've never used a C lib from scheme before, so this could be educational.
But I can at least consider doing this project in Arc, in the short-term, because it's implemented on top of PLT. Bad for winning a pissing contest, good for hacking.
Regarding I/O: it's difficult to do I/O in the presence of green threads. Obviously when one green thread is blocked by I/O the other threads must continue running, meaning we need some sort of async I/O. Most of the async I/O libraries I've seen so far seem to concentrate more on sockets than I/O in general.
What are your ideas for handling async io? I know there are system specific ways, but I don't think that's a good idea.
We could have separate os threads for the io, one for each major io system: HDDs, network, keyboard, etc. We could write special io methods for the green threads that request the io from the scheduler. The scheduler adds the request to the appropriate io thread queue. When the operation completes, it either unblocks the gt, uses the provided call-back, or passes a SNAP style message.
I don't know if that would work very well. It doesn't seem very scalable, and at the very least is complicated. It would be best of course, if we could find a cross platform async io lib. But it still might be a good idea to make the scheduler responsible for io, whatever we use. I'm sure you know more about the whole process than I do.
Do you know how any other systems do it? Does erlang have async io? How does the JVM get it's async io? The wikipedia page claims that it is possible to synthesize async io from polling and interrupts (supposedly the JVM does that), but I don't know how standard and trans-system those are. http://en.wikipedia.org/wiki/Non-blocking_I/O
I assume it uses async I/O: For a long time Erlang had only green threads and didn't actually use OS threads. From what little I could grok of the Erlang source, it seems it has a set of OS-specific "drivers" for I/O, but these drivers seem to be extremely basic. It seems to have some sort of queue, but I can't figure out how it handles the queue (i.e. how it prevents the queue from blocking normal operation).
Each port is apparently modeled as a process that happens to have the ability to resume/suspend other processes. When the port gets its timeslice (?) it goes through its queue, does one I/O request (?), then resumes the process that asked for that I/O (I think).
In fact the scheme you described seems, approximately, what Erlang does. I think. I haven't found any particularly good discussions on the Erlang source.
Then there's some note somewhere in erl_async too that if threads (OS threads?) are unsupported, then the "async" I/O becomes synchronous (?).
> How does the JVM get it's async io?
I think that again, this is OS-dependent. After all, JVM is a virtual machine, so it's up to the JVM implementation to handle this. Figuring out how a random JVM implementation does this probably means digging through C source.
To do async IO there are 2 ways: use OS threads or use green threads and OS-specific asynchronous I/O calls. Either way, the VM should, obviously, abstract away the OS-dependant features. Using OS threads seems easier to me.
Well, there is a Boost library for cross-platform threading. We could just use that and "simulated" async using threads to offload the synchronous io. Now, maybe that's a bad idea, and we need to use some abstracted os specific async libraries, but it would work.
Boost also seems to have plenty of libraries that would be useful for SNAP. How is that going anyway, almkglor? I should probably ask questions pertaining to that subjects in it's own thread.
Pretty quiet around here. Hopefully that means everyone's busy ;)
> Well, there is a Boost library for cross-platform threading. We could just use that and "simulated" async using threads to offload the synchronous io.
Boost also has asio, but it appears to be concentrated more on socket I/O than I/O in general.
What I would like is to have a general-purpose asynchronous I/O library, which would handle all details of asynchronicity.
Basically, I intend to allow SNAP to be compiled in two modes:
1. Single worker thread, multiple process. For cases where the OS doesn't have decent threads (dorky embedded systems? LOL, quite a few of the embedded systems I've seen recently actually have decent threads)
2. Multiple worker OS-level threads, single runqueue.
async I/O is needed for 1, and would be nice for 2: in case 2, if a worker thread blocks on synchronous I/O, the others will still fetch processes to run from the runqueue, although the blocked worker thread is one less thread that can work.
However in case 1, there's just one thread, so it can't block.
rainbow is a completely scheme-independent arc implementation. I expect that it's not the 100-year implementation of the 100-year language: arc2c is likely to have seriously superior performance. And I gather that java isn't pg's all-time favourite language. A lot of scheme leaks into the current arc implementation: (is #f nil) is t, #x12 is 18, 'sread reads scheme expressions. Apart from sread, which is destined in a comment to be replaced by writing 'read, it's not obvious whether these should be considered part of the specification.
In the early days, many java libraries were non-java implementations. Gradually they were replaced by "pure java" versions. Is there any reason arc should not do the same?