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

my programmer senses tingle and I find myself wanting to abstract things away - you hit the nail on the head there. What's more, I'm sure there's meaning in those patterns if we could only make them explicit - listening to music is sometimes listening to a conversation in a mostly-foreign language - words here and there that you recognize, you suspect that something meaningful is being communicated, but it's just beyond your grasp.

don't let the text-only nature of Arc discourage you - no chance, I'm too far gone for that.

-----

1 point by conanite 5554 days ago | link | parent | on: Why does pr return it's first arg?

One way to make this possible is to have your 'html macro (I'm assuming it's a macro) unhygienically provide a lexical binding for 'pr for its body

  (mac html body
    `(do (pr "<html>")
         (let pr prnil ,@body)
         (pr "</html>")))
That way your callers can use 'pr like they're used to, but secretly and subversively you have them calling your own private pr function.

-----

1 point by jazzdev 5553 days ago | link

That's a clever way to do it. Thanks.

-----


Mac 10.5, mzscheme 4.2.1, ended with no error.

-----

1 point by conanite 5561 days ago | link | parent | on: Poll: All things not arc?

It's a little bit chicken-and-egg ... I'll decide once I see who's already there :)

I would guess that a new, more general, forum needs more than some fraction ( x < 1 ) of arc forum users in order to be engaging or useful ... are there other communities you will also attract some seed population from?

Do you want to give an example of the kinds of topics you have in mind?

-----

1 point by thaddeus 5561 days ago | link

forum needs more than some fraction ( x < 1 )

hmmm.... idealistically I had hoped that doing this might grow the arc community, provide more things for the same community to engage in.

are there other communities you will also attract some seed population from

I think so, if I re-tool the forum well enough that conceptual domains are not all over the place, that could happen.

Do you want to give an example of the kinds of topics you have in mind?

yup.

  * Right now I proxy from apache to my arc server. I was   
  reading about the Nginx webserver and wanted to know if 
  anyone had proxied from Nginx to Arc and could 'dicuss' 
  the worth-it/not-worth-it setup&configs of it. Nginx docs 
  are bad and most blogs only discuss integration with 
  mainstream technologies. Really this is a side topic not 
  truly arc related.

  * I was reading about 'coffee script' and want to know 
    if anyone has used it. I was thinking of writing a 
    arc->coffe-script tool, but I would like to post 
    questions on it first.
The list goes on and on.... lol.

-----

1 point by aw 5560 days ago | link

I think that running Nginx as a frontend to Arc is relevant since there may be issues related specifically with the interaction between the two. Of course there might not be, but how would you know until you got into it? For example I'm running Perlbal as a frontend to Arc, and it gets messed up when Arc send a response without carriage returns in the headers but has a carriage returns in the beginning of the body. That's something that it's unlikely that anyone else is going to run into.

And if you're thinking of a Arc -> coffee-script tool, who knows, there might be some things that even if coffee-script is cool in general, might be unusual or problematic in the context of Arc.

I suppose "talk about anything as long as you include an obligatory Arc reference" might be going too far :-) but I suspect the line is further out than you've drawn it ^_^

-----

2 points by akkartik 5560 days ago | link

I'd go farther - it doesn't even have to include an obligatory arc reference. The number of users here is small enough that the usual rules are less important. Especially if it's occasional (the front page is still mostly arc) and from someone we recognize, I think the handful of people here prob won't mind (or they'll respond to this if they do ;)

I'm finding out that creating a new destination site is crazy hard to do. The internet is mature; all of us have our habits, and it takes a lot to change. Just go where your audience is. If they don't like what you say they'll let you know, and you can then iterate.

-----

1 point by thaddeus 5559 days ago | link

hmmm. Good point. I suppose if no one replies to my 'other' items here, then a side forum probably would not work anyhow. And if I don't get replies to most of them - I'll probably get the hint (at least one would hope)... :)

-----

2 points by shader 5559 days ago | link

At this point, I think that more posts is probably a good thing, even if they're only slightly related to arc.

A lot of people like me probably don't check all that often because there isn't much going on. If we can increase the number of comments/submissions to a slightly higher level, it will probably encourage more return visits, and better community interaction. Sure, the quality should be kept high and this is the arc forum. But by all means, submit "other" posts, if only so that there's a reason to check more frequently. That would give the arc community a greater appearance of life, and allow the posts and questions that "really matter" to get more attention as well.

-----


I haven't tried, but according to http://groups.google.com/group/google-appengine-java/web/wil... they support jruby, groovy, jython, rhino, scala, and others, so I don't see why not. It might not be possible to use arc's native webserver if appengine obliges you to go through the servlet api. If that's the case, you'll need a few lines of actual java to make that happen - basically a stub implementation of Servlet that delegates the request to arc. Let me know if you want to try that, I'll be happy to help.

-----

4 points by conanite 5571 days ago | link | parent | on: How to generate SHA1 hash?

app.arc generates sha1 hashes using a system call to openssl:

  (def shash (str)
    (let fname (+ "/tmp/shash" (rand-string 10))
      (w/outfile f fname (disp str f))
      (let res (tostring (system (+ "openssl dgst -sha1 <" fname)))
        (do1 (cut res 0 (- (len res) 1))
             (rmfile fname)))))

-----

3 points by conanite 5581 days ago | link | parent | on: Symbol tables

Here's a macro-based approach that doesn't involve hacking ac.scm. First, an undo function that knows how to restore state for a set of variables:

  (def undo-fn (syms)
    (let backup-syms (map [sym (string "_" _)] syms)
      `(let ,backup-syms (list ,@syms)
         (fn ()
           (= ,@(mappend (fn args args) syms backup-syms))))))
