Arc Forumnew | comments | leaders | submitlogin
small problem: (def power (nbr power)...
2 points by globalrev 6056 days ago | 15 comments
i assume this: "for x 0 power -1" is not working, hence the problem. how do I write it correctly? the -1 argument is accepted, though so what exactly am i doing here confused :) ?

(def power (nbr power) (if (is power 0) 1 (if (> power 0) (let acc nbr (for x 1 (- power 1) (= acc (* acc nbr))) acc) (let acc 1 (for x 0 power -1 (= acc (/ acc nbr))) acc))))



3 points by cchooper 6056 days ago | link

You don't need to nest if expressions in Arc, you can do this:

  (if a b
      c d
      e f
      g)
For defining power, it's easier to use a recursive function:

  (def power (n p)
    (if (is p 0) 1
        (> p 0)  (* n (power n (- p 1)))
        (/ 1 (power n (* -1 p)))))
If you want to use for then the problem is indeed (for x 0 power -1). for only counts up, so (= acc (/ acc nbr)) never gets executed because 0 is already greater than power.

Instead, try counting the other way around:

  (for x power 0
    (= acc (/ acc nbr)))

-----

1 point by globalrev 6056 days ago | link

ah solved it now by reversing the variables. but lets say you have a function where you dont know before hand, how would you solve that? edit: changed variablename too.

  (def power (nbr pow)
    (if (is pow 0)
        1
        (if (> pow 0)
	    (let acc nbr
    		(for x 1 (- pow 1)
        		(= acc (* acc nbr))) acc)
	    (let acc 1
    		(for x pow -1
			(= acc (/ acc nbr))) (/ acc 1.0)))))

-----

1 point by tokipin 6056 days ago | link

take a look at http://arcfn.com/doc/iteration.html for a list of different iteration functions. since you aren't using the x variable in those for loops there, you could just use repeat:

  (repeat (abs pow) ... )
here's my version:

  (def power (nbr pow)
     (withs (acc 1.0
             power+ (fn (times)
                        (repeat times
                            (zap * acc nbr))
                        acc))
            (if
              (> pow 0)
                    (power+ pow)
              (< pow 0)
                    (/ 1 (power+ (- pow)))
              1)))

-----

1 point by wfarr 6056 days ago | link

Okay - here's your problem: 'for from 0 to -1 doesn't run at all. So essentially, you're only returning 'acc right now.

I'll paste a fixed function soon-ish.

EDIT: Look at cchooper's post.

-----

3 points by globalrev 6056 days ago | link

ty very much for all the answers, very hepful.

-----

1 point by globalrev 6056 days ago | link

  (let acc 1
    		(for x 0 6 23456 666
			(= acc (/ acc 2))) acc)
why is the 23456 666 ignored? how can i just insert extra stuff there and nothing happens? where does it go, what can i do with it?

the problem with the func is the step, it need to subtract 1 and not step 1 at a time.

-----

1 point by cchooper 6056 days ago | link

They aren't ignored, they just don't do anything. for can take any number of arguments: the first is the symbol, the second the start value, the third the end value, and the rest are all the body of the loop. They all get executed in every iteration. For example:

(for x 0 6 (prn 2345) (prn 666) (= acc (/ acc 2))) acc)

produces

  23456
  666
  23456
  666
  23456
  666
  23456
  666
  23456
  666
  23456
  666
  23456
  666
  1/128

-----

1 point by globalrev 6056 days ago | link

  (def power (nbr power)
      (if (is power 0)
          1
          (if (> power 0)
	      (let acc nbr
    		  (for x 1 (- power 1)
        	  	(= acc (* acc nbr))) acc)
	      (let acc 1
    		  (for x 0 power -1
			(= acc (/ acc nbr))) acc))))

-----

1 point by globalrev 6056 days ago | link

without thinking i see i used a input witht he same name as the function.

this doesnt seem to cause a problem though. so it is ok or can be a problem?

-----

1 point by wfarr 6056 days ago | link

I believe so.

Because the 'def macro uses '= to define functions, variables and functions are occupying the same namespace (sort of).

For example:

  (def foo () (prn "bar"))
is expanded to:

  (= foo (fn () (prn "bar")))
For example:

  > (def foo () (prn "bar"))
  #<procedure: foo>
  > (= foo "foo")
  "foo"
  > (foo)
  Error: "procedure ...r/src/arc/ac.scm:1224:11: expects 2 arguments, given 1: \"foo\""
Make sense?

Though, that may not affect your usage here since power is just an argument and not a variable itself.

-----

1 point by cchooper 6056 days ago | link

In this case it's not causing a problem. You're allowed to give parameters whatever name you want, but if you name the parameter after the function then you can't call the function from within itself because the name will now refer to the argument.

So if you don't need to call the function recursively, there's no harm. It's just a bit confusing.

-----

1 point by wfarr 6056 days ago | link

Your function works fine for me on Anarki?

-----

1 point by cchooper 6056 days ago | link

Doesn't work on Arc2 for negative powers.

-----

1 point by globalrev 6056 days ago | link

works for (power 5 0), (power 5 2) but not (power 5 -2)

raising power to a negative number returns 1.

-----

1 point by wfarr 6056 days ago | link

Ah - I'll take a gander at that.

-----