1. "Multi-word lines without leading parens are implicitly grouped with later indented lines."
2. "Indentation-sensitivity is disabled inside parens."
That's really all there is to it.
> is there any way to see what my code looks like if I were to type it using parenthesis?
It's a little clunkier than visualizing infix, but you can introspect on any function or macro. Here's an example session:
$ ./wart
ready! type in an expression, then hit enter twice. ctrl-d exits.
def (foo x)
if a b
c d
:else e
foo
=> (object function {sig, body, }) # wart doesn't print table values by default
(body foo)
=> ((if a b (c d) (:else e)))
Here you can see that turning (c d) and (:else e) into calls is probably not desired.
I kept looking and found that read has the functionality I was looking for.
(read)
5+5
=> (+ 5 5)
I also noticed that if I want to generate lists which are expressions, it is not as straightforward as it should be (I'm trying to get a list of the number 5 the symbol + and 5 again but wart for whatever reason rearranges them).
Yeah, that's a bug. I haven't yet bothered to create a version of read without the infix transform. For now you have to:
'(5 (+) 5)
If you decide to try to fix this I'd love to hear your experiences. The point of wart was to be easy to hack on, but I'm losing steam because it's been hard to get feedback on that score.
I'm going to have to familiarize myself with the internals before I actually try to fix it. After looking for a little bit, I think the issue is in the transform_infix function where it handles the quoting.
if (is_quote_or_unquote(n.elems.front())) {
list<ast_node>::iterator p = n.elems.begin();
while (is_quote_or_unquote(*p)) {
trace("infix") << "skipping past " << *p;
++p;
if (p == n.elems.end()) {
trace("infix") << "just quotes/unquotes " << n;
return n;
}
}
I would think that after you determine that the first element is a quote, you would just ignore the rest instead of going through and checking which ones are also quoted. Since I'm not that familiar with c++ or how the internals of wart work, I'm going to have to leave it to you to see if this is actually the problem.
Thanks for the investigation! Yes, that would be the way to disable transforms inside a quoted s-expr.
But I think that still would leave issues. For one, it is approximately as likely that a list innocuously contains a literal '+ as that we're constructing a fragment of code that is eventually intended to be eval'd. We need a way to say, "this is code" or "this is never going to be eval'd." A second issue is that quoting isn't the only way to read data. Imagine using read to read a list from a file. How would we suppress infix there?
I actually think reading data from a file is the bigger issue. Small quoted lists in code will be noticed, and can be replaced with some (klunky) combination of list and cons. It's far worse if you have a multi-megabyte file that silently gets corrupted because of one character.
I'm just wondering if the second rule is really such a good idea. If one wants to use indentation-sensitivity within parens, it is impossible. I'm not sure how often trying to write code like that would come up in practice, but I think the programmer should have the option in that case of whether indentation-sensitivity is actually being used (by using brackets or something else to make it clear).
Ok, interesting idea that I hadn't considered before.
As it happens, I've been watching a discussion about a different use for brackets: http://lambda-the-ultimate.org/node/4879. Lots of people (scheme, clojure, this liso guy) seem to have an idea about what to use brackets for, and it's not clear what the best use is for these precious punctuation characters.
I realized that we actually don't need to have a closing bracket to signal the end of the expression. We just need to implement something like the $ operator in haskell.
def (foo a b c)
if $ and
a = 5
b = 10
c = 15
prn "success"
prn "failed"
There should be enough information based off of the indentation to tell how it should be parsed. $ should mean something along the lines of everything indented after the next symbol is a single expression.
You'll like the old discussion on Bullet which had some similar ideas, including considering how to suppress paren-insertion inside such a special operator, etc.