Arc Forumnew | comments | leaders | submitlogin
3 points by waterhouse 2556 days ago | link | parent

Suggestion: No one should be trying to use the word "quote" as a variable name. Therefore, if (quote o) or (quote optional) or (quote opt) [depending on how verbose we want the word to be; we could even make all of these work] shows up in a parameter list, then the rest of the list shall be optional args. If desired, we could do something similar for keyword arguments. Model:

  (fn (a b 'opt (c 1) d e) ...) --> c,d,e optional args
  (fn (a b (quote opt) (c 1) d e) ...) --> same thing
  (fn ((a b)) ...) --> destructuring

3 points by bogomipz 2549 days ago | link

I like it. Could also be done with less parentheses but explicit nil, like rocketnia did in the ".o" approach:

  (a b 'opt c 1 d nil e)
On the other hand, the parentheses can be reduced with ssyntax when the default is a literal:

  (a b 'opt c.1 d e)


1 point by akkartik 2549 days ago | link

I like this! How about using ? as the separator?

  (a b ? c 1 d nil e nil)


4 points by waterhouse 2548 days ago | link

I dislike the idea of declaring anything to be a separator--and therefore a reserved, special word--that isn't already illegal to put in a parameter list.

...egad. It turns out that it is not just legal, but it works fine, to use "quote" as a variable name just like any other, in Arc and Common Lisp and Racket.

  > (let ((quote 2)) quote) ;Racket
  > (define quote 10)
  > quote
... So much for brilliant ideas. Hmm. On the other hand, if you actually do that, then Bad Things happen:

  > (define quote 10)
  > '(1 2 3)
  procedure application: expected procedure, given: 1; arguments were: 2 3
Meanwhile, CL does disallow defining a function named "quote". It also disallows using 'flet to create a local function named "quote".

Well, what do you think of forbidding people to rebind quote (locally or otherwise)? I think it's acceptable. quote is a fundamental part of Lisp. If it is rebound, then either that will screw up quoted things, or the Lisp parser will handle (quote blah) forms specially, in which case rebinding quote to a function and attempting to call it will fail (you'll just quote the arguments). In other words, either this will fail to return 12:

  arc> (let quote [+ _ 2] (quote 10))
Or this will cause a presumably unexpected error when '(1 2 3) is interpreted as something other than a quoted list:

  arc> (let quote [+ _ 2] '(1 2 3))
  Error: "application: bad syntax in: (1 2 3 . nil)"
I think both of these possibilities suck[1] and, for the purposes of formally specifying Arc, we should say "This is not supported; we recommend that an implementation throw an error when encountering an attempt to locally or globally rebind quote." I probably wouldn't make it illegal, but I'd make it print something like "COMPILER-WARNING: WTF, you're trying to redefine quote? This will probably not end well."

So, if using "quote" as a parameter is officially unsupported, then this officially makes room for "quote" to be used as a special marker in parameter lists. When a program that parses parameter lists encounters (quote blah), it should stop and say "Aha, this is not a legal parameter. What now?" And at this point we can give it whatever desired features in a nice, modular way.

In official Arc, we would have, say, "If blah is 'opt or 'o or 'optional, then proceed to interpret optional arguments." Then akkartik might add, "If blah is 'key, then proceed to interpret keyword arguments", and aw might add "If blah is 'as, then proceed to interpret coerced arguments", and these would be totally compatible extensions to Arc, as long as they didn't choose the same name.

I do think this is the way to go.

[1]A "Lisp-2 function/variable namespace separation" buff might say at this point, "Aha! See, with the namespace separation, this isn't a problem; you can use quote as a variable all you like and it creates no problems." Retort: "I might just as well want to locally create a quote function with flet, and then you have a problem. (And if your language doesn't let you locally bind functions, then it sucks.)" Example case:

  (flet ((quote (x)
           (format t "~S~%That's what she said!" x)))


1 point by akkartik 2547 days ago | link

Yeah you make a lot of sense.

I've been thinking more about making the arc transformer ('compiler' seems excessive) simpler and easier to add hooks into. I don't want to hardcode keywords as non-overrideable; instead I want new keywords like coerced to be easily added to the transformer.