Monday, May 31, 2010

After playing with Clojure for a little while, one feature that I really like about it is doc and doc-strings, which work just like doc-strings in Emacs Lisp. I can use find-doc and ns-publics to find or explore the available symbols. I'm sure that an emacs mode or an IDE could make the interface as nice as the Emacs Lisp interface, but the functionality is there.

In Java, I often use javap to see what the method signatures of a class were, and have sometimes wished that the Javadoc were also available in the same way. The Java compiler could have put the Javadoc in attributes in the class files, which would then be available to tools like javap.

When using hugs or ghci for Haskell, I like using :browse and :info. The name and type almost always is enough to convey what a function does. It would be nice to have a short description of relevant information not captured by the name and type, but that's somewhat rare.

In any case, if I really needed to, documentation for the standard libraries for all three of these languages are available online. For Clojure and Haskell, the source code is available. For Java, the class files can be disassembled, though the occasional native method would remain opaque.

I find Clojure compelling in a way that I do not find Python compelling. They are both dynamically typed, which is a minus to me for both. I'm neither drawn to nor repelled by the syntax of either. However, I like feel of the immutable data structures of Clojure better than the data structures of Python. I'm also going to play around with integrating Clojure code with Java code. And while I haven't explored multimethods or any concurrency features, I can see learning new concepts, perhaps even learning when volatile would be useful when writing in Java, when looking into them.

Monday, May 24, 2010

In the product I work on at work, there are modules that accept items of various content types. Somebody made a dumb extension that made text content a special case, so now I'm getting silly NullPointerException bugs assigned to me because null is being passed in for the content. It would have been much cleaner to just use "text/plain" as the content type without any new special case code.

Monday, May 17, 2010

It seemed inappropriate that I hadn't implemented Parenthesis Hell in a Lisp, so I decided to learn a little about Clojure, a new Lisp dialect. I didn't use any of the concurrency features of Clojure, which is one of its main selling points. However, a Parenthesis Hell interpreter doesn't need any mutable state.