This gives:

  arc>(undo-fn '(a b c))
  (let (_a _b _c) (list a b c) (fn () (= a _a b _b c _c)))
Now, a macro for defining functions that unhygienically inserts a function called "undo":

  (mac ufn (args . body)
    `(fn ,args
      (let undo ,(undo-fn args)
        ,@body)))
A quick test:

  arc>(= undo-test (ufn (x) (= x 999) (prn x) (undo) x))
  arc>(undo-test "original")
  999
  "original"
You could use 'undo-fn directly if you wanted to specify which variables need to be undoable.

-----

1 point by fallintothis 5580 days ago | link

Cool solution! Of course, handling arbitrarily-long history and globals would be more complicated. Maybe you could modify = to push old values onto a stack?

One advantage to an ac.scm approach is that you don't need to use the special ufn. If it worked on fn itself, then any local variables -- in a def, let, with, mac, etc. -- would be undoable. In an attempt to do this, I added a bit to your macro-based approach:

  (def undo-fn (symbols)
    (let backups (map1 [uniq] symbols)
      `(let ,backups (list ,@symbols)
         (fn () (= ,@(mappend list symbols backups))))))

  (mac w/undoable (parms . body)
    `(let undo ,(undo-fn parms)
       ,@body))

  (mac w/undo (expr)
    ((afn (tree)
       (let tree (macex tree)
         (if (caris tree 'fn)
              (let (lambda args . body) tree
                `(fn ,args (w/undoable ,args ,@(self body))))
             (atom tree)
              tree
             (cons (self (car tree))
                   (self (cdr tree))))))
     expr))
Certainly a hack, but it gives us:

  arc> (w/undo (let x 5
                 (prn "original: " x)
                 (++ x)
                 (prn "new: " x)
                 (undo)
                 (prn "undone: " x)
                 nil))
  original: 5
  new: 6
  undone: 5
  nil

  arc> (w/undo
         (def f (x)
           (prn "original: " x)
           (++ x)
           (prn "new: " x)
           (undo)
           (prn "undone: " x)
           nil))
  #<procedure: f>
  arc> (f 5)
  original: 5
  new: 6
  undone: 5
  nil
  arc> (f 10)
  original: 10
  new: 11
  undone: 10
  nil

  arc> (w/undo
         (def f (x)
           (prn "=== OUTSIDE LET ===")
           (prn "original: " x)
           (= x (let x (+ x 1)
                  (prn "=== INSIDE LET ===")
                  (prn "    original: " x)
                  (++ x)
                  (prn "    new: " x)
                  (undo)
                  (prn "    undone: " x)
                  x))
           (prn "new: " x)
           (undo)
           (prn "undone: " x)
           nil))
  *** redefining f
  #<procedure: f>
  arc> (f 5)
  === OUTSIDE LET ===
  original: 5
  === INSIDE LET ===
      original: 6
      new: 7
      undone: 6
  new: 6
  undone: 5
  nil

