Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[REBOL] Re: Translate this code into real Rebol?

From: jeff:rebol at: 23-Jan-2002 17:00

Another entry for the number pretty printer: pretty-number: func [ in-amt [money! integer! decimal!] /local i-part f-part h-part out e neg get-high thousands-sep decimal-sep currency p-amt zpad ][ decimal-sep: #. thousands-sep: #, currency: # set [i-part neg f-part get-high zpad] reduce [ abs to-integer any [ all [money? in-amt out: copy currency in-amt: in-amt/2] all [out: copy currency: # in-amt] ] pick ["-" ""] negative? in-amt do pick [[join decimal-sep f-part] #] found? f-part: find/reverse/tail tail form in-amt #. func [x m /local p s][ reduce either x > p: 10 ** m [[s: to-integer x / p x - (s * p)]][[# x]] ] func [e x][either e [x][skip tail append copy #000 x -3]] ] for i 99 3 -3 [ set [h-part i-part] get-high i-part i if any [not e: currency = out number? h-part][ repend out [zpad e h-part thousands-sep] ] ] rejoin [neg out zpad e i-part f-part] ] commentary: { This has various REBOL idioms mixed in with my own. The way I did the function is a common approach I find I do in programming: breakdown, process, synthesize. In REBOL that amounts to first setting various locals, then doing some processing loop, ending with some kind of REDUCE or JOIN. Another REBOL idiom used is to "piggy-back" work in certain convenient places, for example, in the process of setting 'i-part I conditionally extract the number portion of in-amt if it's a money! in turn making sure that my output string is initialized with the currency or not depending on if money?. Similarly, I "piggy-back" all the word setting together, (except for the three user-vars which I left at the top). I tried to avoid the RT favorite bug-bear, which is to turn all problems into pure string processing. Working with the item-in-question's natural datatype (number), with the notable exception of handling the fractional part. One of my idioms is I often (ab)use issue! datatype. That's because no one seems to use it and I want to be original. (-: To ensure we get a string result, I just make sure NEG is a string. Another handy REBOL idiom is to have a function which returns a block. The block contains your "answer" as well as the next increment. You can see this with set [h-part i-part] get-high i-part i 'I-part gets moved along by each call to GET-HIGH. For example, look at LOAD/next and DO/next. Lets see.. I also removed the brackets refinement because I felt it didn't go with the function, but should go somewhere else. Now, Joel may benchmark these functions and demonstrate that my code is not the optimal solution. (-: This is likely because of the inner functions among other things. Inner functions are used when you want to share context, but in the case above, I defined them inside the function because they go with its "thinking". They'll likely be a performance hit, though (among other things). But efficiency wasn't a condition to play, so the optimization can be left as an exercise for performance critical uses. -jeff }