# TCL mapping question

I’m trying to solve the Roman Numerals exercise, and so far I’m going pretty well, but I don’t really understand how does the map work. I tried doing this at the end:

``````string map {CCCCCCCCC CM CCCCC D CCCC CD XXXXXXXXX XC XXXXX L XXXX XL IIIIIIIII IX IIIII V IIII IV} \$result
``````

But it doesn’t work at all, and separatedly, while the map to CM works, the rest don’t seem to. How does it exactly work?

What’s the value of `\$result` at this time?

Depends, but it basically is the number without the shortenings. So for example, in the case of 3999, result is MMMCCCCCCCCCXXXXXXXXXIIIIIIIII.

Basically, it walks the given string character-by-character, trying to match one of the “key” strings. If one is found, the replacement is made, and the walk continues at the next character.

Hmm, “works for me”

``````\$ tclsh
% set result MMMCCCCCCCCCXXXXXXXXXIIIIIIIII
MMMCCCCCCCCCXXXXXXXXXIIIIIIIII
% string map {CCCCCCCCC CM CCCCC D CCCC CD XXXXXXXXX XC XXXXX L XXXX XL IIIIIIIII IX IIIII V IIII IV} \$result
MMMCMXCIX
``````

Guess it’s time to check the full code then, cause for me it doesn’t work on testing.

``````proc toroman {n} {
set result ""
append result [string repeat "M" [expr \$n / 1000]]
append result [string repeat "C" [expr \$n % 1000 / 100]]
append result [string repeat "X" [expr \$n % 100 / 10]]
append result [string repeat "I" [expr \$n % 10]]
string map {CCCCCCCCC CM CCCCC D CCCC CD XXXXXXXXX XC XXXXX L XXXX XL IIIIIIIII IX IIIII V IIII IV} \$result
return \$result
}
``````

Ah, `string map` returns a value, it does not replace a value.

In Tcl, `\$varname` is the contents of the variable. Once the parser substitutes the variable content, the command (“string map” in this case) cannot know anything about which variable provided the value.

The manual pages try to be explicit about it. For example append

append varName ?value value value … ?

and string map

string map ?-nocase? mapping string

TL;DR - you’ll need

``````    set result [string map ... \$result]
return \$result
}
``````

Or just implicitly return the value of the last command

``````    string map ... \$result
}
``````

Understood, it now works. Thanks a lot!