Arc Forumnew | comments | leaders | submitlogin
~Tilde and macros
7 points by aston 6149 days ago | 21 comments
It kinda sucks that this works:

  arc> (litmatch "a" "aston")
  t
But this does not:

  arc> (~litmatch "a" "aston")
  Error: "Function call on inappropriate object #3(tagged mac #<procedure>) (\"a\" \"aston\")"
All can be repaired with a simple (def litmatch1 litmatch), which then beckons the question, why not always have something like that happen when the tilde operator comes in front of a macro?


3 points by lojic 6149 days ago | link

Are you sure the simple def fixes it?

  arc> (def litmatch1 litmatch)
  #<procedure: litmatch1>
  arc> (litmatch1 "b" "brian")
  nil
  arc> (~litmatch1 "b" "brian")
  t
  arc> (~litmatch1 "z" "brian")
  t

-----

4 points by rkts 6149 days ago | link

Why do we even have the tilde syntax? Isn't ~f the same thing as no:f?

-----

8 points by pg 6149 days ago | link

Yes, ~f means the same as no:f. So far I like the brief and distinctive look of negated functions thus: ~foo. But since potential symbol-syntax chars are rare, I might use ~ for something else one day if negated fns turn out not to be too common. There are currently only 9 in news.arc (1410 LOC).

Edit: Looks like there could be 4 more. Most of news.arc was written before ssyntax, so it's not maximally up to date.

-----

3 points by absz 6149 days ago | link

(1) Technically, it's the same as (complement f), which I believe is roughly equivalent.

(2) Because it's nicer-looking, especially with things like keep.

-----

4 points by aston 6149 days ago | link

But, unlike ~ and complement, no:litmatch works.

-----

8 points by pg 6149 days ago | link

no:litmatch only works in functional position, because (no:litmatch ...) is transformed in ac into (no (litmatch ...)).

To add to the confusion, it's a bug that ~litmatch doesn't work in functional position. There's a comment reminding me to fix that in ac.scm.

-----

1 point by parenthesis 6148 days ago | link

Wouldn't it make more sense for (~foo ...) to expand into (no (foo ...)) ?

-----

2 points by absz 6148 days ago | link

Not really, because that would make (keep ~foo lst) meaningless, and that's an important use of ~.

-----

2 points by cooldude127 6149 days ago | link

complement only works with functions. behind the scenes, it uses apply to call the original function. at first glance, i don't really see a reason that it couldn't just do the same as (compose no _)

-----

2 points by eds 6149 days ago | link

I know compose works on macros... but I'm not sure you are straight on, because compose uses apply as well. And the macro expansions look exactly the same.

  arc> (macex '(compose no litmatch))
  (fn gs1639 (no (apply litmatch gs1639)))
  arc> (macex '(complement litmatch))
  (fn gs1641 (no (apply litmatch gs1641)))
  arc> ((compose no litmatch) "a" "aston")
  nil
  arc> ((complement litmatch) "a" "aston")
  Error: "vector-ref: expects type <non-negative exact integer> as 2nd argument,
  given: \"a\"; other arguments were: #3(tagged mac #<procedure>)"
So what is going on here?

-----

3 points by cooldude127 6149 days ago | link

except calls to compose are optimized away in the interpreter. they are treated specially. look in the `ac' function in ac.scm. i'm guessing this is the reason.

-----

1 point by absz 6149 days ago | link

Ah! That must be the problem, yes. Good catch!

Now, what to do about the other case... there's still no reason it should bug out, it seems to me. Or rather, it should be implementable in such a way that it shouldn't.

-----

2 points by cooldude127 6149 days ago | link

mainly, we need an apply that works for macros. why would that not be possible, i wonder.

-----

5 points by pg 6149 days ago | link

What you're thinking of can be done, but only by calling eval explicitly. I.e. what you could do thus with or if it were a function:

  (apply or args)
you have to do thus with the real or, which is a macro:

  (eval (cons or args))
This is not surprising, because macros live in the world of expressions, not values.

-----

3 points by aston 6149 days ago | link

What you mean is, we need macros to be first class.

-----

1 point by absz 6149 days ago | link

Yes, we do. But if I recall (and I can't test, because the git "wiki" broke for later mzschemes again), apply does work for macros, except it evaluates all the arguments first, which breaks things like and. Someone should test that, though; as I noted, I can't.

EDIT: No, sorry. It doesn't work. My bad.

-----

4 points by nex3 6149 days ago | link

Just as a note, the wiki is fixed now.

-----

1 point by absz 6149 days ago | link

I saw, that's how I was able to test. Thank you for setting it up, by the way! And if you fixed it, thank you for that; if someone else did, thank them for that.

-----

3 points by nex3 6149 days ago | link

You're welcome :-). It would be wfarr who fixed this issue, though.

-----

1 point by cooldude127 6149 days ago | link

well, yeah. basically.

-----

1 point by absz 6149 days ago | link

Compose does something very similar behind the scenes as well, in fact. So there's no reason it should work either.

-----