What is wrong ?
Hi Just discovering Rebol and i try this below: factorial: func [n] [either n > 1 [n * factorial (n - 1)] [1]] print factorial (3) print factorial (2) print factorial (3) * factorial (2) The output is 6 (OK) 2 (OK) 720 (wrong?????) What i am doing wrong?
posted by: Gérard 29-Nov-2012/6:14:33-8:00
Evaluation in REBOL is left to right, but infix operations take precedence over prefix operations. The "*" symbol takes two values, so your code is evaluated as: factorial (3 * (factorial 2)) factorial (3 * 2) factorial 6 720 Use parentheses to force precedence: >> factorial 2 + 1 * 2 == 720 >> factorial (2 + 1) * 2 == 720 >> factorial 2 + (1 * 2) == 24 >> (factorial 2 + 1) * 2 == 12 So the code you want is: print (factorial 3) * (factorial 2) or print (factorial 3) * factorial 2 ; second parens not required (factorial 3) * (factorial 2) 6 * 2 12 To add some more clarification, all infix operators have prefix versions: (2 * 2) = (* 2 2) So, another way to write your intended expression could be: print * factorial 3 factorial 2 Be sure to look at the source: source * *: native [ "Returns the first value multiplied by the second." value1 [number! pair! char! money! time! tuple!] value2 [number! pair! char! money! time! tuple!] ] The prefix version is * value1 value2 The infix version is value1 * value2 <- (VALUE1 * VALUE2) WILL BE COMPUTED _BEFORE_ THE REST OF A SURROUNDING LEFT-TO-RIGHT EXPRESSION Hope that helps :)
posted by: Nick 30-Nov-2012/6:06:49-8:00
Notice there's a difference in performance between infix and prefix operators: do http://www.fm.vslib.cz/~ladislav/rebol/timblk.r >> time-block [loop 1000 [2 + 2]] .05 == 4.4464111328125E-4 >> time-block [loop 1000 [+ 2 2]] .05 == 8.6083984375E-4
posted by: Nick 30-Nov-2012/6:16:26-8:00
I'm not sure I can figure out which is consistently faster: R E B O L [] factorial: func [n] [either > n 1 [* n factorial (- n 1)] [1]] wait 1 start: now/time/precise loop 100000 [(factorial 3) * factorial 2] print now/time/precise - start wait 1 start: now/time/precise loop 100000 [* factorial 3 factorial 2] print now/time/precise - start halt factorial: func [n] [either n > 1 [n * factorial (n - 1)] [1]] wait 1 start: now/time/precise loop 100000 [(factorial 3) * factorial 2] print now/time/precise - start wait 1 start: now/time/precise loop 100000 [* factorial 3 factorial 2] print now/time/precise - start halt 0:00:02.231 0:00:02.372
posted by: Nick 30-Nov-2012/6:24:24-8:00
That's actually really interesting to me. I always tend to use parentheses, but would have tended to consider the prefix notation more "REBOLish" (I remember reading somewhere that infix notation was first converted to prefix notation, then interpreted from there). It'll be really interesting to see the code soon - I'm sure there will be all sorts of tests and optimization attempts...
posted by: Nick 30-Nov-2012/6:35:23-8:00
Anyone know the answer to this already? Is infix faster than prefix notation?
posted by: Nick 3-Dec-2012/22:36:04-8:00
|