Live data from Hacker News

What Python developers need to know before migrating to Go

blog.repustate.com

61–70 of 117 posts

Re: What Python developers need to know before migrating to Go

#61
post #54
post #50

Earlier quoted context omitted.

'+' is damn near universal. '&&' && '||' !universal.

They're not universal, but they're essentially so; pretty much everyone who's used C(++), Java, C#, ... has seen && and ||, and knows what it is. And people who've only used languages with 'and' and 'or' will only take a few minutes to get up to speed (they have the option of spending longer complaining about it if they want).

I don't think the argument is that people can't understand '&&' and '||', but that using 'and' and 'or' is a better choice.

Re: What Python developers need to know before migrating to Go

#62

Some thoughts after spending ~100 hours with Go. - Function overloading is a major convenience that you will miss. There are differently named versions of every function and you will call the wrong version with the wrong arguments all the time . The number of functions in the standard library could be reduced by at least 1/4 if they'd got this right. The official FAQ ( http://golang.org/doc/faq#overloading ) explains…

> between chars (or "runes" WTF?) and integers.

"Runes" were the original name, as implemented in Plan 9 by the same folks, for what the standards committee later decided to call the relatively blaze term "Unicode codepoints"--and which are not quite the same thing as characters.

(In fact, I would say that the notion of a Unicode "character" is ambiguous to the point of uselessness--there are glyphs composed from several codepoints (base glyph + combining accents), which should be treated as one "character"; there are ligatures that hold single codepoints, but which semantically are multiple "characters"; there are stacking languages where one "character", representing a whole word, will be composed together from several codepoint "radicals"; while in other ideographic languages, each pre-composed idea-part is its own "character" and has its own codepoint; and so forth.)

Re: What Python developers need to know before migrating to Go

#63
post #57

Earlier quoted context omitted.

> In Go: len("нєℓℓσ") // 12, because there are 12 bytes utf8.RuneCountInString("нєℓℓσ") // 5, plz kill me i am an abomination I'm not sure I understand your objection. Bytes and UTF8 characters are different things, and you can't abstract away the difference. There are also times, perhaps the majority of times, when you will need the byte count of a UTF8 string. That means you need at least two different length funct…

I think the majority of the time you want the number of utf8 characters and not the byte count. In fact I have never wanted the byte count. If I did I would expect something like byteLen and Len. Not the other way around. You should be optimizing the common case, not the exception. Obviously I'm not a language designer so perhaps I'm talking out of my ass but I've heard this complaint A LOT.

Aside from API, there's a convincing performance argument to have len() return the byte count rather than number of utf8 characters.

The implementation of strings in Go is a 2-word struct containing a pointer to the start of the string and the length (in bytes). Under this implementation, len(s) is O(1) and RuneCountInString(s) is O(n). It makes sense to have the default case also be the fast one, particularly since people appreciate Go for its performance.

Alternatively, you could store the rune-count in the 2-word struct to reverse the above runtimes. However, this is detrimental for the common operation of converting between []byte/string as well as writing a string to a buffer. Both of those operations are a simple memcpy with the actual Go implementation, but would be O(n) using this alternate implementation.

Perhaps you could make it a 3-word struct that contains both byte-length and rune-length; Then all strings take up additional memory as well as requiring more overhead when used as function arguments.

Re: What Python developers need to know before migrating to Go

#64
post #49

Some thoughts after spending ~100 hours with Go. - Function overloading is a major convenience that you will miss. There are differently named versions of every function and you will call the wrong version with the wrong arguments all the time . The number of functions in the standard library could be reduced by at least 1/4 if they'd got this right. The official FAQ ( http://golang.org/doc/faq#overloading ) explains…

> Using && and || for logical operators in this day and age is just ridiculous No it's not, it takes 10 minutes to learn that && means and and || means or (maybe a little longer to get the hang of it properly), and this knowledge transfers to many programming languages. (This is a little like arguing "we shouldn't use + when English has a perfectly good word 'add'"; symbol reasoning is valuable.)

That's 10 minutes where I could be... you know, living my life, man. Everybody knows what + does. You don't have to teach a high schooler that "if A or B" means "if either A or B is true". They just get it. But what the heck does "if A || B {}" mean?

Re: What Python developers need to know before migrating to Go

#65
post #60

Earlier quoted context omitted.

> Actually, you can declare a fixed-length array as a type. So if you need to return a triple of ints, you can declare the return type to be [3]int and have the type system check that you're actually returning an array of ints of length 3. That's different from a tuple as it is commonly known in Python and statically typed languages. Tuples can be heterogeneous in languages like Python, OCaml, and Haskell, which Go f…

Something like this? http://play.golang.org/p/6nvdLWOi5D

Not quite. What you have is a single type interface{} that happens to be the super type of all other types. You still haven't solved the issue of having multiple different types in a tuple--you've just thrown all the type information away!

Think of a tuple as an anonymous struct. (Or perhaps think of a struct as a tuple with labels :P.) We want to statically differentiate between a pair of ints, a pair of strings and an int, string pair, which we simply can't do with interface{}.

Re: What Python developers need to know before migrating to Go

#68
post #49

Earlier quoted context omitted.

> Using && and || for logical operators in this day and age is just ridiculous No it's not, it takes 10 minutes to learn that && means and and || means or (maybe a little longer to get the hang of it properly), and this knowledge transfers to many programming languages. (This is a little like arguing "we shouldn't use + when English has a perfectly good word 'add'"; symbol reasoning is valuable.)

That's 10 minutes where I could be... you know, living my life , man. Everybody knows what + does. You don't have to teach a high schooler that "if A or B" means "if either A or B is true". They just get it. But what the heck does "if A || B {}" mean?

Actually, you do have to teach most high schoolers (actually most people) what "A or B" means. The common usage reads that as "A xor B"

Re: What Python developers need to know before migrating to Go

#69
post #63
post #57

Earlier quoted context omitted.

I think the majority of the time you want the number of utf8 characters and not the byte count. In fact I have never wanted the byte count. If I did I would expect something like byteLen and Len. Not the other way around. You should be optimizing the common case, not the exception. Obviously I'm not a language designer so perhaps I'm talking out of my ass but I've heard this complaint A LOT.

Aside from API, there's a convincing performance argument to have len() return the byte count rather than number of utf8 characters. The implementation of strings in Go is a 2-word struct containing a pointer to the start of the string and the length (in bytes). Under this implementation, len(s) is O(1) and RuneCountInString(s) is O(n). It makes sense to have the default case also be the fast one, particularly since…

Why not a 2-word struct with the rune count instead of the byte count? There's zero performance cost for many strings because the rune count is known at compile time. For the rest, most strings are too short for Big-O analysis to be relevant and I would guess (enlighten me if I'm wrong) that the cost of computing the bounds of each character is negligible on a modern processor. Multi-byte chars in a string are going to be adjacent in memory, adjacent in cache, and therefore trivial for today's not-at-all-instruction-bound CPUs. Again, correct me if I'm wrong.

Re: What Python developers need to know before migrating to Go

#70

Earlier quoted context omitted.

That's 10 minutes where I could be... you know, living my life , man. Everybody knows what + does. You don't have to teach a high schooler that "if A or B" means "if either A or B is true". They just get it. But what the heck does "if A || B {}" mean?

Actually, you do have to teach most high schoolers (actually most people) what "A or B" means. The common usage reads that as "A xor B"

A very good point. I still think it's a big win if it makes it 1% easier for new programmers to understand.
Post reply on HN