I've pretty much made up my mind on this, so please don't feel like you have to take time to respond point-by-point. Unless you've seen a gaping hole in my reasoning, anyway, then by all means, have at it.

On 11/26/2012 05:41 PM, Eli Barzilay wrote:
Two hours ago, Neil Toronto wrote:
For example, it's common to have arrays of Indexes, or (Vectorof
Index), which would have to print like this with implicit quoting:

    (array `#[,'#(0 0) ,'#(0 1)])

Just working out the algorithm to print such a thing made me want to
curl up and whimper.

Three sidenotes:

1. You probably mean (array `#[,`#(0 0) ,`#(0 1)]), right?

The inner quasiquotes can be quotes because #(0 0) and #(0 1) are vectors, not array rows. If they were array rows, they still shouldn't need to be quasiquoted. Well, depending on design...

Array rows don't exist as separate objects (an array is just a function), so I have a hard time intuiting what it means to quote the inner ones. But here are some (just some) design options:

 1. Allow a quote just on the outer "#[...]" and have it apply to all
    nested "#[...]".

 2. Allow a quote on the outer "#[...]" and have it apply to all
    nested "#[...]", but allow them to override with their own quotes.

 3. Allow quotes at any level, unpropagated.

 4. Avoid difficulty altogether by having array syntax not quote
    its elements.

#1 might be easy. #2 might be cool, but complicated. #3 is kind of weird, and I think it means the only quotes that matter are the innermost. For all of these, there are additional design options. For example, for #3, should quasiquoting outer rows be necessary if you want to quasiquote inner ones? For #2, how would one spell "override" in a way that distinguishes it from "element"?

#4 avoids all these choices, and that's what is currently implemented.

3. And besides, doing such algorithms is usually easier than it
    sounds.  (And IME, they're a perfect example where developement
    with test cases makes things way easier...)

I'm okay with inventing apparently complicated recursive algorithms that eventually come down to a few well-chosen rules. (That's language semantics in a nutshell.) My problem has been *coming up with the test cases* for the various options I listed above.

Now, I know where your brain just went, so let me head it off. You were about to reply with a bunch of starter test cases or a load of helpful hints. (Because that's who you are... and I appreciate it!) Let me make a case for not developing another set of array parsing/printing algorithms first, starting with your example:

For example, I'll need to write something like

   (define (±1 i)
     (array `#(,(sub1 i) ,i ,(add1 i))))

make it return a 3x3 array, and you get some less convenient thing
like

   (define 1- sub1)
   (define 1+ add1)
   (define (±1 i j)
     (array `#(#(,(list (1- i) (1- j)) ,(list i (1- j)) ,(list (1+ i) (1- j)))
               #(,(list (1- i)     j ) ,(list i     j ) ,(list (1+ i)     j ))
               #(,(list (1- i) (1+ j)) ,(list i (1+ j)) ,(list (1+ i) (1+ 
j))))))

I wouldn't want to write that, either. Right now, you'd write

  (array
   #[#[(list (1- i) (1- j)) (list i (1- j)) (list (1+ i) (1- j))]
     #[(list (1- i)     j ) (list i     j ) (list (1+ i)     j )]
     #[(list (1- i) (1+ j)) (list i (1+ j)) (list (1+ i) (1+ j))]])

The vector syntax just delimits rows; it never quotes. Square parens aren't required, but make rows easier to distinguish. Arrays' custom printers print square parens, which gives feedback when a user is confused about whether #(...) means a row or a vector-valued element.

Quotes and quasiquotes stop the `array' macro's recursion into rows, so quotes always mean "this is an element". For example, this is a zero-dimensional array that contains a vector:

  (array '#(0 1 2 3))

Here are my reasons for leaving it as it is:

 * Most array elements will be self-quoting anyway (numbers, strings,
   other primitive types).

 * It's easy enough to remember the exception "quote literal vectors".
   Also, Racket's printer writes an explicit quote before literal
   vectors, so arrays of array indexes parse and print the same.

 * I'm having a hard time with test cases for implicitly quoted array
   rows, which means math/array users would probably have a hard time
   reasoning about it as well.

 * There are enough possible design choices that give rise to similar-
   but-subtly different behavior that it would be easy for users to
   get confused about the actual rules.

At any rate, I'm all for simple. Thanks for hashing this out with me.

Neil ⊥

_________________________
 Racket Developers list:
 http://lists.racket-lang.org/dev

Reply via email to