Category:TXR: Difference between revisions

From Rosetta Code
Content added Content deleted
Line 55: Line 55:


Slices, even empty ones, are assignable places in TXR Lisp: we can easily replace a possibly empty section of a string, lisp or vector, with a sequence that is of different length, also possibly empty: for instance, if <code>x</code> contains <code>"abc"</code> then <code>(set [x 1..2] "foo")</code> changes <code>x</code> to contain <code>"afooc"</code>.
Slices, even empty ones, are assignable places in TXR Lisp: we can easily replace a possibly empty section of a string, lisp or vector, with a sequence that is of different length, also possibly empty: for instance, if <code>x</code> contains <code>"abc"</code> then <code>(set [x 1..2] "foo")</code> changes <code>x</code> to contain <code>"afooc"</code>.

The <code>group-by</code> function is a straight rip-off from Ruby.

Revision as of 02:16, 25 January 2014

This page is a stub. It needs more information! You can help Rosetta Code by filling it in!
Language
TXR
This programming language may be used to instruct a computer to perform a task.
Official website
See Also:


Listed below are all of the tasks on Rosetta Code which have been solved using TXR.

TXR is a new language implemented in C, running on POSIX platforms such as Linux, Mac OS X and on Windows via Cygwin as well as more natively thanks to MinGW.

TXR started as a language for "reversing here-documents": evaluating a template of text containing variables, plus useful pattern matching directives, against some body of text and binding pieces of the text which matches variables. The variable bindings were output in POSIX shell variable assignment syntax, allowing for shell code like

eval $(txr <txr-program> <args> ...)

TXR remains close to these roots: its main language is the pattern-based text extraction notation well-suited for matching large regions of entire text documents. That language has become powerful enough to neatly parse grammars, while the tool developed a Lisp dialect to round out the functionality and increase its power.

What's with all that @ stuff?

About the @ character: this serves as a multi-level escape in TXR. In the fundamental TXR syntax, which is literal text, this character is a signal which indicates that the object which follows is a variable or directive. Then inside a directive, the character indicates that the object which follows is a TXR Lisp expression to be evaluated as such, rather than according to the expression evaluation rules of the pattern language:

This is some literal text to be matched.
This text matches and binds @variable.
@(require  ;; this is the start of a directive in the TXR matching language
   @(> x 42) ;; this is an expression in TXR Lisp
)@# This is a comment in the pattern language.
Back to text.

In TXR Lisp, the @ character has more "meta" piled on top of it: @foo denotes (sys:var foo), and @(foo ...) denotes (sys:expr foo>). In any context which needs to separate meta-variables and meta-expressions from variables and expressions, this may come in handy. It's used by the op operator for currying, for instance (op * @1 @1) returns a function of one argument which returns the square of that argument. The implementation of the operator looks for syntax like (sys:var 1) and replaces it with the arguments of the generated lambda function. The @ character also appears in quasiliteral strings, where it interpolates the values of variables and expressions as text.

TXR is somewhat unusual in that the relationship between a domain-specific language (DSL) and general-purpose host language is reversed. Typically, at least in Lisp systems, DSL's are embedded into the parent language. In TXR, the "outer shell" is the domain-specific language for extracting text, and Lisp is embedded in it as "computational appliance". It doesn't take much to reach the Lisp though: a TXR source file can just consist of a single @(do ...) directive which contains nothing but TXR Lisp forms. Also, TXR Lisp evaluation is available from program invocation via the -e and -p options.

The second unusual feature in TXR Lisp is that the "tokens" in the pattern matching language are essentially themselves Lisp symbols and expressions. These "tokens" are used to create a block-structured language. This is quite odd. For instance a construct might begin with a @(collect :vars (foo)). This is a Lisp expression with interior structure, but to the parser of the pattern language, it's also basically just a token, like a giant keyword. IT begins a collect clause, and is followed by some optional material which may just be literal text, and must be terminated by the @(end) directive: another token-expression entity.

Dual Personality

From the solutions below, it is obvious that some of them make heavy use of the pattern language and little or no TXR Lisp. Others are quite the other way around, based entirely or almost entirely on Lisp, whereas others follow strategies of mixing the approaches.

