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

Have you looked at Termite (that is, Gambit)? It seems to support continuations well - continuations are even serializable (along with ports, threads, etc) - and I think concurrency is handled exceptionally elegantly (built-in message-passing a la Erlang).

I never got many chances to use such exotic features, but I believe the combination of message passing and serializable continuations would allow you to do fun stuff like easily transfer code execution between different computers.

My limited experience suggested it was fast. It's also compilable to C. I suspect tail calls are properly handled - doesn't seem like something Feeley would let slide. I'm not sure about reliability.

I stopped using it because of lack of documentation and poor library support.

-----

2 points by garply 5535 days ago | link | parent | on: Arc.arc vs lib/util.arc

I'm not proposing hacking existing functions. Basically everything should be able to be maintained by running a diff between the 2 arc.arcs and pasting the extra functions in the Anarki version into pg's new arc.arc. What difficulties did you encounter last time?

-----

1 point by garply 5538 days ago | link | parent | on: File I/O Challenge

If we can count w/stdoutfile from lib/util.arc as part of the Arc language (and I'd argue that we should), we could drop another token:

  (w/stdoutfile "fileio.txt"
      prn!hello
      prn!world)
    (pr:cadr:readfile "fileio.txt")
10 tokens is pretty good - Skimming the list, I think Arc pretty much mops the floor in terms of concision.

-----

4 points by fallintothis 5537 days ago | link

Hm. Anarki calls them w/stdoutfile and w/stdinfile, but wouldn't tofile and fromfile be more consistent with tostring and fromstring (and shorter, besides)? Then there's the whole appending business. Can't really give an optional parameter to tofile like outfile has, and toappendfile runs together horribly. What about just appendfile?

Then, using readline instead of readfile so that it (1) doesn't try to parse things as s-exprs and (2) doesn't read the entire file for no good reason, I'd envision it thus:

  (tofile "fileio.txt" (prn "hello"))
  (appendfile "fileio.txt" (prn "world"))
  (fromfile "fileio.txt" (readline) (pr (readline)))

-----

1 point by waterhouse 5537 days ago | link

Excellent. Have added to my personal Arc library (which is a big fat file named "a", to which I keep appending things):

  (mac tofile (f . body)
    (w/uniq gf
      `(w/outfile ,gf ,f
         (w/stdout ,gf
           ,@body))))
  (mac fromfile (f . body)
    (w/uniq gf
      `(w/infile ,gf ,f
         (w/stdin ,gf
           ,@body))))
I'm not sure about the appendfile--given what infile and outfile do, it sounds like a procedure that creates an output-port that appends to a file. Maybe to-appendfile, appendtofile, appendingfile, tofile/append... Alternatively, we could make keyword arguments happen in Arc, and then you would just throw ":append t" or something inside the call to tofile. That would also allow for further extension with, e.g., an :if-exists argument.

-----

1 point by rocketnia 5537 days ago | link

How about 'tolog? Are files opened for appending for other reasons, in practice? This would also keep with the to-means-output, from-means-input pattern.

-----

2 points by fallintothis 5537 days ago | link

I'd try to err on the side of generality. And I'm not quite as concerned about to:output / from:input, if the names are still "clear enough".

As to waterhouse's suggestions, I had considered those names. I suppose if you read appendfile as a noun instead of a verb-and-noun, it's confusing (though infile and outfile don't really have the same problem, so it's not the train of thought my brain follows). It's hard modifying a name like tofile with a long word like append. We already have two words in tofile, so adding a third without hyphenation is stretching it, and adding hyphens breaks the flow with the other names (fromfile, tostring, etc.). We could go for something shorter, like addtofile, which delineates itself well without hyphens because each word is one syllable. If we can't avoid hyphens, using / instead (e.g., tofile/a or tofile/append) flows better, but isn't that great.

Another name that occurred to me -- and is probably my favorite so far -- is ontofile, which is still simple enough to not need hyphens, communicates intent (appending something onto a file), and worms the word to in there, painting it with the to:output / from:input correlation. Thoughts?

-----

2 points by evanrmurphy 5537 days ago | link

Another name that occurred to me -- and is probably my favorite so far -- is ontofile, which is still simple enough to not need hyphens, communicates intent (appending something onto a file), and worms the word to in there, painting it with the to:output / from:input correlation. Thoughts?

+1! ontofile is a great name, in my opinion, for all the reasons you listed.

I searched for a good portmanteau in the vein of mappend, but I don't think there is one. fappend? Sounds like frappuchino. filepend is decent, but I think I prefer ontofile.

-----

2 points by fallintothis 5537 days ago | link

fappend? Sounds like a frappuchino.

Hahaha! Or worse: http://www.urbandictionary.com/define.php?term=fap :P

filepend is decent, but I think I prefer ontofile.

Agreed on both counts. But that's a clever one; I hadn't thought to try out portmanteaus yet.

-----

1 point by evanrmurphy 5537 days ago | link

Oh wow, didn't know that one. Who knew you could get street smarter hanging out on Arc Forum??

-----

1 point by garply 5537 days ago | link

Regarding logging, I use a log function such that (log "my log message here") appends to a globally identified file log*.

-----

3 points by garply 5540 days ago | link | parent | on: Ask AF: How to troubleshoot a memory leak?

I've had problems with a memory leak using srv.arc before as well - I was unable to track it down. Curious to hear what you find out.

On the other hand, have you considered switching to http.arc and dispatch.arc? I personally would like to phase srv.arc out of Anarki.

-----

1 point by evanrmurphy 5540 days ago | link

I haven't tried http.arc and dispatch.arc yet. Were those written by palsecam? Have you had good experiences with them?

-----

2 points by garply 5539 days ago | link

Yes and yes. With pg's code, I kept having to make ugly hacks to things like respond to be able to do what I wanted. It was hard to modify, hard to maintain, and hard to debug. IMO, palsecam's code is much more flexible and much better written. I highly recommend it.

-----

5 points by garply 5542 days ago | link | parent | on: Named loop or continue keyword?

How about something like this?

  (mac xwhile (test . body) 
    `(while ,test (ccc (fn (continue) ,@body))))
Then:

  (let x 0 
    (xwhile (< x 10) 
      (when odd.x 
        (++ x) 
        (continue)) 
      (prn x) 
      (++ x)))
does what I want it to do.

P.S. How do I format this with proper indentation on this forum?

Edit: Thanks waterhouse

-----

5 points by fallintothis 5542 days ago | link

Looks good. That's what I would've done, if you hadn't beaten me to it. :)

Relevant arc.arc definitions:

  (mac point (name . body)
    (w/uniq (g p)
      `(ccc (fn (,g)
              (let ,name (fn ((o ,p)) (,g ,p))
                ,@body)))))

  (mac catch body
    `(point throw ,@body))
Thus,

  (catch
    (while t
      (throw 5)))
expands into

  (point throw
    (while t
      (throw 5)))
which expands (modulo gensyms) into

  (ccc (fn (current-continuation)
         (let throw (fn ((o return-val)) (current-continuation return-val))
           (while t
             (throw 5)))))
So throw serves to "point back" to the current continuation, and optionally continues with a return value. (This seems to be the behavior of a simple (ccc (throw) ...) without the let; I'm not sure why it's defined this way.) The above loop returns 5 -- the continuation captured by ccc is outside of the loop, so its action is to return whatever value we say the while expression returns and continue evaluating anything after it.

This way, Arc gives you a decorator for return values. You can use this pattern to decorate any portion of your loop, to give different effects. Outside of the loop, it's like a break. Inside of the loop, it's like a continue due to how while is expanded.

  arc> (load "macdebug.arc") ; see http://www.arclanguage.org/item?id=11806
  nil
  arc> (macsteps '(while test
                    (point continue body1 body2 body3))
                 'show 'while 'point)
  Showing only: while, point

  Expression:

    (while test
      (point continue body1 body2 body3))

  Macro Expansion:

      (while test
        (point continue body1 body2 body3))

  ==> ((rfn gs2027 (gs2028)
         (when gs2028
           (point continue body1 body2 body3)
           (gs2027 test)))
       test)

  Expression:

    ((rfn gs2027 (gs2028)
       (when gs2028
         (point continue body1 body2 body3)
         (gs2027 test)))
     test)

  Macro Expansion:

      (point continue body1 body2 body3)

  ==> (ccc (fn (gs2029)
             (let continue (fn ((o gs2030)) (gs2029 gs2030))
               body1
               body2
               body3)))

  Expression:

    ((rfn gs2027 (gs2028)
       (when gs2028
         (ccc (fn (gs2029)
                (let continue (fn ((o gs2030)) (gs2029 gs2030))
                  body1
                  body2
                  body3)))
         (gs2027 test)))
     test)

  nil
As you can see, the continuation is captured around the body, but the test properly resides outside of the body, so it'll still be executed even if you continue (because, again, the default continuation is to keep on chuggin' along).

You could have a while macro encapsulate these (similar to catch) so you don't have to write

  (point break
    (while test
      (point continue
        body)))
I've been trying to think of good names for such a loop. The most descriptive words are long (e.g., continuable-while, breakable-while), but we usually recognize "esc" as "escape", so it's a short yet descriptive option. Something like

  (mac esc-while (test . body)
    `(point break (while ,test (point continue ,@body))))
