>>REBOL [ snip] >> >>string: ask "Please enter a string to upcased: " >>posctr: 0 >>upcase-string: foreach character string [ >> posctr: posctr + 1 >> either character > 91 >> [ change string character - 26 ] >> [ character ] >>] >>upcase-string: foreach ... Hmm, are you trying to implement a function (upcase-string: func [ ] [ foreach ...]) or do you mean to be producing something you can reuse later by calling upcase-string? (i.e. upcase-string: [ foreach ... [] ]. do upcase-string? Or are you trying to assign the string the user entered - converted to uppercase - to upcase-string? I'm assuming the latter. In that case you do have a few more problems ... and there is IMHO a very elegant solution: In REBOL a block evaluates to the last value it assumes. Last value in your example means the value valid during the final iteration of foreach. In your example the last thing foreach will return may be one of two things: a) the result of executing the block [change string ...] b) the result of executing [character] This leads to two extremely different results: If the last character in string happens to be an uppercase character, either will choose [character]. What foreach will return is character. Character is not of type string! it is of type char!. upcase-string will point at a single character - type char!, which is the last uppercase character of string. On the other hand, if string's last character happens to be lower case, then either will choose [change string character - 32] and upcase-string will be pointing at whatever it is that change returns. What does change return? Here: >> change [1 2 3 4] 5 == [2 3 4] >> change at [1 2 3 4] 4 5 == [] If you compare the two results you notice that change returns the series type (block, or string ...) it was changing at the position immediately FOLLOWING the index that was changed. In the first example we changed the item at index 1, change returned the block beginning at index 2. In the second example we used at ... 4 to modify the item at index 4 of [1 2 3 4]. Since that was the last item of the block, change returned the block beginning at its tail. So, if the last character of string happens to be lower case, then [change ...] will be executed and that will result in upcase-string pointing at the end of the modified string, immediately behind the last character. What you want, however, is for upcase-string to point at the head of the modified string. I like your notation (upcase-string: foreach ...) and therefore here is yet another variant, one designed to support the assignment of the modified string to the leading upcase-string (BTW, we don't need the posctr, you never do anything useful with it, probably you wanted to use to index into the string, but you forgot?): upcase-string: foreach character string [ append "" either character > 96 [character - 32] [character] ] Here what foreach returns is the result of append, which is the string "" after all the characters, in upper case, were appended to it. Accordingly upcase-string points at "" after it contains all uppercase characters. (Did you know that literal series, such as strings "" or blocks [] are persistent and not newly allocated at each function call or iteration? Always use word: copy [] or word: make block! [], if you want to be using a new, empty string or block at each iteration or new function call!!!! Here we are exploting this.) Elan
