Arc Forumnew | comments | leaders | submit | skenney26's commentslogin
1 point by skenney26 6312 days ago | link | parent | on: Improve this function?

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?

-----

4 points by skenney26 6313 days ago | link | parent | on: Improve this function?

  (def rec (f base xs)
    ((rfn r (xs)
       (if (atom xs)
           (base xs)
           (f (map r xs))))
     xs))

  arc> (= test (list 1 2 3 (list 3 4 5) (list 3 4 (list 1 2 3))))
  (1 2 3 (3 4 5) (3 4 (1 2 3)))
  arc> (rec avg idfn test)
  13/5

  arc> (rec avg [* _ 2] test)
  26/5
  arc> (rec [apply + _] [* _ 3] test)
  93

-----

1 point by skenney26 6316 days ago | link | parent | on: Help needed with macro

Still sucks but slightly better:

  (mac bias args
    (withs (ps (pair args)
            bs (map car ps)
            cs (map cadr ps))
     `(let r (rand (apply + ',bs))
        ((afn (b c i)
           (if (< r (apply + (cut b 0 i)))
               (eval (c (- i 1)))
               (self b c (+ i 1))))
         ',bs ',cs 1))))

-----

1 point by skenney26 6316 days ago | link

  (mac bias args
    (withs (ps (pair args)
            bs (map car ps))
     `(let r (rand (apply + ',bs))
        (if ,@(mappend list
                (rev (accum a
                       (for i 1 (len bs)
                         (a (list '< 'r
                                  (apply + (cut bs 0 i)))))))
                (map cadr ps))))))

-----

1 point by skenney26 6315 days ago | link

  (mac bias args
    (withs (ps (pair args)
            bs (map car ps))
     `(let r (rand (apply + ',bs))
        (if ,@(mappend list
                (map [list '< 'r (apply + (cut bs 0 _))]
                     (range 1 (len bs)))
                (map cadr ps))))))

-----

1 point by skenney26 6315 days ago | link

  (mac bias args
    (withs (ps (pair args)
            bs (map car ps))
     `(let r (rand (apply + ',bs))
        (if ,@(let i 0
                (mappend
                  [list (list '< 'r (apply + (cut bs 0 (++ i)))) _]
                  (map cadr ps)))))))
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?)

-----

1 point by almkglor 6315 days ago | link

> (Why does the mappend expression work? Aren't the values of the biases unavailable during macro-expansion?)

They are if the biases are constant numbers.

See my solution above instead for a way of making it work with non-constant biases

-----

1 point by skenney26 6314 days ago | link

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

-----

3 points by rkts 6314 days ago | link

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).

-----

1 point by skenney26 6312 days ago | link

  (mac bias args
    (w/uniq (bs r)
     `(withs (,bs (list ,@(map car (pair args)))
              ,r  (rand (apply + ,bs)))
        (if ,@(mappend
                (fn (c) `((< (-- ,r (pop ,bs)) 0) ,c))
                (map cadr (pair args)))))))

-----

1 point by skenney26 6314 days ago | link

Interesting solution. I like the clever use of --

-----

1 point by almkglor 6314 days ago | link

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.

-----

1 point by skenney26 6316 days ago | link | parent | on: Help needed with macro

The problem with using a function is all the arguments are evaluated.

  arc> (biased-choice 3 'black 3 'white 1 (pr 'blue))
  blueblack

-----

1 point by almkglor 6316 days ago | link

If all weights are ints:

  (mac biased-choice args
    (w/uniq (choice nums sum fns rsum)
      (givens (pairs        (pair args)
               weight-exps  (map [_ 0] pairs)
               choice-exps  (map [_ 1] pairs)
               )
        `(givens (,nums   (list ,@weight-exps)
                  ,sum    (apply + ,nums)
                  ,choice (rand sum)
                  ,fns    (list ,@(map [idfn `(fn () ,_)]
                                       choice-exps))
                  ,rsum   0)
           (while (< rsum choice)
             (zap + rsum (car nums))
             (zap cdr nums)
             (zap car fns))
           ((car fns))))))