or, crafting a portmanteau à la whilet,

  (mac whilesc (test . body)
    `(point break (while ,test (point continue ,@body))))
Don't know if this actually made continuations any clearer, but there you go.

-----

3 points by waterhouse 5542 days ago | link

To make code show up here properly, put two spaces before each line of code and paste it here. As in:

  ;I used this function to add spaces so I could put it here!
  (def add-spaces (xt) 
    (no:map [prn "  " _] lines.xt))
This assumes you have it indented already. If you don't, find a text editor that indents Lisp code for you (I recommend DrRacket). The 'ppr function works reasonably well, too.

-----

3 points by zhtw 5540 days ago | link

ccc is certainly way to go, but just in case: mzscheme does not use continuation passing style so the ccc can work much much slower than just a function call because it copies the stack.

Actually I didn't do the profiling so maybe there is nothing to worry about.

-----

3 points by fallintothis 5539 days ago | link

  arc> ; with ccc
  (time
    (with (x 0 y 0)
      (while (< x 1000000)
        (catch
          (when (odd x)
            (++ x)
            (throw))
          (++ y)
          (++ x)))
      (list x y)))
  time: 27208 msec.
  (1000000 500000)

  arc> ; without ccc
  (time
    (with (x 0 y 0)
      (while (< x 1000000)
        (if (odd x)
            (++ x)
            (do (++ y)
                (++ x))))
      (list x y)))
  time: 1978 msec.
  (1000000 500000)
Interesting observation!

-----

2 points by akkartik 5539 days ago | link

Ah, that helps understand ccc. I've been mulling ccc for months without having a handle on it. But seeing a simple solution to a simple problem I can relate to helps immeasurably.

-----

1 point by evanrmurphy 5542 days ago | link

Much more elegant and less buggy than my attempt. Nice work.

-----

2 points by garply 5542 days ago | link | parent | on: Named loop or continue keyword?

Your code works because nothing follows your continue. This does not work as I would want it to:

(afor i 0 3 (when (odd i) (continue)) (prn i)) goes to:

0

2

4

5

nil

-----

1 point by garply 5542 days ago | link | parent | on: Named loop or continue keyword?

Thanks, but next in an xloop doesn't really work as a substitute, right? The code after a (next) still gets executed after the recursion completes, whereas with a continue, the rest of the branch isn't executed. I really need the latter.

-----

3 points by rocketnia 5542 days ago | link

(I wrote this response before I read some of the more recent comments, so it'll end up duplicating information, but I'm posting it anyway 'cause of the example utilities.)

In that case, I typically use 'catch or 'point (which indeed use continuations). If you want a loop with the ability to either break or continue, you can put a 'point on the outside and another 'point on the inside.

Here's a half-effort to abstract this away. I don't know how useful it'll be, but it might be the start of something better, so everyone, feel free to use it for anything without credit. ^_^

  (mac w/breaks (break next loop-header . body)
    (w/uniq g-breakpoint
      `(point ,g-breakpoint
         (let ,break (fn ((o val)) (,g-breakpoint val))
           (,@loop-header
             (point ,next
               ,@body))))))
  
  (mac forever body
    `(while t ,@body))
  
  (mac bforever body
    `(w/breaks break next (forever) ,@body))
  
  (mac bfor (var start end . body)
    `(w/breaks break next (for ,var ,start ,end) ,@body))
  
  ; What a name.
  (mac beach (var coll . body)
    `(w/breaks break next (each ,var ,coll) ,@body))
  
  ; Turn any loop into a breakable one. Example usage:
  ;
  ; (b-:until (all has-come-home cows) :
  ;   (tip rand-elt.cows)
  ;   (unless whales
  ;     (next))
  ;   (actually-beach rand-elt.whales)
  ;   (when cops
  ;     (prn "Uh, oops?")
  ;     (break)))
  ;
  (mac b- (loop)
    (let (header (_ . body)) (split loop (pos ': loop))
      `(w/breaks break next ,header ,@body)))
Silly example:

  (def going-up (top-floor)
    ; Alternately, "(b-:for floor 1 top-floor :".
    (bfor floor 1 top-floor
      (when (and (is floor 13) (~is top-floor 13))
        (next))
      (when (< 20 floor)
        (prn "...And that's it.")
        (prn "Sorry, this elevator is afraid of heights.")
        (break))
      (prn "Floor " floor (case floor 13 "?? O_O" "!"))))
(Clearly, this wouldn't mix very well with 'xloop; since an 'xloop doesn't loop unless you make it loop, a "continue" continuation wouldn't really make any sense.)

-----

3 points by garply 5548 days ago | link | parent | on: Language-neutral news.arc

I use some i18n in my programs, a key decision I think you'll have to make is whether translation should be done at compile-time or dynamically. I went the former route, but I often find myself wishing my strings were translated dynamically.

I use a global called locale* and have a macro which translates strings based on it. I'd be happy to work with you and the community to agree on something we all think works well and put it in the github repo.

-----

1 point by chris_l 5547 days ago | link

I don't think the cost of dynamic lookup will be very high, at least in news.arc there isn't that much text. I intend to use a function that looks into a table:

(prn (i18n 117))

I think numbers over pseudo-text-symbols will fit with arc's keep-it-brief style.

-----

3 points by garply 5546 days ago | link

I don't like the numeric setup - I find it makes the code hard to read. Most of the other i18n libs I've seen use English in the code and then a mapping between English and other languages in a separate file. I think that approach makes more sense. When I'm skimming code, I'd rather read (i18n "Add Comment") than (i18n 143).

-----

2 points by garply 5554 days ago | link | parent | on: Try Arc->Javascript

Please feel free to use arcscript. I only dumped that file into the repo because I had it lying around and thought someone might have use for it. You got around to completing a nice functional JS compiler implementation before I did and I'm glad you did. Feel free to upload on top of my file :)

-----

1 point by evanrmurphy 5554 days ago | link

Wow, thank you very much.

-----

1 point by garply 5608 days ago | link | parent | on: JavaScript Compiler, js.arc (w/ arc.js)

I have looked at parenscript and even started an arcscript which is totally non-functional - I was just translating it to Arc as I went as a way to understand the original codebase. I never finished it, but I'll post what I have on github and maybe we can collaborate.

Edit: pushed to github.

-----

More