REBOL Forum Recent REBOL Forum Topics Rebol vs. FizzBuzz There's a programming problem that someone came up with, and people have supposedly found it to confound a surprising percentage of interview candidates. It goes like this: "Write a program that prints the numbers from 1 to 100. But for multiples of three print 'Fizz' instead of the number, and for the multiples of five print 'Buzz'. For numbers which are multiples of both three and five print 'FizzBuzz'." While it seems quite easy (and well...*is* easy), many programmers will want to express the string "Fizz" and "Buzz" just once each in the program, while doing the tests for divisibility just once each. That's not something most languages can do. If you want to see the carnival of workarounds in various languages, here's a wiki link where some people discuss the problem: HOW WELL CAN REBOL2 DO? This is the kind of problem that the Rebol evaluation model would seem suited at factoring the way people would want. Rebol2 seems like it might be able to do it with something like: repeat n 100 [ print any [ rejoin [ if 0 = mod n 3 ["Fizz"] if 0 = mod n 5 ["Buzz"] ] n ] ] It's a pattern that would *almost* work, foiled by REJOIN stringifying the nones instead of propagating them as a none return result: >> rejoin [none none] == "nonenone" Let's imagine for the moment a variant of REJOIN which always produces a STRING! (like AJOIN) but that returns a NONE! if no values in the block reduce to anything besides NONE!. (Note that REJOIN has a number of problems when used for strings: ) I'll call this new operation UNSPACED: unspaced: func [b [block!]] [ b: reduce b remove-each item b [none? item] if not empty? b [ajoin b] ] Changing the FizzBuzz code above to use UNSPACED instead of REJOIN, we'll get a working solution. WHAT DOES REN-C BRING TO THE TABLE? Ren-C has UNSPACED defined "in the box", as well as SPACED. Both of these are specializations of a generic DELIMIT operator. You could make more specializations: comma'd: specialize 'delimit [delimiter: ", "] >> comma'd ["a" if false ["b"] "c"] == "a, c" >> comma'd ["a" case [1 > 2 ["b"] 2 > 3 ["c"]] "d"] == "a, d" But it also has a significantly more powerful model for infix. Not only can it drive generic THEN and ELSE operations which complete their left hand side and check for the absence of a value, but comparison operators like = can also complete their left hand side...offering more natural precedence. MOD is also infix. COUNT-UP acts like REPEAT, with a complementary COUNT-DOWN operation. So it shapes up like: count-up n 100 [ print [ unspaced [ if n mod 3 = 0 ["Fizz"] if n mod 5 = 0 ["Buzz"] ] else [n] ] ] It's the same idea, *evolved*. (The details about how this is driven by a complete absence of value (NULL) opposed to a "falsey" NONE! are beyond the scope of this post, but are fairly epic.) All told, it's nice to see a kind of coup-de-gras against FizzBuzz, where each word of code can be mapped back to the problem statement. This is no trick--things haven't been designed just to make FizzBuzz--the components are just elegant enough that this is one of the many problems it addresses cleanly. WANT MORE EXAMPLES OF "REBOL: EVOLVED"? There's plenty, but here's a nice one on how `--` and `??` are being reshaped for debug output: And hey, look...I know people are envious...but envy isn't necessary. They're good ideas--just respect them as such, and you can use them too., Posted by: Fork 16-Nov-2018/18:27:18-8:00 Referring to next/prev series entries I often used loops with a counter for those sorts of routines: repeat i length? x [print [x/(i) x/(i - 1)]], Posted by: Nick 5-Nov-2018/23:32:46-8:00 'inform' inside a function Well, then, there is a head-slapping moment. Regarding that concept of third-party documentation, some time ago, frustrated by the lack of documentation for VID, I wrote my own third-party documentation. Not that VID was undocumented, but the documentation that I could find was not organized to my liking for a reference manual. So after reading your above note, I went to MY OWN documentation, and THERE IS WAS, a section on request-list. What more can a guy do... , Posted by: Steven White 24-Oct-2018/14:51:12-7:00 Parse pattern matching You're looking for some fairly elementary pattern matching here that PARSE can certainly handle, though FIND will also be your friend here: PARSE: remember that for parse to return TRUE, you have to provide a rule that describes the input string: foreach ID FILENAMES [ if parse ID ["CV_Permits_" to end][ ; to end will match everything after your prefix print ["Process:" ID] ] ] FIND: the /MATCH refinement will only return 'truthy' if the search string is at the current index: foreach ID FILENAMES [ if find/match ID "CV_Permits_" [ print ["Process:" ID] ] ] , Posted by: Chris 22-Oct-2018/15:33:36-7:00 Parsing on a non-printable character Thank you. I just did this, and it seemed to work just fine. I keep forgetting about that collect/keep. CLIPBOARD-LINES: func [ /local CLIPSTRING LINEBLOCK ] [ LINEBLOCK: copy [] CLIPSTRING: copy "" CLIPSTRING: read clipboard:// LINEBLOCK: parse/all CLIPSTRING "^(0D)^(0A)" return LINEBLOCK ], Posted by: Steven White 16-Oct-2018/12:16:37-7:00 My algorithmic art Finnish seems to get translated fairly well by Google :), Posted by: Nick 30-Sep-2018/12:57:39-7:00 Parsing baby steps While this seems an easy task, a few matters make it more difficult than it looks with historical PARSE. One of the not-so-easy aspects is that the TO and THRU doesn't allow you to use complex rules, which complicates your paragraph termination conditions. This is a decision which was reversed in Red (and will be also in Ren-C, when time permits). You can try this in Red, and while there are likely workarounds for it in Rebol2 and R3-Alpha I'd rather consider the fact that this doesn't work as-is a bug than figure out what that would be: heading-rule: [ "===" copy heading to "^/" ( append html-out reduce [ <h1> heading </h1> newline ] ) ] paragraph-rule: [ copy paragraph to ["^/^/" | "^/" end | end] ( append html-out reduce [ <p> paragraph </p> newline ] ) ] parse in-text [ (html-out: copy {}) some [newline | heading-rule | paragraph-rule] ] print mold html-out, Posted by: Fork 10-Sep-2018/15:17:01-7:00 Setting a drop-down at run time Good point. VID is an artifact of a past era and if we want to find out some things about it, we are on our own to study it. So I tried to encapsulate your above advice into my little VID reference in case others might find it helpful. Thank you. , Posted by: Steven White 6-Sep-2018/9:06:07-7:00 Red: How to Pass Authentication for HTTPS URL Read? Hi Steven, I didn't state that well - R2 does support https, but does NOT work w/ sites that have imposed newer versions of TLS. Too bad R2 can't be updated...., Posted by: JackKOrt 24-Aug-2018/9:51:15-7:00 Full Circle Another suggestion might be to put the material on something like GitHub, put it under a Creative Commons licence, and open it up to pull requests for changes?, Posted by: Steve 23-Aug-2018/22:56:54-7:00