I suppose Qi's greatest "innovation" is their datatyping scheme which allows the definition of datatypes based on C. A. R. Hoare's Sequential Calculus. I haven't read the paper; but I suppose it might be worth looking into. Basically, it's defining a datatype based on a set of rules.
I'm not sure how useful it would be in Arc, Qi and Arc have very different goals. Qi tends toward functional programs and often breaks away from lispyness, while Arc holds simplicity and elegance up as its goals. Arc also wants to stay lispy, albeit adding a few useful shortcuts (though I'm still on the fence with the new .! syntax). Personally, speaking, I don't see the datatypes Qi has as particularly useful unless you also adopt some sort of static typing scheme as well and I'm pretty sure one of Arc's goals is NOT to do that.
Implicit Function Currying is also allowed by Qi. It's useful in some cases and wouldn't HURT adding to the code; though the people who seem to be saying it would dramatically improve the brevity of Arc code are overestimating its effect; Arc has a lot of optional parameters which could make currying useless for a lot of the places it is used in Qi. For example, (+ 4) which curries an addition operating to the next number that is passed to it. In Arc, this is would return 4. I'm unconfident about which way is the right way.
Qi is certainly a decent language for Functional Programming Enthusiasts but doesn't have a lot to offer Arc. Maybe their new class system which is coming around in Qi II would be useful to adopt, but I'm afraid I've never seen it in action myself so I'm unsure of its usefulness.
Something very useful, which you might consider adding to the standard is something similar to Kenny Tilton's Cells. I'd be interested in seeing how someone would adopt Cells to use in, say, a web application. It could be very useful.
I am working on a "lite" version of Cells for Arc as we speak
(rough start here http://common-lisp.net/cgi-bin/viewcvs.cgi/kennysarc2/cells-...) and I do think a logical step after that would be exploration of applying that to a web app. Unfortunately I have not mucked with interwebby programming so I really would not know where to start. And it might make more sense for me to start with a Common Lisp library such as Hunchentoot. Stay tuned.
Wow Cells! All right, I just heard a lot of enthusiasm for Cells on c.l.l but never managed to grok much of it (insufficient docs IMO); it would be interesting how you handle the mutation of objects - there's no hook in Arc for that yet.
From the looks of this framework it's a test specification.
Incidentally, arc.arc already defines an (obj ...) macro. Do you intend to redefine it?
Thanks, but I think all the enthusiasm on c.l.l is from me. :) Maybe when I provide a Web app example people will get fired up. (I am a dinosaur, thought a desktop GUI would do the trick);
http://common-lisp.net/project/cells-gtk/
As for controlling change, right, my-obj!my-slot will be a backdoor, Arcells (name?) will have to work via readers/writers that invoke the Arcells engine.
Framework? Test spec? What I have so far is merely motivational examples (and I am using the OBJ macro, not redefining it):
http://smuglispweeny.blogspot.com
Look for (+ Arc Cells) Baby Steps, which I am mopping up once the caffeine hits my cortex. When done I'll submit a new thread.
(def pair (xs (o f list))
" Applies pairs of elements to the function `f'.
See also [[tuples]] [[map]] "
(if (no xs)
nil
(no (cdr xs))
(list (list (car xs)))
(cons (f (car xs) (cadr xs))
(pair (cddr xs) f))))
(defpat *defpat-pair
" Example/testcase for defpat in redefining
the `pair' function. "
((x y . zs)) `((,x ,y) ,@(*defpat-pair zs))
((x y . zs) f) `(,(f x y) ,@(*defpat-pair zs f))
((x) . _) `((,x))
(() . _) ())
(def map1 (f xs)
" Return a sequence with function f applied to every element in sequence xs.
See also [[map]] [[each]] [[mappend]] [[maps]] [[andmap]] [[ormap]] "
(if (no xs)
nil
(cons (f (car xs)) (map1 f (cdr xs)))))
(defpat map1-pat
(_ ()) ()
(f (x . xs)) (cons (f x) (map1 f xs)))
Do you have an example of a function you might write in an application, rather than the definition of one of the basic list traversal operators? As I said in the Arc Challenge, pattern-matching looks great when it's used for those, but tends not to be so useful in applications, precisely because operations like map, once they're defined, give you so much of what you need from pattern matching.
I've only read a bit and dabbled myself. I particularly liked the currying and partial application that I saw in Haskel. It just seemed like a fundamentally good idea to me. Possibly even axiomatic. The impression I got was that it added power in flexibility of function composition.
Regarding pattern matching & guards, I have even less experience with that, but the functional folks are certainly enamored with them. There was a thread on comp.lang.lisp regarding a symbolic simplifier that was apparently much more concise with pattern matching.
Hopefully some functional experts will come along to articulate the benefits.
partial application is something I always miss in lisp. I often find myself writing anonymous functions that would be much shorter with partial application. here are a few examples from some of my own CL code (pay attention to the second let binding):
I also enjoy currying and "pointfree" style. However, wouldn't it require giving up functions that take an arbitrary number of arguments? (In fact Scala has both, but it required introducing a special syntax.)
I find that Arc's shortcut closure [] notation is a surprisingly good curry-substitute. For example:
(map (act w) locs-to-check) ; currying
(map [act w _] locs-to-check) ; only one token longer
there's something to that. i didn't really think about it, but that might just be fine. that's actually exactly what scala's explicit partial application looks like, with the underscore.
i honestly haven't been doing a whole lot of practical arc programming. CL and Slime have spoiled me to the point where I find it difficult to use a language that doesn't have that convenience
Qi is completely type inferring, so it proves the type correctness of the code at compile time from a minimum number of declarations, like the ML family of languages.
However, as this is optional, it can also be switched off in places to handle code that the type system can not prove correct.
To make a similar system work, you'd have to label the inputs and return type of each function, and enforce the consistency of this, all at compile time. There is a complete prolog system buried in QI allowing the types to self reference and be turing complete in terms of complexity.
Having said that, the whole of QI is only meant to be 4k lines of common lisp and under an MIT license, so it'd be quite easy to port the interesting bits of it once the core of arc has stabilised.
pg, I was referring to Jekyll's explanation of optional typing. The 'maybe' means that I don't know the value in it, I've just heard that some people like it.