(defn ph-eval* [expr scope input]
(loop [scope* scope]
(cond
(empty? expr) input
(contains? scope* (first expr))
((scope* (first expr)) (rest expr) scope input scope*)
:else (recur (scope* 'outer)))))

(defn ph-valid? [val]
(cond
(not (seq? val)) false
(empty? val) true
(not (seq? (first val))) false
(empty? (first val)) (recur (rest val))
:else (recur (cons (first (first val)) (cons (rest (first val)) (rest val))))))

(defn ph-fn [body]
(fn [expr scope input def-scope]
(ph-eval* body def-scope expr)))

(defn ph-quote [expr scope input def-scope]
expr)

(defn ph-let [expr scope input def-scope]
(if (empty? expr)
()
(loop [bindings (first expr) scope* {'outer scope}]
(cond
(empty? bindings) (ph-eval* (rest expr) scope* input)
(empty? (first bindings)) (recur (rest bindings) scope*)
:else (recur (rest bindings)
(assoc scope*
(first (first bindings))
(ph-fn (rest (first bindings)))))))))

(defn ph-car [expr scope input def-scope]
(let [expr* (ph-eval* expr scope input)]
(if (empty? expr*) () (first expr*))))

(defn ph-cdr [expr scope input def-scope]
(let [expr* (ph-eval* expr scope input)]
(if (empty? expr*) () (rest expr*))))

(defn ph-cons [expr scope input def-scope]
(if (empty? expr)
()
(let [head (ph-eval* (first expr) scope input)
tail (ph-eval* (rest expr) scope input)]
(cons head tail))))

(defn ph-if [expr scope input def-scope]
(cond
(or (empty? expr) (empty? (rest expr))) ()
(not (empty? (ph-eval* (first expr) scope input)))
(ph-eval* (first (rest expr)) scope input)
:else
(ph-eval* (rest (rest expr)) scope input)))

(defn ph-eval [expr scope input def-scope]
(let [expr* (ph-eval* expr scope input)]
(if (not (ph-valid? expr))
(throw (IllegalArgumentException. "Not valid Parenthesis Hell")))
(ph-eval* expr* scope input)))

(defn ph-eval
"Evaluate a Parenthesis Hell expression with optional input."
([expr] (ph-eval expr ()))
([expr input]
(if (or (not (ph-valid? expr))
(not (seq? input)))
(throw (IllegalArgumentException. "Not valid Parenthesis Hell")))
(ph-eval* expr
{'() ph-quote
'(()) ph-let
'((())) ph-car
'(()()) ph-cdr
'((())()) ph-cons
'(()()()) ph-if
'(((()))) ph-eval}
input)))

Monday, May 10, 2010

Here is are a couple of programs in Parenthesis Hell that print themselves. I've inserted a bunch of line breaks, but they should be on one line.

The first one uses the optional concat in the initial scope. The second does not, and I haven't successfully tested it, since my interpreter runs out of memory when running it.

The following uses concat:

((())((((()()))()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()()()(
)(()(()()(()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()(
)()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()()()()(
()(()()(()()(()(()()()()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()
()()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()()()()((
)(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(
()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()((
)(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()
()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()()()()(()((
)()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()(()(
)(()(()()(()()(()(()()()()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()
()(()()(()(()()()()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()(()()
(()(()()(()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()
()()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()()()()((
)(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(
()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()((
)(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(
()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()()()()(()((
)()()()()(()(()()(()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()(
)(()(()()()()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()()()()(()(()(
)(()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()()()()((
)(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()(
()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()
(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()((
)()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(
()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()
()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(
()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()
()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()((
)()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()(
)(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()
()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()(
)(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()
()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()
(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()(
)()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()
(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()(
)()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(
()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()
()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(
()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()(
)()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()((
)(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(
()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()
(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()
()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(
()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()((
)()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(
()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()
()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()((
)()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()
()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()((
)()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()(
)(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()
()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()(
)(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()
()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()(
)(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()
()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()(
)(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()
()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()
(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()(
)()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(
()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()(
)(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(
()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()
()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()
(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()((
)()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()((
)(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()(
)(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(
()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()
()(()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()
(()(()()()()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()()()()(()(()()
()()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()()()()(()(()()()()()(
()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()(
()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()()()()(()(()()(()()(()
(()()()()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))((())(()()())()((()(()))(()()()(()(()()()())))(()(()))((())
((())))(()(()))(()()()(()(()()(()))))(())(()()))()()))(()(()))(()()()(()(()
()()()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()()()(
)(()(()()()()()(()(()()()()()(()(()()()()()(()(()()()()()(()(()()(()()(()((
)()()()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()()()()(()(()()(()))
))))))))))))))))))))))))))))))))))))))))(()(()))((())((()())))((()())))

The following does not use concat:

((())((((()()))()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()()()(
)(()(()()(()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()(
)()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()()()()(
()(()()()()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()
(()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()()()()(()(()()(()()((
)(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()()
()()(()(()()()()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()(()()(()
(()()(()()(()(()()()()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()((
)()(()(()()(()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()()()()(()(
()()()()()(()(()()(()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()(()(
)(()(()()()()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()
()()()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()()()(
)(()(()()(()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()()()()(()(()
()()()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()()()()(()(()()()()()
(()(()()()()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(
)()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()(()()(()
(()()(()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()()()()(()(()()()(
)()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()((
)()(()()(()(()()()()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()
()(()(()()(()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()()()()(()((
)()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()()()()(()(()()()()()
(()(()()()()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()()()()(()(()(
)(()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()(()()((
)(()()()()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()()()()(()(()()(
)()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()()()()(()(()()(()()(()
(()()(()()(()(()()()()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()
()()(()(()()(()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()()()()(()
(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()()()()(()(()()()()
()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()(
)()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()(()()(
()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()
(()()(()(()()(()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()()()()((
)(()()()()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()((
)()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(
()()()()()(()(()()(()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()
()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()()()()(()((
)()()()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()()()()(()(()()(()(
)(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()
()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()
(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()(
)()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()(()()((
)(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()()
()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()()()()(()
(()()(()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()()()()(()(()()()
()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()((
)()()()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()(()(
)(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()(
)()()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()()()()
(()(()()(()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()
()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(
()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()
(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()(()()(()
(()()(()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()()()()(()(()()()
()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()()()()(()((
)()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()(()()
(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()
(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()()()()((
)(()()()()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()()()()(()(()()(
()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()
(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()((
)()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(
()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()
()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(
()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()
()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()((
)()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()(
)(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()
()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()(
)(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()
()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()
(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()(
)()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()
(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()(
)()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(
()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()
()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(
()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()(
)()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()((
)(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(
()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()
(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()
()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(
()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()((
)()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(
()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()
()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()((
)()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()
()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()((
)()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()(
)(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()
()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()(
)(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()
()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()(
)(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()
()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()(
)(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()
()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()
(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()(
)()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(
()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()(
)(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(
()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()
()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(
()(()()(()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()()(
)()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()((
)(()()()()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()(
()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()
()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()
(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()
(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()((
)()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()(
)(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(
()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(
()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()
()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()()()()(()((
)()()()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()()()()(()(()()(()(
)(()(()()(()()(()(()()()()()(()(()()()()()(()(()()()()()(()(()()()()()(()((
)()()()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()()()()
(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(()(()()(()()(()(()(
)(()()(()(()()(()()(()(()()(()()(()(()()()()()(()(()()()()()(()(()()()()()(
()(()()(()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()(()()(()(()()((
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))((())(()()())(((())))((()()())(((()))((())))
(((())())((())((())())(((()))((())))(()()))())(()()())((()())((())))(((())(
))(())(())((())())((()())((())))(()()))(()()))(()()))((((())))(()()())()(((
))((())())(()()()(()(()()()())))(())((())())((((())))((())))(())((())())(()
()()(()(()()(()))))(((())))(()()))()()))(())((())())(()()()(()(()()()()()((
)(()()()()()(()(()()()()()(()(()()(()()(()(()()(()()(()(()()()()()(()(()()(
)()()(()(()()()()()(()(()()()()()(()(()()()()()(()(()()(()()(()(()()()()()(
()(()()(()()(()(()()(()()(()(()()(()()(()(()()()()()(()(()()(()))))))))))))
))))))))))))))))))))))))))))))(())((())())((((())))((()())))((()())))

Monday, May 3, 2010

The tasq programming language

tasq is a macro-expansion language with a single task queue and a small set of operations.
Syntax

A tasq program is a sequence of declarations or comments, optionally separated by whitespace.

A comment starts with a dot (.) and continues to the end of the line.

A declaration is an identifier followed by zero or more operations, and ending with a dot (.). Whitespace may separate identifiers and operations, but is otherwise ignored.

An operation is an identifier or one of +, -, ~, or ?.

An identifier is an uninterrupted sequence of non-whitespace characters not including +, -, ~, and ?.

A declaration of an identifier with zero following operations adds the identifier to the end of the task queue.

A declaration of an identifier followed by one or more operations defines the identifier's expansion as those operations.

It is illegal to use undefined identifiers. It is illegal to have more than one definition for an identifier.
Execution

Execution consists of dequeuing and executing the top item of the task queue repeatedly while the task queue is not empty.
Operations

+ Write 1 to the output.
- Write 0 to the output.
~ Discard the next item in the task queue.
? Read one bit from the input. If 1 is read, do nothing. If 0 is read, discard the next item in the task queue. If at EOF, discard the next two items in the task queue.
identifier Append the identifier's expansion to the end of the task queue.
Examples

Hello world:

w-+--+----++--+-+-++-++---++-++---++-++++--+------+++-
+++-++-++++-+++--+--++-++---++--+----+----+----+-+-.w.

cat:

bit? 1 0. .Read a bit
0 -bit. .Write 0, handle next bit
1 +~. .Write 1, discard the ensuing -
bit. .Initial task queue

Self-printing program (formatted as multiple lines, but should be a 1-liner):

d.0-z.1+o.z--+-------++----.o--+-------++---+.q p.p--+------+++---+--+-+++--
---+-+-.d 0 1 1 0 0 1 0 0 0 0 1 0 1 1 1 0 0 0 1 1 0 0 0 0 0 0 1 0 1 1 0 1 0
1 1 1 1 0 1 0 0 0 1 0 1 1 1 0 0 0 1 1 0 0 0 1 0 0 1 0 1 0 1 1 0 1 1 0 1 1 1
1 0 0 1 0 1 1 1 0 0 1 1 1 1 0 1 0 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1
0 1 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 0 0 1
0 1 1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1 0 1 1 0 0 1 0 1 0 1 1 0
0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 1
0 0 1 1 0 1 1 1 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1 0 1 1 0 0 1 0 1
1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 0 0 1
0 1 1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1 0 1 1 0 0 1 0 1 0 1 1 0 0 1 0 1 1 0 1 0
0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1 0 1 1 0 0 1 0 1 1 1 0 0 1 1 1 0 0 0
1 0 0 1 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 1 0 1 1 1 0 0 1 1 1 0 0 0 0 0 0 1 0 1
1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1 0 1 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 0 0 1
0 1 1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1 0 1 1 0
0 1 0 1 0 1 1 0 0 1 0 1 0 1 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0
1 0 0 1 0 1 0 1 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1 0 1 1 0 0 1 0 1
1 0 1 0 0 1 0 1 0 1 1 0 0 1 0 1 0 1 1 0 0 1 0 1 0 1 1 0 0 1 0 1 1 0 1 0 0 1
0 1 1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1 0 1 1 0
0 1 0 1 1 0 1 0 0 1 0 1 0 1 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 1 0 0 1 1 0 0 1 0
0 q.

Interpreter


module Main(main) where

import Data.Map(Map,empty,insert,(!))
import Data.Bits(testBit)
import Data.Char(chr,ord)
import System.Environment(getArgs)
import Text.ParserCombinators.Parsec(CharParser,anyChar,char,getState,many,many1,manyTill,newline,noneOf,runParser,setState,space,spaces,(<|>),(<?>))

data Task = Out0 | Out1 | In | Discard | Task String

parse :: String -> String -> (String -> [Task],[Task])
parse file src =
either (error . show) id (runParser program (empty,[]) file src)

type Parser a = CharParser (Map String [Task],[Task]) a

program :: Parser (String -> [Task],[Task])
program = do
many (space <|> comment)
many statement
(map,queue) <- getState
return ((map !),reverse queue)

comment :: Parser Char
comment = do
char '.'
manyTill anyChar newline
return ' '

statement :: Parser ()
statement = do
id <- name
body <- many task
char '.'
many (space <|> comment)
(map,queue) <- getState
setState (if null body then (map,Task id:queue)
else (insert id body map,queue))

task :: Parser Task
task = do
t <- (char '-' >> return Out0)
<|> (char '+' >> return Out1)
<|> (char '?' >> return In)
<|> (char '~' >> return Discard)
<|> fmap Task name
spaces
return t

name :: Parser String
name = do
str <- many1 (noneOf "+-?~. \r\n\t\f\v")
spaces
return str

run :: (String -> [Task]) -> [Task] -> [Bool] -> [Bool]
run _ [] _ = []
run defs (Out0:tasks) input = False : run defs tasks input
run defs (Out1:tasks) input = True : run defs tasks input
run defs (In:[]) _ = []
run defs (In:_:[]) [] = []
run defs (In:_:_:tasks) [] = run defs tasks []
run defs (In:_:tasks) (False:input) = run defs tasks input
run defs (In:tasks) (True:input) = run defs tasks input
run defs (Discard:[]) _ = []
run defs (Discard:_:tasks) input = run defs tasks input
run defs (Task name:tasks) input = run defs (tasks ++ (defs name)) input

main :: IO ()
main = do
(file:_) <- getArgs
src <- readFile file
interact (fromBits . uncurry run (parse file src) . toBits)

toBits = concatMap (flip map [7,6..0] . testBit . ord)

fromBits (b7:b6:b5:b4:b3:b2:b1:b0:rest) =
chr ((if b7 then 128 else 0) + (if b6 then 64 else 0)
+ (if b5 then 32 else 0) + (if b4 then 16 else 0)
+ (if b3 then 8 else 0) + (if b2 then 4 else 0)
+ (if b1 then 2 else 0) + (if b0 then 1 else 0)) : fromBits rest
fromBits _ = []