-----

1 point by shader 5563 days ago | link

All of the solutions so far have been interesting, but I was thinking more of being able to undo any change to any variable, instead of just the few variables declared as parameters.

The idea would be something like this:

  (with x 5 y 4
    (w/undo
      (++ x)           -> x=6
      (undo x)         -> x returns to 5
      (= y (++ x))     -> x = y = 6
      (side-efn x y)   -> x and y are modified
      (undo)           -> x = y = 6 again
      (reset)))         -> x = 5, y = 4
It seems like being able to undo side effects caused by function calls to arbitrary variables would require overloading = (or more likely sref).

Maybe if you did that you could replace variables that are modified with objects that when evaluated return their current value, but which can undo and maybe even redo by changing the return value to an earlier or later value on the stack. They should also be added to a list of modified variables owned by the w/undo macro, so that it can reset all of their values, and also commit their final value when the block is completed.

Would this even be possible? I'm not sure that it would be, since I think arc uses lexical scoping, which means that an arbitrary function call would use its own context's definition of sref, and thus wouldn't pay attention if we redefined it. Maybe since sref is a global variable, it could be replaced and then reset by w/undo? Meta w/undo!

Anyway, this concept of making variables able to remember their past and return previous values reminds me of lazy evaluation and memoization. Maybe their's some sort of connection that could be used to unify them simply, and add them to arc as a unit?

-----

2 points by rocketnia 5563 days ago | link

