I've been working a bit on rainbow optimisation lately, mostly to get welder up to an approximately usable speed. The bottleneck in welder is tokenising arc source code, so the tokeniser in parser.arc has been the target of my benchmarks.
On my mac, arc3 performs about 3 times faster than rainbow, which itself is now performing 5 times faster that it was a few weeks ago.
I used to use a prime-number generator to compare ... curiously rainbow performs slightly better for small numbers (find all primes under 10000, 413ms vs 465), but worse for large numbers (find all primes under 100000, 8.4s vs 7.4s). This particular generator uses continuations; there are probably other ways of writing it to exploit weaknesses in either java or scheme to get different results.
Try it for yourself... you really need to be running timing tests against code that you want to run, since different code may end up being faster or slower.
Arc lists are terminated by 'nil, Scheme lists by '(). Because Scheme lists sometimes appear in Arc, the Arc runtime (such as 'is) treats '() like 'nil.
arc> (ssexpand '+.a.b)
.a.b
arc> (ssexpand 'a.+.b)
(andf a. .b)
... but I guess this usage is sacrificed for the greater good of having andf compression. Gentle reminder that #\& wouldn't conflict with a pre-existing builtin function, while making intuitive sense.
Another little surprise:
arc> (ssexpand '++x)
x
arc> (ssexpand 'x++)
x
It's a pity to silently drop pre- and post-fix #\+, instead making special cases for '+ and '++. These are probably "valuable semantic space" - eg expand ++x to (++ x).
Final surprise: I wanted to try all the ssyntax together.
I fiddled a bit with ac.scm to get what I wanted. The problem is that expand-ssyntax invokes expand-compose even if there is only a non-initial #\~ in the symbol. But expand-compose does nothing with non-initial #\~, so my test expression never gets expanded. This fix triggers expand-compose iff #\~ is the first character. Making #\~ have lower precedence than #\+ (as a comment in ac.scm suggests) should also do the trick, but I haven't tried that. (warning: manual diff)
(define (ssyntax? x)
(and (symbol? x)
(not (or (eqv? x '+) (eqv? x '++) (eqv? x '_)))
(let ((name (symbol->string x)))
- (has-ssyntax-char? name (- (string-length name) 1)))))
+ (or (eqv? (string-ref name 0) #\~)
+ (has-ssyntax-char? name (- (string-length name) 1))))))
(define (has-ssyntax-char? string i)
(and (>= i 0)
(or (let ((c (string-ref string i)))
- (or (eqv? c #\:) (eqv? c #\~)
+ (or (eqv? c #\:)
(eqv? c #\+)
;(eqv? c #\_)
(eqv? c #\.) (eqv? c #\!)))
(has-ssyntax-char? string (- i 1)))))
But ^ is the symbol for conjunction, i.e. "and"-ing (well, not the literal caret, but the upwards-pointing symbol -- $\wedge$ in Latex). Did you mean to suggest ^ instead of +?
Have you looked at arc-welder (arc IDE distributed with rainbow, uses java/swing for UI) ?
You can evaluate code from the IDE, although for the moment output goes to the console. This is trivial to change though. I've just recently added a crude jump-to-definition feature so it's quick and easy to find function and macro definitions. Screenshot at http://www.fnargs.com/2009/05/introducing-welder.html
I'm preparing a new, faster rainbow which will hopefully be ready in the next few days. Let me know if you're interested in trying it out.
I had a similar load-path concept in rainbow for a while (using "ARC_PATH" from the environment), but recently realised I could delete a lot of code by assuming everything was under the current working directory. But I'm not entirely sure that this assumption will scale as arc proceeds to world domination.
I wonder if the kind of packaging/distribution infrastructure you mention is a prerequisite for a great language, or is it the other way around? Afaik the rubygems concept was developed quite a bit after ruby became popular. There are some amazing libraries in anarki, and some of them are solutions looking for a problem. What application do you have in mind that would be simpler/shorter with CPAN-style support in place?
There was a time in Ireland (where I'm from) when the government built lots of roads because neighbouring England had a thriving economy, and lots of roads. It turned out the dependency was the other way around.
btw thanks for the new vocabulary: I'm going to "whomp" up some functions now :))
I know this is outrageous nitpicking, but there's a possible comment inaccuracy in ac.scm, in (define (ac s env) ...
; the next two clauses could be removed without changing semantics
((eq? (xcar (xcar s)) 'compose) (ac (decompose (cdar s) (cdr s)) env))
((eq? (xcar (xcar s)) 'complement)
(ac (list 'no (cons (cadar s) (cdr s))) env))
Expanding fn-position compose and complement in ac enable composition of macros. (rev:accum a (a 1) (a 2)) works for example although accum is a macro. I tried removing the removable clauses from ac, and indeed the rev:accum example no longer works.