Arc Forumnew | comments | leaders | submitlogin
2 points by rocketnia 3696 days ago | link | parent

"The next one refers to s and str as well. Is that intended?"

Yes. Only <s> appears in the pattern itself, but the meaning of <str> is explained by "...where <str> is the string name of the symbol <s>."

---

"Also, I don't follow the distinction between the string case and the symbol case."

Did you see this part? -- "(That may look simple enough, but a completely different symbol pattern applies when matching a list element. See below.)"

A symbol which occurs in a list acts as a hybrid keyword/positional argument. A symbol by itself acts just like a string.

---

Sorry I'm being terse with this stuff. I found it hard to express my points in informal English, which is why I went with a spec document style in the first place.

Let's see...

My motive is to show you a way your desired features can be accomplished in an extensible ravioli style, rather than one big chunk of spaghetti. What you want is achievable with a simple enough collection of parser combinators, although sometimes their interfaces may be unusual due to expression evaluation being part of the parsing process.

For instance, in the system I gave, the parser combinators use a few unusual design patterns:

- The combinators must take in an evaluation environment.

- The combinators frequently quote a value so they can pass it off to another combinator that may eval it again. (I think I've seen you use this style before, actually.)

- The combinators must sometimes return the evaluated expression, just so that the (<a> | <b>) pattern can avoid double evaluation.

Another important point I'm making is that you probably don't need to reorder the argument list for the purposes of keyword arguments. My system instead (effectively) reorders the parameter pattern so the keywords are processed first.

I got this system a bit wrong because I don't support multiple keyword aliases for the same parameter. My (<a> | <b>) pattern instead binds multiple parameter variables to the same argument value, so I got that backwards.



2 points by akkartik 3696 days ago | link

This seems really useful. I got the motivation off the bat, but I still don't understand the spec. Can you give an example session showing how functions are defined, and how they are called?

-----

2 points by rocketnia 3696 days ago | link

Okay, I'll give that a try. Let's say we're defining a function and using it like this:

  > (def foo '(a b)
      (list a b))
  > (foo (+ 1 1) (+ 2 2))
  ((+ 1 1) (+ 2 2))
Let's vary some things here:

  '(a b)             ; the parameter list
  (a b)              ; the args to (list ...)
  ((+ 1 1) (+ 2 2))  ; the args to (foo ...)
  ((+ 1 1) (+ 2 2))  ; the result
  
  (baz)
  (baz)
  ((+ 1 1))
  ; Error! Can't make the function call (2).
  
  '(a b c)
  (a b c)
  ((+ 1 1) :c (+ 3 3) (+ 2 2))
  ((+ 1 1) (+ 2 2) (+ 3 3))
  
  '(a :b b c)
  (a b c)
  ((+ 1 1) (+ 2 2))
  ; Error! Unbound variable b in expression (list a b c).
So I have some more kinks to work out, lol. I finally appreciate your predicament. :)

The (baz) issue is caused by the complexity of the fact that in a normal function call, each of the arguments should be evaluated, but the list of arguments shouldn't. So if the traditional Arc parameter list (baz) is a pattern, it should destructure an unevaluated list in such a way that the baz pattern inside operates on an evaluated version of the list's first element.

It would be a lot simpler if we wrote this argument list differently:

  > (def foo (baz) ...)  ; doesn't work
  > (def foo `(,baz) ...)
  > (def foo (arg-list baz) ...)
      ; where (arg-list ...) is a pattern special form
I think that last one is promising, because then we can just write (baz) and the macroexpansion of (def ...) can insert that into (arg-list baz) for us. Then we get to have slight differences between how parameter lists work and how list destructuring works.

As for the "unbound variable b" issue, I think that could be solved by having each pattern take an optional current expr, rather than a mandatory one. My exact implementation of this would probably vary substantially based on what else I was trying to do. I might want a guarantee of which variables will be bound by a pattern long before there's an actual argument list to match it against, for compilation purposes and such.

-----