The above macro supports that the weights are expressions instead of constants

(untested)

-----

1 point by almkglor 6316 days ago | link

ah crick: here's a working debugged version:

  (mac biased-choice args
    (w/uniq (choice nums sum fns rsum)
      (givens pairs        (pair args)
              weight-exps  (map [_ 0] pairs)
              choice-exps  (map [_ 1] pairs)
        `(withs (,nums   (list ,@weight-exps)
                 ,sum    (apply + ,nums)
                 ,choice (rand ,sum)
                 ,fns    (list t ,@(map [idfn `(fn () ,_)]
                                        choice-exps))
                 ,rsum   0)
           (while (<= ,rsum ,choice)
             (zap + ,rsum (car ,nums))
             (zap cdr ,nums)
             (zap cdr ,fns))
           ((car ,fns))))))
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:

  (def rand-float (lim) (* lim (rand)))

  (mac biased-choice args
    (w/uniq (choice nums sum fns rsum)
      (givens pairs        (pair args)
              weight-exps  (map [_ 0] pairs)
              choice-exps  (map [_ 1] pairs)
        `(withs (,nums   (list ,@weight-exps)
                 ,sum    (apply + ,nums)
                 ,choice (rand-int ,sum)
                 ,fns    (list t ,@(map [idfn `(fn () ,_)]
                                        choice-exps))
                 ,rsum   0)
           (while (<= ,rsum ,choice)
             (zap + ,rsum (car ,nums))
             (zap cdr ,nums)
             (zap cdr ,fns))
           ((car ,fns))))))
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.

-----

1 point by fallintothis 6316 days ago | link

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).

-----

1 point by skenney26 6316 days ago | link | parent | on: Help needed with macro

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.

-----

1 point by rkts 6316 days ago | link

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))))))

-----

1 point by skenney26 6338 days ago | link | parent | on: Show and Tell: ballerinc.com

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?

-----

3 points by antiismist 6338 days ago | link

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.

-----

3 points by skenney26 6362 days ago | link | parent | on: Checkbox

You could also use a function.

Add this after opsel in html.arc:

  ; minimized attribute (use w/ selected, checked)
  (def opmin (key val) 
    `(if ,val (pr " " ',key)))
Add this to the list of attributes in html.arc:

  (attribute input checked opmin)
Add this wherever you like:

  (def checkbox (name (o checked))
    (gentag input type 'checkbox name name checked checked))
A test webpage:

  (defop checkboxes req
    (checkbox 1 t)
    (br)
    (checkbox 2))
This is the resulting source code:

  <input type=checkbox name="1" checked><br>
  <input type=checkbox name="2">

-----

1 point by gidyn 6362 days ago | link

Thank you. Exactly what I need.

-----

2 points by skenney26 6383 days ago | link | parent | on: 2 questions about for

Thanks for the help absz. I'm creating a variety of iterators for a graphics app and I just want to make sure they're being written correctly.

I still don't quite understand why v needs to be initialized. For example, the following definition seems to work fine:

  (mac for (v init max . body)
    (w/uniq gm
     `(let ,gm (+ ,max 1)
        (loop (set ,v ,init) (< ,v ,gm) (set ,v (+ ,v 1))
          ,@body))))

-----

2 points by absz 6383 days ago | link

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.

-----

1 point by skenney26 6383 days ago | link

Ah, it finally makes sense. Thanks again.

-----

2 points by skenney26 6387 days ago | link | parent | on: Interpreter Manipulation?

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?

-----

1 point by almkglor 6386 days ago | link

> I'm curious: So arc-eval translates your arc code into scheme code and then passes it to scheme's eval?

Yes, I think so.

> If so, would it be possible to print the scheme code to a file before it gets evaluated?

Yes. sacado did some work on this I think.

-----

3 points by skenney26 6396 days ago | link | parent | on: Local Scopes?

Recently I've been thinking alot about scope and would be interested in hearing you expound on what Python and Arc got wrong.

-----

More