Actually, I'm with you on rec. Even after writing it my head was struggling to fully understand it. Complex recursion is tough to grasp; i wish there was a way of visualizing recursive calls that was similar to expanding a macro. Does anyone know if there's a way of doing that?
This one is very similar to the definition of rand-choice. (Why does the mappend expression work? Aren't the values of the biases unavailable during macro-expansion?)
This version still needs some massaging but it works with non-constant biases:
(mac bias args
(let bs (map car (pair args))
`(let r (rand (+ ,@bs))
(if ,@(let i 0
(rev (accum a
(each c (map cadr (pair args))
(a `(< r (+ ,@(cut bs 0 (++ i)))))
(a c)))))))))
arc> (with (a 1 b 2 c 3) (bias a 'red b 'white c 'blue))
white
Your macro has problems with variable capture and multiple evaluation (see chapters 9-10 of On Lisp). Here's a version that should work properly:
(mac bias args
(w/uniq r
(withs (ws (map car (pair args))
xs (map cadr (pair args))
us (map [uniq] ws))
`(with ,(mappend list us ws)
(let ,r (rand (+ ,@us))
(if ,@(mappend
(fn (u x) `((< (-- ,r ,u) 0) ,x))
us xs)))))))
IMO, though, the use of a macro here is a premature optimization. I think you should try to get a function working first, and then wrap a macro around it if you know that's what you need. See my comment http://arclanguage.org/item?id=7760 for an example of such a wrapper macro (in CL, but the Arc is similar).
I still suggest you take a look at how I do it http://arclanguage.com/item?id=7765 , which (1) avoids multiple evaluation, and (2) avoids variable capture.
(1) is the hard part here, which is why I had to use a list.
Also: the reason it needs ints is because of the 'rand function. We could also define a rand-float function which creates a random floating point number and use that instead:
the above now works with weight expressions that return real numbers. Also as specified, only the chosen expression is executed; however, all weight expressions are executed.
Ah, I misread that you wanted something akin to random-elt rather than rand-choice -- i.e., you'd want to use this as a control structure, in which case a macro indeed is what you'd need. My bad. That's what I get for commenting on an empty stomach (well, empty brain is more like it, but excuses are entertaining).
Shouldn't there be a simple, elegant solution to this problem that doesn't necessitate using ccc and return? Maybe I'm resistant to using continuations because I'm still coming to grips with understanding them... but there's alot of code in arc.arc and only one call to ccc.
You can write a tail-recursive version of tokipin's code pretty easily. Personally though I think this could be an addition to the "examples of LOOP" thread from a while back.
(defun wrandf (xs weights)
(loop with r = (random (apply #'+ weights))
for x in xs
for w in weights
for cw = w then (+ cw w)
when (> cw r) return x))
; assumes pair
(defmacro wrand (&rest args)
`(funcall
(wrandf
(list ,@(mapcar (lambda (x) `(lambda () ,(cadr x))) (pair args)))
(list ,@(mapcar #'car (pair args))))))
Any advice related to setting up and running your web server would be highly appreciated. I recently got a hosting account and was stuck trying to figure out how to keep the server running after logging out of ssh. Also, have you had any security concerns while developing your applications?
I use the screen utility. Basically, I always have screen running, and the repl / vim running. With the repl running in screen you can detach via control-a d, and then log off, and the repl keeps on running. Then you ssh back in, and can reattach via screen -dr.
I haven't had any security concerns - I have a couple admin pages but of course one has to be an admin to see them.
The problem is that if you define it this way, then your v is no longer lexical; instead, it's in the global namespace. Thus, writing (for ref 0 n (frob ref)) would overwrite the global ref procedure, which is not what you want.
I'm curious: So arc-eval translates your arc code into scheme code and then passes it to scheme's eval? If so, would it be possible to print the scheme code to a file before it gets evaluated?