Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

An interesting corollary to concept 5 (the fact that everything in Tcl is a string) is that this means that Tcl is actually homoiconic. It does it completely differently from Lisp, but still ends up in the same place: code and data have the same representation.


You can represent arbitrary C++ code as a string, too, and C++ has a fairly decent string type. Does that make C++ homoiconic? I wouldn't say so, because the structure of the code is lost when you represent it as a string and because C++ doesn't give you any way of using the code represented thus (e.g., there's no standard way to compile it).

(The second of those isn't strictly part of what's meant by homoiconicity. You could, after all, write your own compiler, just as you might write a metacircular evaluator in Lisp. But it seems like an important part of the spirit of the thing.)

Tcl may be homoiconic -- it's been years since I looked at Tcl and I don't remember anywhere near enough details to try to pronounce on this -- but if so, it isn't merely because it represents everything as strings. It'll be to do with simple string operations being able to do all the parsing you need (on account of the syntax being simple and/or there being string operations that do things like parsing out a {...} block of code), and with there being a usable eval.


Tcl has eval and uplevel, which allow you to easily execute arbitrary Tcl code within the language. You can easily implement macros, lambda expressions, list comprehensions, and more using these tools, if you want to.


TCL code in the form of a string is not a data structure the language provides you tools to manipulate past being able to execute it: if you wanted to write a macro you are forced to parse the string. While the code is conceptually a list of commands, each of which is a list of lists, with code strings as a special case of value that is itself really a list itself, those semantics are not what you type: code is a semi-colon separated list of lists (which could contain, of course, nested semicolons), and cannot thereby be parsed as any normal TCL data structure (nor can it trivially be run through split or something to get a normal TCL data structure). The square brackets are themselves somewhat special, and the white-space has complex semantics; variable substitution is a one-off feature. The language thereby has the property that code is data (so the example about C++ given by gjm11 was probably confusing, and even got me at first: I was about to write a response to him talking about how in C++ code is separate from data in a way that it isn't in TCL), but it isn't really "homoiconic" (which I then realized as I started working on that response, as it has been over a decade since I lived and breathed TCL, and all I had remembered was the abstract conceptual beauty as opposed to the nitty-gritty details of actually typing it; I started typing it, tried to manipulate the string, and failed). Due to this, I would quibble that you can easily implement macros: you actually first have to write a TCL parser (which people have done; if you search for tcl parser you find some TCL parsers written in TCL in the package index) to recover the structure of the code from the opaque data. Like, you may as well be coding in JavaScript: no one would claim JavaScript is homoiconic, but they do define a .toString() on functions which is supposed to return a string with code that could be evaluated back to a function... you technically can then write macros that take as an argument a function that is .toString()'d, run the code string through a JavaScript implementation of JavaScript's grammar (such as Narcissus), and then manipulate the result to return replacement code in the form of a new function... if you've ever worked in an actually-homoiconic language (like Lisp) this is a fundamentally different experience.


Hi, downvoters! Would you care to tell me what you disliked about my comment, and thereby help me do better in future? (Or allow me to defend myself if I don't see what you disliked as a fault.)

I should maybe clarify one point: I was not saying that Tcl isn't homoiconic (which is, e.g., why I said "Tcl may be homoiconic"). Only that the mere fact of representing everything as a string doesn't make it homoiconic.


This is one the reasons I like parsing HTTP requests through TCL. Everything in HTTP is a string, there are no numerals. Typecasting arguments from query strings is the source of many ills. It isn't much of a problem with TCL since like HTTP, everything is a string.

Everything else about web service backends in TCL is pretty sad and frustrating, though. Unless it's embedded, anyway.


Everything in TCL is a string. Until you treat it like a number. And it has a leading zero. Then it's octal.

(Understanding TCL lists are just delimited strings lets you do interesting things. Sometimes unintentionally.)


Interesting. I've never worked with Tcl, is it possible to write Common Lisp loop macro in Tcl?


I'm not familiar with lisp loop macros, but here is how this works.

For example the Tcl does not have try-catch-finally statement. If that happens in other languages you just need to accept it. In Tcl you can implement it yourself for example:

http://code.activestate.com/recipes/68396-try-catch-finally/


I like tcl, but in my experience it's no lisp.

You can do macro like things in tcl, but very often the evals and uplevels all worked to make my brain hurt in ways that writing cl macros never has.


It's not possible to write CL's loop macro per-se (tcl does not have macros, but commands/functions which are executed each time and there isn't an distinct macroexpansion/compilation phase), but it's certainly possible to write something that essentially matches behavior and user interface of loop (and it's probably significantly easier to do than writing loop in CL).




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: