Arc Forumnew | comments | leaders | submit | evanrmurphy's commentslogin

> Hey, I have a wild idea. Anarki's the most active Arc community project, right? Why not make a GitHub Pages site for Arc and let it be public-push?

You could get pretty far with that and Github gists. Except that they don't do syntax highlighting for Arc: https://gist.github.com/729894

-----


This looks nice! Definition, examples, "see also", source, and the best feature of http://php.net/manual (i.e. comments)... seems very thorough.

-----

1 point by evanrmurphy 5401 days ago | link | parent | on: Extend Arc's ssyntax?

Thanks for the tip, this is working well. The only minor issue I'm still dealing with on this is how to strip the dot of all special meaning except in the context of rest parameters.

By adding the dot ssyntax exception in ac and not applying the read-normal macro from the OP to #\., I've gotten this to work so long as dot is inside the scheme bars:

  ; Dot treated as a symbol when inside the bars

  arc> (= |.| 2)
  2
  arc> (is (+ 1 1) |.|)
  t

  ; It still works in the rest parameter context

  arc> (def foo (x . args)
         `(,x ,@args d))
  #<procedure: foo>
  arc> (foo 'a 'b 'c)
  (a b c d)

  ; But it doesn't work as a symbol without the bars.
  ; Note that (read-normal #\.) can make this work but
  ; it breaks the rest parameter case.

  arc> (= . 2)
  Error: "map: expects type <proper list> as 2nd argument,
  given: 2; other arguments were: #<procedure:ac-niltree>"
So I'm about 3/4 of the way there. :)

-----


Thanks for the link to Guide: Racket. I've also had trouble getting into Racket's documentation, but this looks like a much more accessible starting point than Reference: Racket.

-----

1 point by evanrmurphy 5409 days ago | link | parent | on: Configuring (nsv)

I think nsv takes the port as an argument. It defaults to 8080, but if you run (nsv 80) then it will serve on localhost:80. Do this on a VPS such as Linode or Slicehost, configure your domain name servers to point to that VPS, and then your site will be accessible on the web via that domain.

-----


I'm fascinated with this topic. Related to previous threads on this forum such as:

http://arclanguage.org/item?id=1917

http://arclanguage.org/item?id=2003

http://arclanguage.org/item?id=5052

-----

1 point by evanrmurphy 5413 days ago | link | parent | on: Arc Conference

1. Silicon Valley or some city in Texas would be best for me. I could possibly attend somewhere else in North America, but going further than that would be beyond my means.

2. Anything!

3. I might like to talk about web-based REPLs, compiling Arc to JavaScript or some related topic.

4. Any time of year is fine, but can we do it over a weekend rather than during the week?

5. Sorry for the tardy response!

-----


> But there are many instances it has been used on single symbols like !id. How do I interpret that?

a!b and (!b a) are equivalent:

  arc> (= a (table))
  #hash()
  arc>(= a!b 42)
  42
  arc> a!b
  42
  arc> (!b a)
  42
  arc> (is a!b (!b a))
  t
Hope this helps.

-----

2 points by rick_2047 5415 days ago | link

Ya I learned that, but that still doesn't solve the problem I have. Please see the edit.

-----


If you run the arc server as a thread, you can load in files while it's still running or restart the server without killing the arc process:

  ; Start the arc server in a thread called t*

  arc> (= t* (thread (asv)))
  #<thread: t*>
  arc> ready to serve port 8080

  ; Load a file while the server is still running  
  ; Every function and macro in arc.arc is redefined (ellipsized here for brevity)

  arc> (load "arc.arc")
  *** redefining caar
  *** redefining cadr
  *** redefining cddr
  ...

  ; Stop the server without terminating the arc process by
  ; breaking the thread

  arc> (break-thread t*)
  #<void>
  arc> user break

   === context ===
  /home/evanrmurphy/programas/arc/arc3.1/ac.scm:1040:20: socket-accept
   handle-request-1
   gs1046
  zz

  ; Restart the server by creating the thread anew

  arc> (= t* (thread (asv)))
  #<thread: t*>
  arc> ready to serve port 8080

-----

2 points by hasenj 5417 days ago | link

Thanks Evan, nice trick!

Now, can we watch filesystem for changes?

I suppose we can sleep and poll the timestamp, but I'm running into a problem, mtime is defined in lib/files.arc,

The way I'm settings things up, my experimental "app" is in a completely isolated folder, and once I'm in there, "lib/files.arc" is no longer in the current directory, how should I go about loading stuff from "lib/"?

For now I only need the 'mtime' function so I just snatched it, but I hope there's a better way of importing standard libs.

Otherwise, here's a little file watcher I just wrote, seems to work with my tiny test case:

    (def mtime (path)
      " Returns the modification time of the file or directory `path' in
        seconds since the epoch. "
      ($.file-or-directory-modify-seconds path))

    (= file-ts* (obj))
    (def file-ts-changed (file-name)
        (no:is (file-ts* file-name) (mtime file-name)))
    (def update-file-ts (file-name)
         (= (file-ts* file-name) (mtime file-name)))

    ; watch file system for updates to file-name
    ; and run 'delegate' when file is updated
    (def watch (file-name delegate)
         (update-file-ts file-name)
         (while (no (file-ts-changed file-name))
                (sleep 2))
         (delegate)
         (update-file-ts file-name))

    (def watch-load (file-name)
         (repeat 2 (prn))
         (pr "watching " file-name " for changes ..")
         (watch file-name 
                (fn() (load file-name) (pr "reloaded " file-name))))

    (watch-load "web.arc")

-----

1 point by bogomipz 5416 days ago | link

Just a couple of comments on the watch function:

1. Shouldn't the last line be (watch file-name delegate) so that it continues to watch after the first update? Or should that be optional?

2. It might be a good idea to pass file-name to the delegate. Not strictly necessary, and doesn't give any benefit in this example, but it could mean that you sometimes don't need to use a fn as the delegate. If you didn't want to pr "reloaded" for instance, you could just do (watch file-name load).

3. Is the hash table really necessary? Here is a version without it:

  (def watch (file-name delegate)
       (let ts mtime.file-name
         (while (is ts mtime.file-name)
                (sleep 2))
         (delegate)))

-----

1 point by hasenj 5416 days ago | link

I put the call to watch as the last line inside the file itself.

And the hash table is there because I initially wanted to watch multiple files at the same time. But I suppose if the main file in the web app loads the other files, then it's not needed at all.

The other thing I did is running the (asv) thread only once by checking for an unbound symbol, so that when the file is reloaded it doesn't run the server again.

  (def srvr ()
    (if (no (bound 't*))
      (= t* (thread (asv)))))

  (srvr)

-----

1 point by bogomipz 5415 days ago | link

Ah, so loading the file makes it watch itself. You need to do the load in a thread then?

I still fail to see how the hash table helps since my version above should do exactly the same as yours. I would see the point if you made a thread check all files in the table, and made the first call to watch launch the thread, while subsequent calls just add entries to the table.

-----

3 points by hasenj 5414 days ago | link

Well actually, I'm putting the (asv) call in a thread and making it so that reloading the file doesn't restart the server:

  (mac set-once (s v)
       `(if (no:bound ',s)
          (= ,s ,v)))

  (set-once t* (thread:asv))
Watching for changes is not running in a thread, it's just the last line in my "web.arc"

And you're right, the hash-table is not needed at all. That was a premature design.

I actually re-wrote it a bit:

  ; watch the result of (func) for change
  ; and run 'on-change' when value changes
  (def watch-fn (func on-change)
       (let init (func)
           (while (is init (func))
              (sleep 2))
       (on-change)))
  
  ; watch the value-exp expression for changes
  ; and run on-change-exp when it changes
  (mac watch (value-exp on-change-exp)
       `(watch-fn (fn() ,value-exp) (fn() ,on-change-exp)))
  
  (def watch-file (file-name deleg)
       (watch (mtime file-name) (deleg file-name)))
  
  (def auto-reload (file-name)
       (prn "w/auto-reloading " file-name)
       (watch-file file-name load))
  
  (auto-reload "web.arc")

-----

1 point by evanrmurphy 5433 days ago | link | parent | on: Pervasive keyword args for arc

I like this. Bravo. It's neat!

I'm also intrigued by your whitespace pattern:

  (def foo(a b) (cons a b))  ; no space between foo and its args
I'd always seen it one of these ways:

  (def foo (a b) (cons a b))

  (def foo (a b)
    (cons a b))
Omitting that space helps my eye to logically group things, and it could help make lisp look a bit more familiar to anyone coming from C-style syntax.

-----

1 point by akkartik 5433 days ago | link

Yeah I've been using that unconventional layout in my code. (I started out as a C programmer.)

But it is unconventional, and I didn't want to change it in the arc repo itself, so let me know if you see it in any non-test files.

-----

More