Saw this on LWN: http://q-lang.sourceforge.net/
Looks interesting, and reminiscent of symbolic algebra systems like Mathematica. Also, the website mentions dynamic typing and "Batteries Included", which made me think of Python. Damned silly name, though (perhaps pre-Google?). Anybody here used it? Snippet from the FAQ: 2. Yet another "Haskell for the poor"? Not quite. Even though the syntax and some of the stuff in the standard library looks superficially similar, Q is different in a number of ways: * First and foremost, Q is an equational rather than just a functional language, meaning that it is based on general term rewriting instead of the lambda calculus (which is just one, and very special, rewriting system). In particular, Q has no a priori distinction between "constructors" and "defined" function symbols, and argument patterns are not restricted to "constructor terms". This allows you to have symbolic evaluation rules like the following distributivity rule: X*(Y+Z) = X*Y+X*Z. Such rules are not allowed in ML and Haskell because they violate the "constructor discipline". Moreover, the Q interpreter also happily reduces expressions involving variables, so that you can try your definitions with symbolic inputs (e.g., map F [X,Y] will evaluate to [F X,F Y]), which is quite useful for debugging purposes. * While other functional languages are either "eager" or "lazy", Q tries to give you the best of both worlds: It uses eager (call-by-value) evaluation by default (which lends itself to an efficient implementation), but also allows you to define your own special forms, which can be used to implement both call-by-name functions and lazy data constructors. Using special forms you can also define your own "meta functions" which manipulate arbitrary (not necessarily irreducible) expressions as literal terms. This gives you full control over the reduction strategy, where this is desired, as well as a kind of "macros" and "self-modifying programs", since constructs like lambda abstractions can be analyzed, transformed and constructed in many ways before they are actually evaluated. * Q uses dynamic typing. This has become a rare feature in contemporary functional languages, which usually employ a Hindley/Milner type system which offers more safety at the expense of restricting polymorphism. Q gives you back the flexibility of good old Lisp-style ad-hoc polymorphism and even allows you to extend the definition of existing operations (including built-in functions and operators) to your own data types. Moreover, Q has a Smalltalk-like object-oriented type system which supports data encapsulation and (single) inheritance. This makes it possible to manage complex, polymorphic data with ease. * Q takes the pragmatic route in that it provides (monad-free) imperative programming features such as imperative I/O and mutable data cells, similar to the corresponding facilities in ML. While one may argue about these, they certainly make life easier when programming complex I/O stuff such as graphical user interfaces. * Last but not least, the Q programming system comes with batteries included. There are quite a few add-on modules interfacing to third-party libraries which, while not as comprehensive as the facilities provided by traditional scripting languages like Perl and Python, allow you to tackle most practical programming problems with ease. In particular, multimedia and computer music is an area where Q shines, providing facilities to handle graphics, digital audio and MIDI in a convenient and efficient manner (efficient enough for soft realtime applications), which go well beyond what is currently being offered for other functional languages. Some of Q's flexibility comes at a price. In particular, Q's symbolic evaluation capabilities as a term rewriting language dictate that the language is essentially exception-free. This means that an "ill-formed" expression (such as "division by zero" or, more generally, the application of a function to data for which there is no corresponding definition) does not, by default, raise an exception, but instead the expression is already in "normal form", i.e., it evaluates to itself. As a remedy, Q provides facilities to add explicit error rules which raise exceptions, and to handle exceptions in a suitable manner. Another limitation is that Q does not allow you to have arbitrary local definitions in the style of Haskell and ML's "let" and "where" clauses. In Q, "where" clauses are limited to variable definitions (similar to Haskell's pattern bindings), but local rewriting rules are not supported as they would wreak havoc on the term rewriting semantics. You will also notice that Q lacks most of the syntactic sugar found in Haskell. This is partly due to my laziness, but it also keeps the language and the core system simple. Using Q's symbolic processing capabilities, the usual bits like lambda abstractions, pattern matching conditionals and list comprehensions can easily be written in Q itself (although this does not offer quite the same performance as when they are provided as builtins, of course). John -- http://mail.python.org/mailman/listinfo/python-list