Lisp Innovation

Although TXR Lisp is heavily based on prior work and strongly influenced by Common Lisp (for instance, there is a real nil symbol which is a list terminator and means "false", and it's primarily Lisp-2 dialect), TXR Lisp nevertheless manages to innovate within the world of Lisp.

Can't We All Just Get Along?

One major innovation is the way in which TXR Lisp closes the ages-old gap between Lisp-1 and Lisp-2, and the associated religious sectarian division it has caused. TXR Lisp recognizes that there are advantages both in having separate function and variable namespaces, and in having a single namespace: and it provides support for both approaches. The idea is devilishly simple. A special operator called "dwim" (do what I mean) is provided such that (dwim forms ...) basically denotes (forms ...), but with Lisp-1 style evaluation: any of the forms which are symbols are resolved according to a flattened namespace that combines variable and function bindings (with conflicts resolved in favor of variables). TXR Lisp programmers do not use the dwim operator directly, but rather the square bracket notation [a b c ...] -> (dwim a b c). So for instance, [mapcar list '(1 2 3) '(a b c)] zips together two lists. Using round brackets, it would have to be (mapcar (fun list) '(1 2 3) '(a b c)). Moreover, if foo is a variable that holds a function of one argument, it has to be called using (call foo arg). But with the "dwim brackets", it is just [foo arg]. The "dwim brackets" also support various funcall-extensions, like indexing into arrays and slicing and so on. If h is a hash then [h "a" 42] looks up the string a in the hash and returns the value, or else returns 42 if the key is not found. If a is an array, list or string, then [a 2..3] extracts a slice. On the other hand, "dwim brackets" do not support operators: [let (a b c) ...] is not valid; or rather, it expects a variable or function let to exist, ignoring the let operator. Operators are strictly in the Lisp-2 domain, which is fine because Lisp-2 is a cleaner model with regard to operators anyway!

Polymorphizing the Classics

In TXR Lisp, classic Lisp operations like mapcar, cdr or append work exactly like they are supposed to, when they operate on lists. However, most of the operations have been extended to also work with strings and vectors. So for instance, (mapcar (op + 1) "abc") nicely yields the string "bcd" where 1 has been added to every character code of the original string. (car "abc") yields #\a, a character, (cdr "abc") yields "bc", and (cdr "c") yields nil (rather than the empty string!) (Almost) everything proceeds from there.

One Quote to Bind Them

TXR Lisp dispenses with the distinction between quoted lists and quasi-quoted lists, in favor of an experiment to combine them. There one quoted syntax denoted by forward quote. This syntax supports unquoting. If you don't unquote anything, you get a regular quote. Splices are not spelled ,@ because we have had enough of the @ character, and because it is ambiguous: does ,@x mean "unquote (meta x)" or "splice x?" So the splice operator is denoted by an asterisk. Because there is only one kind of quote, there is some reduction in power in regard to mixing quotes and quasiquotes in one expression due to the ambiguity. The quasi-quote expander contains some hacks to make all the common cases work fine. Notably, the combinations ,'form and ,*'form (unquote quoted expression and splice quoted expression) are treated specially: the "comma cancels the quote", and so any unquotes inside form do not belong to the inner quote, but to the surrounding quote.

Good Hackers Borrow; Great Ones Steal

TXR steals ideas from libraries and languages related to Lisp. The op operator is inspired by Goo's op, and the cl-op library for Common Lisp which is also inspired by Goo's op.

Array and list slices are straight out of Python, right down to the half-open ranges (not including the upper endpoint), and negative values indexing from the tail of the array. The concept is further improved upon by allowing the Lisp symbols nil and t to be used as range indexes.

Slices, even empty ones, are assignable places in TXR Lisp: we can easily replace a possibly empty section of a string, lisp or vector, with a sequence that is of different length, also possibly empty: for instance, if x contains "abc" then (set [x 1..2] "foo") changes x to contain "afooc".

The group-by function is a straight rip-off from Ruby.

Subcategories

This category has the following 3 subcategories, out of 3 total.

Pages in category "TXR"

The following 160 pages are in this category, out of 160 total.