There are several ways to solve this in Go. The first that comes to mind, assuming you want to truncate to the first 12 runes, not bytes:<p><pre><code> func main() {
v := []rune(os.Args[1])
if len(v) > 12 {
v = v[:12]
}
fmt.Println(string(v))
}
</code></pre>
Or more in the spirit of the C example in the post:<p><pre><code> func main() {
res := make([]rune, 12)
copy(res, []rune(os.Args[1]))
fmt.Println(string(res))
}
</code></pre>
Note that res will stay on the stack, just like C.<p>I expect the author is trying to say something about Go that I'm not quite getting. Perhaps that it is not an expression-based language, so to make code readable you need to make use of multiple statements. That's by design, but I understand it may be unappealing if you want to program in an expression-heavy style.
> Simple enough, in essence given first argument, print it up to length 12. As an added this also deals with unicode correctly<p>That's not true, Python 3 uses codepoint-based indexing but it will break if combining characters are involved. For instance:<p><pre><code> > python3 test.py देवनागरीदेवनागरी
देवनागरीदेवन
</code></pre>
because there is no precombined version of the multi-codepoint grapheme clusters so some of these 10 user-visible characters takes more than a single you end up with 8 user-visible characters rather than the expected 10.<p>edit: the original version used the input string "ǎěǐǒǔa̐e̐i̐o̐u̐ȃȇȋȏȗ" where clusters turn out to have precomposed versions after all. Replaced it by devanāgarī repeated once (in the devanāgarī script)
Doesn't the C version have a serious bug? If the input string has 12 or more characters, the destination string will not be zero-terminated.<p>From the strncpy docs:<p>"No null-character is implicitly appended at the end of destination if source is longer than num. Thus, in this case, destination shall not be considered a null terminated C string (reading it as such would overflow)."
The author awards some arbitrary points to C even though his implementation of the solution is broken. His similarly poor Go implementation receives zero of these arbitrary points.<p>Why does this deserve the attention of everyone here? The author did not compare languages, he compared his aptitude with these languages, and considered broken implementations to somehow be comparable.<p>A more meaningful comparison would be to implement simple, efficient, <i>working</i> solutions to these problems and comparing them. This, as it stands, does not lead to any useful discussion.
I'm not sure what the takeaway is from this blog entry. Is it that Python 3 can do substrings easier than the other languages therefore we should use Python 3? That was what I thought it was, anyway.<p>Seems silly to pick a language based off this single, silly criteria otherwise why not JavaScript or probably other languages that can make the code even smaller?<p>console.log(mystring.substring(0, 12));<p>So it just seems arbitrary and weak in my opinion.
There are at least three major flaws in the 7-line C program, even ignoring character set issues. (main returns int, argv[1] can be null, and strncpy doesn't always null-terminate the target). If you're going to compare languages, you should find someone who knows each of them well.
The Unicode situation in most languages is dismal.<p>Honestly though, the lack of generics for that Math.min function makes me happy I'm not programming in Go.
A mandatory smart-ass Haskell response<p><pre><code> import System.Environment (getArgs)
main = do
[str] <- getArgs
putStrLn $ take 12 str</code></pre>
Completely off topic, so if you are looking for discussion about the article skip this.<p>The low contrast ratio and bright colors on this blog are a bit hard to read. I normally switch to readability mode in safari when I encounter this, but the sites layout prevents this from working.