What happens if side-efn is this?

  (mac side-efn (x y)
     ; NOTE: This form is only intended to be used in the case where x and y are
     ; raw symbols, as they are in forms like (side-efn foo bar).
     `(= ,x (- ,y ,x)    ; temp = old y - old x
         ,y (- ,y ,x)    ; new y = old x (calculated as old y - temp)
         ,x (+ ,y ,x)))  ; new x = old y (calculated as old x + temp)
Should 'undo reverse just one of these assignments or all three? Should it make any difference if these assignments are three separate = forms within a (do ...) block?

A top-level undo could be nifty, but on the Arc top level even the macro environment gets to change from expression to expression, so it can be a bit different. To allow undo on a finer scale raises the question of just how to measure the previous transaction. How many assignments should be undone, and what if they're hidden away in a call to a function nobody likes to read? What about assignments for scopes whose dynamic extent has ended?

-----

1 point by shader 5559 days ago | link

I'm not entirely sure. Now that I think about it, fine grained undo is really a different concept from global state restoration, and is commonly only done for variables that the programmer a) knows about and b) has in mind the place he would like to restore to.

This means that finer grained undo would be more accurately implemented with save and restore functions, as opposed to just an undo function.

The global undo should work the same was as previously stated, more like a reset, and going all the way back to the start point, which may or may not be the beginning of the w/undo block.

Maybe a better system would be two pairs of save and restore functions, one that works on individual symbols, and the other that redefines '= to store the old value in a table if it didn't already exist, so that reset could restore it.

-----

1 point by conanite 5582 days ago | link | parent | on: Symbol tables

In ac.scm during compilation/macroexpansion there's a variable passed around called 'env which I think is the list of lexically bound symbols for the current scope. Not sure how you'd hook into that for your purposes though.

-----

1 point by fallintothis 5581 days ago | link

Yeah, but env just keeps the variables around, not their values. It's used to distinguish between locals and globals when compiling down to lambda.

  > (ac '(fn (x) (+ x 1)) '())
  (lambda (x) (ar-funcall2 _+ x 1))
  > (ac '(+ x 1) '())
  (ar-funcall2 _+ _x 1)
  > (ac '(+ x 1) '(x))
  (ar-funcall2 _+ x 1)
So it's not quite what you'd want. Off the top of my head, you could hack ac.scm to treat

  (fn (x) body)
as something like

  (fn (x) (= (locals* 'x) x) body (wipe (locals* 'x)))
Since Arc does all of its local binding with fn (either directly or by macroexpansion), this would work. ac.scm won't heed Arc-side redefinitions of fn, so I can't think of a convenient vanilla Arc implementation. As for efficiency, thread safety, etc., my idea seems gross.

I know Common Lisp has environments (http://www-prod-gif.supelec.fr/docs/cltl/clm/node102.html), but I don't know how they're usually implemented.

  $ clisp -q
  [1]> (let ((x 10)) (let ((y 20)) (the-environment)))
  #(#(Y 20 #(X 10 NIL))
    NIL
    NIL
    NIL
    ((DECLARATION XLIB::CLX-VALUES VALUES OPTIMIZE DECLARATION)))

-----


I don't think it's off-topic at all, if I had an arc app to show this is the first place I'd post it ...

I tried dilbert.com and it showed me today's comic, but the older/newer links didn't do anything. Dailyshow.com ... "this sucks", it showed me a page from Onion instead, and likewise, older/newer didn't do anything.

It didn't occur to me until I mouseovered that the coloured strips were supposed to be clickable, I thought they were just decoration.

I'm on FF3.5.7, mac. HTH.

-----

1 point by akkartik 5584 days ago | link

Update: I've made the buttons more button-like. Is that clearer? (it's certainly uglier; I'll work on that next)

-----

1 point by thaddeus 5584 days ago | link

Much better. When I revisited I went much further and clicked through those option buttons. Since then I noticed one more thing: The space on the left side showing the history fluctuates in size quite a bit and only takes advantage of a third of the vertical space my screen has available. The fluctuating size forces me to chase the <older and newer> links as they move around the screen. Might I suggest moving the older/newer nav links to the top area so they remain in a fixed position, then allow the history to fill to the bottom of the webpage. My 2 cents :).

[Edit: or even have the links both atop and bottom]

-----

1 point by akkartik 5584 days ago | link

I added pagination links to the top, and made it 25 links per page. Since there's links at the top I'm less concerned about requiring scrolling to paginate :) Thanks for the suggestion.

-----

1 point by thaddeus 5583 days ago | link

I think there's a bug. I ran finance from home yesterday -> http://readwarp.com/station?seed=finance# and stepped through the history section. On my lunch hour today I gave the same input... and the same history is still there. Given I don't have a user account and I am at a different IP, I think everyone get a shared history.

Earlier you posted...

"so if somebody else makes a request while you're browsing, you see the history for their station when you hit older or newer.."

I don't think anyone one else made this request while I was browsing and these are the links from yesterday.

-----

1 point by akkartik 5583 days ago | link

That quote was a bug report, and it was already fixed at the time of writing :)

The way it works right now: stations are distinct, and have their own history, but are shared across users. The fact that the same history is still there just means that nobody else used the finance station in the meantime. Am I misunderstanding something?

Why don't we take this offline? My email is in my profile. If you send me email I can set you up with a user account. It's extremely unpolished, but you'll be able to import your own feeds and so on.

This goes for anyone else reading this, btw. Send me email and I'll set you up with your own private feedreader on readwarp.

-----

1 point by akkartik 5585 days ago | link

Oh wow, I really need to fix those buttons.. :(

-----

2 points by conanite 5595 days ago | link | parent | on: Contract ssyntax

And beware of 'a&~b - it hangs (at least it did 132 days ago ... http://arclanguage.org/item?id=10513 ), I don't know if this has been fixed.

-----

1 point by fallintothis 5594 days ago | link

Yeah, it's still a problem. Oddly enough, I only ever noticed it in test code that expanded ssyntax tree-wise (vs. Arc's symbol-wise ssexpand). I didn't put deliberate thought into making sscontract aware of the bug, but I think it's avoided because of careful precedence separation.

  arc> (sscontract '(andf f (complement g)))
  (andf f ~g)
  arc> (sscontract '(compose f (complement g)))
  f:~g
  arc> (sscontract '(f ~g))
  (f:complement g) ; ew...should probably return (f ~g)
  arc> (sscontract '(f '~g))
  (f (quote ~g))
Thanks for the andf case, by the way. Hadn't thought of that one. If you find any incorrect contractions, please let me know. If you want, you can use bitbucket's issue tracker: http://bitbucket.org/fallintothis/contract/issues/

-----

More