Arc Forumnew | comments | leaders | submit | CatDancer's commentslogin
5 points by CatDancer 6676 days ago | link | parent | on: Does Arc need modules? Maybe not.

Can you go into detail a bit more on #3? How would I supply a dynamic prefix?

-----

1 point by cchooper 6676 days ago | link

Something like this would be a starting point:

  (mac def-with-prefix (prefix name args . body)
    `(eval (list 'def
            (read (+ (coerce ,prefix 'string)
                     "-"
                     (coerce ',name 'string)))
            ,args
            ,@body)))
called like this:

  (= prefix 'blub)
  (def-with-prefix prefix foo (x) (+ 1 x))
produces this:

  (def blub-foo (x) (+ 1 x)))
Note this is quite clunky because I couldn't find a better way to bind a dynamically determined variable in Arc. Set only takes a symbol as a first argument.

-----

1 point by cooldude127 6676 days ago | link

what is the point of the eval thing? isn't that what macros are supposed to do by themselves?

-----

2 points by cchooper 6676 days ago | link

You mean like this?

  (mac def-with-prefix (prefix name args . body)
    `(def
        (read (+ (coerce ,prefix 'string)
                 "-"
                 (coerce ',name 'string)))
        ,args
        ,@body))
It doesn't work, because

  (def-with-prefix 'blub 'foo (x) (+ 1 x))
expands to

  (def (read (+ ...blah...blah...)) (x) (+ 1 x))
and def will only take a literal symbol as the first argument. That's also the problem with set I mentioned before.

-----

2 points by shiro 6676 days ago | link

How about

    `(def ,(read (+ (coerce prefix 'string) "-" (coerce name 'string))) ,args ,@body)

-----

1 point by cchooper 6676 days ago | link

Doesn't work I'm afraid:

  (= pre 'blub)

  (your-def-with-prefix pre foo (x) (+ 1 x))
  => #<procedure: pre-foo>

  (my-def-with-prefix pre foo (x) (+ 1 x))
  => #<procedure: blub-foo>
Without being able to take the prefix from the value of a variable, the whole macro is pointless.

-----

1 point by eds 6676 days ago | link

Then why don't you just eval prefix?

  `(def ,(read (+ (coerce (eval prefix) 'string) "-" (coerce name 'string))) ,args ,@body)
It's still much less clunky than expanding the whole def under an eval.

-----

1 point by cchooper 6676 days ago | link

Still has a bug:

  (let pre2 'blub (your-def-with-prefix pre2 foo (x) (+ 1 x)))
  => Error: "reference to undefined identifier: _pre2"

-----

2 points by cooldude127 6676 days ago | link

that's because the macro gets expanded (and thus eval is called on pre2) before the let form is evaluated.

-----

1 point by eds 6676 days ago | link

Yeah, I see the problem with that.

cchooper, did you actually ever run your version? I can't make your orginal version work.

  arc> (def-with-prefix pre foo (x) (+ 1 x))
  Error: "reference to undefined identifier: _x"
And looking at the macro expansion, I'm not at all surprised:

  arc> (macex '(def-with-prefix pre foo (x) (+ 1 x)))
  (eval (list (quote def) ; my indentation
              (read (+ (coerce pre (quote string)) "-" (coerce (quote foo) (quote string))))
              (x) (+ 1 x)))
args and body would need to be quoted for this to work properly. And then it admittedly does what it is supposed to, but it becomes even uglier.

  (mac def-with-prefix (prefix name args . body)
    `(eval (list 'def
            (read (+ (coerce ,prefix 'string)
                     "-"
                     (coerce ',name 'string)))
            ',args
            ,@(map [list 'quote _] body))))

-----

1 point by cchooper 6675 days ago | link

Hmmm... it worked last night. I must have made a mistake when I copied it into the comment. Thanks for catching it.

Here's a slightly less clunky version:

  (mac def-with-prefix (prefix name args . body)
    `(eval (join (list 'def 
                  (sym (+ (coerce ,prefix 'string)
                          "-"
                          (coerce ',name 'string)))
                  ',args)
            ',body)))
I also tried doing it with nested quasiquotes but that just looked worse.

-----

1 point by shiro 6676 days ago | link

Ah, I got it.

-----

1 point by cooldude127 6676 days ago | link

yes, like that. there is no reason i can see for a macro to have to call eval except in the MOST EXTREME cases.

-----

2 points by cchooper 6676 days ago | link

Unfortunately, Arc makes this an extreme case. There's just no way to get the exact required behaviour in Arc without using eval.

In Arc:

  arc> (= foo 's)
  s
  arc> (set foo 4)
  4
  arc> foo
  4
  arc> s
  Error: "reference to undefined identifier: _s"
In Common Lisp:

  CL-USER> (setf foo 's)
  S
  CL-USER> (set foo 4)
  4
  CL-USER> foo
  S
  CL-USER> s
  4

-----

2 points by CatDancer 6677 days ago | link | parent | on: Really using git

it would be awesome if PG would expose his changes as Git commits

If someone is looking for a small project to take on, that sounds like an easy and useful task to volunteer for.

-----

6 points by byronsalty 6677 days ago | link

Well the real nice part would be PG himself using git and doing diffs against other repos to see what's festering in the community.

Right now the forum seems to be the only what of contributing patches to arc and this seems ripe for having things lost. (And who wants to bring up the same patch twice if it went unnoticed the first time).

-----

5 points by nex3 6677 days ago | link

Well, taking arcn.tar and merging it isn't that hard - I did it for arc1 and will probably continue to do so. It would just be nice if we could have more granular official patches.

-----

5 points by CatDancer 6680 days ago | link | parent | on: Python-like generators in arc

Do you mean to (re)define a global "yield" function on each call to defgen? In Arc, an internal def doesn't work like an internal Scheme define... it always sets the global top-level variable named as its first argument, it doesn't create a local binding as an fn or let would. (I couldn't tell if that's what you wanted to do or not).

-----

2 points by applepie 6680 days ago | link

Ugh, the code was wrong. I'm starting to think that Arc didn't really learn the lesson (i.e. getting scope right).

IMHO, it would be cleaner if def behaved more like Scheme's internal define (i.e. create a new local binding and set!).

I'd keep the current behaviour of def under the name defglobal or something.

-----

3 points by nex3 6680 days ago | link

I added an "lset" form to Anarki that works just like Scheme's define.

-----

2 points by CatDancer 6680 days ago | link | parent | on: Simplified w/bars

Ah, the first argument to rem is automatically testified, so

  (mac w/bars body
    `(apply pr
            (intersperse bar* (rem "" (macmap list tostring ,@body)))))

-----

8 points by CatDancer 6681 days ago | link | parent | on: Automatic .arc reloading in background

Nice! If you don't want to wait five seconds after saving your file, you could stick a call to your reload-check (without the sleep or the loop) in srv.arc at the point a request comes in:

    (def handle-request (s (o life threadlife*))
      (if (len< (pull dead srvthreads*) threadlimit*)
          (let (i o ip) (socket-accept s)
  +         (atomic (reload-check ...))
            (++ requests*)
though of course you wouldn't want to do this on a server that had a lot of requests coming in, since it would do the check on every request.

-----

2 points by byronsalty 6681 days ago | link

Yep this is definitely for dev only.

I found in practice that 5 seconds we fast enough, I would save the file, switch to browser and refresh and it would be there. Of course 5 seconds is the worst case - 2.5 seconds would be the average.

-----

1 point by CatDancer 6681 days ago | link | parent | on: New version

mkdir -p

-----

1 point by CatDancer 6681 days ago | link | parent | on: New version

Rather bizarrely, on my Linux system at least, make-directory is creating directories with the sticky bit set... and I didn't see anywhere in the MzScheme's manual a way to set the umask. Perhaps someone else will have better luck.

If this can be fixed, the make-directory* function in the MzScheme file.ss library will usefully create intervening directories, like mkdir -p does.

-----

3 points by elibarzilay 6680 days ago | link

That was fixed in version 371.

-----

1 point by CatDancer 6682 days ago | link | parent | on: Capturing expression output and errors

That's true.

-----


In arc0,

  arc> (on-err details (fn () (/ 1 0)))
  "\"/: division by zero\""
can you give me an example of when you'd want that?

-----

1 point by CatDancer 6688 days ago | link | parent | on: Musings on Language Design

Hmm, Language::MzScheme isn't compiling against MzScheme v352. The documentation says it works with MzScheme v200 or greater, so I suspect it might not have made the transition to the v300 series.

-----

More