Hacker News new | past | comments | ask | show | jobs | submit login
What Python developers need to know before migrating to Go (repustate.com)
104 points by rachbelaid on April 24, 2013 | hide | past | favorite | 103 comments



> The code you write with Go just seems to be correct. I can’t really put my finger on it, but somehow once the code compiled (and it compiles QUICKLY), you just get the feeling that it’ll work (not just run without error, but even logically be correct). I know, that sounds very wishy-washy, but it’s true.

This statement needs to be qualified.

Switching from an interpreted to a static language will catch a certain class of bugs upfront. I've rewritten some small programs from C to Go, and the same logic bugs are present in both.

In this sense, switching to Go is no different than switching to Java/C in terms of the bugs it will catch. There's nothing in Go that sets it apart from other static languages in this respect (unlike Haskell).

> It’s very similar to Python in terms of verbosity (or lack thereof) and it treats functions as first-class objects, so functional programming is easy to reason about.

Where is map, reduce/fold, filter, scan? Go doesn't support functional programming primitives due to lack of generics.

I may not have written enough Go programs, but I find Go marginally less verbose than C thus far (ignoring concurrency). Channels and goroutines and are its most interesting features.


> you just get the feeling that it’ll work (not just run without error, but even logically be correct)

This is the feeling I get from good strongly/statically typed languages too. My best example is a ray tracer written from scratch in haskell. It took a good couple of hours, but then once it actually compiled it run the first time without error (but rendered everything behind the camera) and exactly as it was supposed to work on the second try.

I really like languages which give me that kind of feeling.


There are, in fact, many small features of Go that make it more safe than C in terms of runtime correctness. eg. it has much stricter rules about automatic type conversion (you can't assign one int/char type to another differently sized int/char type without an explicit cast), it has sane built-in string handling much less likely to result in buffer overflow style issues, you have to go way out of your way with the unsafe package to blow your foot off by doing pointer arithmetic, etc, etc. None of these small things by itself adds a lot over C or C++, but combined they really add up.

I did C/C++ programming professionally for more than 10 years (and come from a static language background) and I share the OP's view that compilable Go code is much more likely to be correct than code in other languages I've used, even static ones... the fact that the Go code compiled is of course no guarantee it'll be correct, but the Go compiler enforcing the rules of the Go spec does eliminate whole classes of common gotchas even ones that bite you in C/C++ and other compiled languages.


I agree. To be more specific, I occasionally use the strict typing to guarantee my units are correct. I can define two float types and know that I won't mix up a variable with nanometers with one using microns.

The lack of exceptions and forced handling of errors means you have to think of error handling immediately. It adds verbosity to code but also means most potentially failing calls have been explicitly handled, even if it's causing a fatal error and printing a message. Go considers unused variables an error, and while that can be a pain sometimes, it's also caught a few bugs where I've used an initialize and set operator (":=") in an inner scope, which didn't set the same variable in an outer scope.

The main thing I wish Go had is generics.


For me it is mainly a C successor that catches up with what the Pascal family of languages has been offering since the mid-80's, in terms of compilation speed, modules, concurrency and safety.


I know Go has been touted as a C successor since inception, but most new users seem to be coming from interpreted languages. Like this blogger, they attribute a lot static language advantages as unique to Go.

I don't see a lot of C/C++ developers switching, probably because they have sunk costs with their respective languages and Go doesn't offer very much by comparison.

I would definitely use Go where it seems appropriate, but I don't see it replacing C as a systems language.[0] Sometimes when I write something in Go, I look back and wonder why didn't I just do it in C. However, Go is great in a distributed systems / networking environment where most new code seems to be written.[1]

In the words of a friend, "You can pry raw memory access from my cold, dead fingers."

[0] systems == OS, drivers, etc.

[1] Motivations summarized in the abstract: http://talks.golang.org/2012/splash.article#TOC_1.


This is one of the areas where I actually take Go's defence.

Have a look at Native Oberon and AOS, both desktop operating systems developed at Zurich's technical university.

They are done in GC enabled systems programming languages and were used both as desktop systems by the teachers, as well as to teach operating systems classes.

Quite nice desktop environments using strong typed languages, but offering a Smalltalk like user experience.

http://www.inf.ethz.ch/personal/wirth/books/ProjectOberon.pd...

https://www.ics.uci.edu/~franz/Site/pubs-pdf/BC03.pdf

http://www.ocp.inf.ethz.ch/wiki/Documentation/WindowManager

The problem with any systems programming language is that it is only used as such, if an OS vendor makes it the only way to do OS programming. Like Microsoft does with C++ or Apple with Objective-C.


I worked on GNOME for a summer, and can see Go being a viable option for DE's. GNOME has added a lot of libraries to bring object support to C, but Haskell has proven gc language is fast enough for a WM (xmonad).

Go might need to improve its gc to prevent the occasional stutter, but it would otherwise be sufficient.

However my original statement defined systems as kernel code, since HN tends to have many opinions on the topic.

> The problem with any systems programming language is that it is only used as such, if an OS vendor makes it the only way to do OS programming. Like Microsoft does with C++ or Apple with Objective-C.

I see plenty of new C code still be written outside of systems, the problem is lack of exposure. HN community is fairly web focused but HPC, scientific computing, graphics, engines are still predominantly done in C/C++.


> However my original statement defined systems as kernel code, since HN tends to have many opinions on the topic.

That is how I understood it. Have a look at the Project Oberon book.

Assembly is only used for the boot loader, device driver glue and some GC implementations. The same type of stuff you need language extensions in C as well, as they are not part of ANSI C.

Everything was coded in Oberon or Active Oberon, depending on which OS version we talk about.

This startup is selling embedded compilers for Oberon that target 32 bit ARM since the late 90's.

http://www.oberonday2011.ethz.ch/talks/armembedded.pdf

The trick is to have control when the GC happens and to allow for manual memory management via a SYSTEM pseudo module.

But yes, in the current state of affairs C and C++ will outlive us anyway.


> I worked on GNOME for a summer, and can see Go being a viable option for DE's.

Desktop applications are not very demanding. You can write them in scripting languages like Python or JavaScript, both has been done in Gnome. The libraries/toolkits are more demanding.

> Haskell has proven gc language is fast enough for a WM (xmonad).

https://github.com/BurntSushi/wingo

> However my original statement defined systems as kernel code

Rob Pike (one of the Go creators) seems to define it differently:

"We designed it to be a systems level language because the problems we do at Google are systems level, right? Web servers and database systems, and storage systems and those are systems. Not operating systems, I don't know that Go would be a good operating system language but I am not sure it wouldn't be, what was interesting was because of the approach we took in the design of the language, somewhat to our surprise it turned out to be a really nice general purpose language." http://www.infoq.com/interviews/pike-google-go


>The problem with any systems programming language is that it is only used as such, if an OS vendor makes it the only way to do OS programming.

Well, one has to question then why no vendor made something like Oberon etc "the only way to do" his OS programming.

Perhaps because having POC OSes at some university wasn't enough, and performance was lacking of OS level work, and lacking in a way that Moore's law cannot address?

(E.g we see Go pausing for 1-10 secs every few minutes on large memory loads. Which might be hood for an academic OS, but not for the OS I want to run video editing, audio DAWs, large apps and application servers on. And even the attempt by SUN to write something as basic as a web browser in pure Java was dog slow circa 2000).


> one has to question then why no vendor made something like Oberon etc "the only way to do" his OS programming.

I reckon it is for the same reason we're still mostly running on PC-compatibles with an x86-based architecture. The only reason for that has been compatibility, not any kind of inherent technical superiority.

> Something as basic as a web browser

I am puzzled at how you can make such a statement. That is definitely one of the more complex programs running on a typical desktop.


It is always a matter of investment.

If Sun did not invest in JIT research Java would already be gone, the same for JavaScript JIT research.

Having used those systems I can say they were fast enough to be able to display videos. The codecs make use of Assembly, but the same is true when C is used.

Those languages were just victims of the C trap, were the OS copied the UNIX model and thus were being developed in C as well.

Which mainstream OS vendor can you imagine bringing an OS to the market, with an alternative systems programming language and being able to succeed at it?


>Which mainstream OS vendor can you imagine bringing an OS to the market, with an alternative systems programming language and being able to succeed at it?

If the language is good for this purpose, and the resulting OS is better, as in equally fast AND far more secure than the current ones (a marginal increase in security won't matter at all), then any big vendor.

If the OS is feature complete and can run current apps (even if recompiled) with a compatible system call API, then why not?


Microsoft certainly have the resources, and some interest as proven by their Singularity experiment. Obviously they haven't found it commercially viable as of yet, we'll see what the rumored Midori can bring.

But if Microsoft with all their resources can't make it performant enough to be of interest outside of academia (where Singularity ended up) then I doubt anyone can.

The thing is of course that native non-garbage collected operating systems aren't crash-prone, if they were then we would have seen a shift in systems language out of pure necessity ages ago. As it stands, bugs are found, bugs get fixed, systems end up stable and very performant.


Actually Microsoft is already heading slowly in that direction in Windows.

C is official legacy and its compiler won't be improved past C90.

C++ got the C++/CX extensions, which kind of make it language with integrated reference counting, if you only care about Windows. Assuming Windows 9 or whatever it will be called will have broader WinRT support and better commercial luck than Windows 8.

.NET applications are compiled to native code in Windows Phone 8, by making use of techniques developed during the Singularity project. So they got something out of it already, even if it is not at kernel level.

However it is a case of "Worse is Better" and I personally think it will take a few generations for young developers to replace the old mentality. Or I am just plain wrong.


Like this blogger, they attribute a lot static language advantages as unique to Go.

This is true, but there is one piece ~unique to Go: type inference. It doesn't exist in Java or C, and it's only just made it to C++.

For an individual coming from an interpreted language, it makes an otherwise statically typed language feel a lot less unwieldy and bureaucratic.


Again you keep trying to position Go as a C successor, I don't understand why you are so hellbent on that.

Look where C is being written today, mainly in libraries or very/extremely performance oriented applications and low level systems programming where any kind of unecessary overhead (performance, footprint, dependencies) is actively being avoided. Where does Go fit in here?

Instead Go has mainly seen an uptake in web oriented development, I personally think it also has great future in desktop style application development, but that remains to be seen.


> Again you keep trying to position Go as a C successor, I don't understand why you are so hellbent on that.

Actually I rather vote for D or Rust, after a few disappointments with Go's design.

What I will ALWAYS defend, regardless of the language, is the use of GC enabled systems programming languages.

I am an old dog and have used quite a few operating systems in academia and also internal in-house ones developed in such languages and know from experience they can be usable if only an OS vendor cared to support such languages.


So if it weren't for the tyranny of C, maybe today we'd be a lot more comfortable with concurrency programming, and have higher quality software in general if M2 had enjoyed more widespread use 30 years ago?


If it weren't for the tyranny of C, that doesn't mean we'd instead be using whatever you want - maybe today we'd all have to be using Pascal, or some other worse-is-better tool. Better result with concurrency? Probably not.

Anyway, popularity isn't the same thing as tyranny, there isn't some conspiracy to keep other languages down


Who knows, maybe.


Exactly. Go is Borland Pascal for the 2010s. Funny how slow progress is.


Yeah, just look how so many concepts from Lisp days are only now slowly becoming mainstream.

I want my Lisp Machine back :)


"The code you write with Go just seems to be correct."

Ironically, Eric Raymond made very similar statements _about Python_ in his 2000 article explaining why he had moved to Python from static languages and from his previous dynamic language of Perl:

"When you're writing working code nearly as fast as you can type and your misstep rate is near zero, it generally means you've achieved mastery of the language. But that didn't make sense, because it was still day one and I was regularly pausing to look up new language and library features!"

"This was my first clue that, in Python, I was actually dealing with an exceptionally good design. Most languages have so much friction and awkwardness built into their design that you learn most of their feature set long before your misstep rate drops anywhere near zero. Python was the first general-purpose language I'd ever used that reversed this process."

____and again, regarding a little program whose code he links in the article____. . .:

"That doesn't look too bad for deep black magic, does it? Thirty-two lines, counting comments. Just from knowing what I've said about the class structure, the calling code is even readable. But the size of this code isn't the real shocker. Brace yourself: this code only took me about ninety minutes to write—and it worked correctly the first time I ran it."

"To say I was astonished would have been positively wallowing in understatement. It's remarkable enough when implementations of simple techniques work exactly as expected the first time; but my first metaclass hack in a new language, six days from a cold standing start? Even if we stipulate that I am a fairly talented hacker, this is an amazing testament to Python's clarity and elegance of design."

"There was simply no way I could have pulled off a coup like this in Perl, even with my vastly greater experience level in that language. It was at this point I realized I was probably leaving Perl behind."

http://www.linuxjournal.com/article/3882


I don't think it's so ironic. He wasn't speaking in comparison to Python; Go does bring a lot of the feel of Python as far as its conciseness and regularity of syntax.


Thanks, I had just skimmed the article. You're right that there is no irony. And it may not even be a coincidence, may just be that one of the reasons that a person attracted to Python may also be attracted to Go.


Personally I find its dependency resolution to be one of the highlights of Go, and furthermore since circular dependencies are disallowed then that eases maintaining much larger and more complex codebases.


> This statement needs to be qualified.

Yeah, "seems to be correct" is a little wishy washy... I'd argue that Go has enough syntactic sugar to be easy to learn from a Python background, but enough structure that it encourages good software engineering practices.


> This statement needs to be qualified.

The whole paragraph is a qualification. How much more do you want??


You can actually do functional programming in Go. Lack of generics just means you have to think harder.

In fact, a friend of mine did a Go library to write functional-style code: https://github.com/tcard/functional


We have two differing definitions of functional programming. I would argue that your code represents functional style in an imperative language.

If function pointers are sufficient to qualify a language as a functional, then that would include C/C++.

In contrast, Rust has support for the standard functional language primitives.[0][1][2]

[0]: http://static.rust-lang.org/doc/core/vec.html#function-map

[1]: http://static.rust-lang.org/doc/core/vec.html#function-foldl

[2]: http://static.rust-lang.org/doc/core/vec.html#function-filte...


How about this for functional programming in C? https://github.com/cioc/functionalC

It's got some of your primitives (map and filter but no fold, but I'm assuming that it's just a matter of getting bored before implementing it) and closures.

It's not a serious project, but it serves as a counter-example.


I'm not sure what you're trying to say this is a counter-example to, exactly. wting said "represents functional style in an imperative language"; that's all this seems to be. And as the author of that code themselves all but says, you'd be crazy to use that in production code, so it's not a particularly "good" implementation either.

Nobody's questioning that a map-like thingy can be implemented in any Turing-complete language you choose, the question is whether it's actually useful in the context of the rest of the language. I can in fact write a generic map function in Go, by using reflection, but it'll be very slow, and it will still absolutely require the user of the map function to cast the result into the proper type manually since the Go compiler can't do it for you.

(You actually can do something like closures in C, though managing the lifetime of the closure data struct can be tricky. And that's actually the problem with functional programming in C; the functional style does not technically "require" GC to work properly, but it sure does encourage it awfully strongly. Or you need something like Rust, with strong support for explicit lifetime management. In C you're just begging for memory leaks with a functional style.)


Is that because in C, you have to explicitly pass around your lexical scope as fields in a struct, and then you have to remember to explicitly deallocate the struct and null out any pointers to it later when it's no longer needed?


Pretty much, yeah. Closures can actually be a problem for memory deallocation in garbage collected languages. Someone I know was working on a common lisp app and eventually found some of their performance problems to be related to the amount of data held onto by closures.


The thing about languages is that you can write other languages inside them. You can implement garbage collection in C. You can compile it to Java bytecode. You can convert Java bytecode to x86 assembly. You can write your own preprocessor to allow C++ style templates in Go. You can make a shim that will allow you to make calls to the Go networking library from a shell script.

The question is not whether you can do something, it's how many hoops the language makes you jump through to do it.


Can you be more precise about the difference between a program written in the functional style, and one which is written using functional programming?


Well there is the "official" definition on Wikipedia.[0]

Informally, my definition of a functional programming language is one that supports functional style as the default. (Hooray for using a recursive definition. :p) The language should strive for referential transparency and the language and compiler should be optimized for functional idioms.

Let's define the sum of a list functionally[1]:

    # Python
    sum = lambda x: reduce(int.__add__, x, 0)

    # Haskell
    sum = foldl' (+) 0
You could write this same function in C using function pointers and arrays. However it's not very convenient to do so. You would need to write a reduce function, an add function, anonymous functions don't exist, and syntactically it would be very messy. On top of all this, the compiler is not optimized for reduce functions vs an imperative for loop.[2]

More generally, functional style typically refers a style of programming where most functions are pure and side effects are contained specifically. This allows for easier reasoning of a program's correctness.

John Carmack has a post about functional programming in C++:

http://www.altdevblogaday.com/2012/04/26/functional-programm...

Summed up, functional style is about containing side effects and functional programming has built-in support for common idioms.

[0]: https://en.wikipedia.org/wiki/Functional_programming

[1]: This ignores the fact that sum() is already provided in most functional languages.

[2]: Python straddles my definition of functional programming and that's why it's awesome and frustrating at the same time. It supports many staple functional idioms but is not optimized for it. Function calls are very expensive, and thus recursive performance is also hurt tremendously.

Plus Guido hates functional programming:

http://python-history.blogspot.com/2009/04/origins-of-python...


> Lack of generics just means you have to think harder.

Or use other languages that are more developer friendly.


Name one that has generics and is developer friendly.


Well, you can start with all the functional languages that automatically are able to do these things you're talking about, like Haskell and so on. You can argue they aren't 'developer friendly' but you never defined that term to begin with, and people are certainly productive with those languages (developer friendly compared to what? Go is certainly not the most accessible language)

But in terms of more 'mass market' languages, C++ and C# both have incredibly robust generics that can be used to do real, no-foolin' functional programming, though doing it in C++ certainly takes a lot more effort and leans on modern libraries - closures are a comparatively recent introduction to the language. You've also got 'mass market' functional languages like F# to have fun with.

Then there are the more fun options, like writing your functional code in Lua or Python and running it in a high-performance runtime like LuaJIT/PyPy to get fairly competitive performance without even needing explicit typing or built-in 'generics'.


I think F# has aesthetics similar to Python, despite being a statically typed language in the ML family. It's open sourced, with great IDE support on Windows (via Visual Studio, including a free option) and good IDE support on other platforms via Xamarin's tooling. Does that count as "developer friendly"?


Developer friendly is a matter of taste. As for having some form of generics:

- C++

- Haskell

- Modula-3

- Ada

- Java

- OCaml

- Delphi

- F#

- Virgil (from Google)

- VB.Net

- Eiffel

- Sather

- Zonnon

- Scala

Just a small list.


A very large amount of this is "Moving to a statically typed language".

1. "Different assignment operator is used depending on whether you are inside & outside of function ie. = vs :="

= is an assignment, := is a declaration and assignment at the same time. It's true that you can't := outside a function (which I think is silly), but the comparison should be between these two:

    var foo string = "Hello"
    foo := "Hello"
2. "Else (or else if) has to be formatted properly, where the else is on the same line as the curly bracket from the if clause. Weird."

Whereas, coming from Python where indentation matters. Weird :-) Both are style conventions enforced by the language.


The same-line convention comes from automatic semicolon insertion at the end of lines. A semicolon is inserted if the line ends with "}", but not "{"... hence, "} else {". This is also the reason multi-line lists require a trailing comma.


The syntax is pretty explicit in not inserting the ';' after some characters; eg. '.' (which is why you can go:

    blah.Go().
    Go().
    Go()
Which is equivalent to:

    blah.Go().Go().Go()
I don't see why it would be significantly breaking to allow a } to similarly avoid the automatically inserted semicolon for if statements.

This wasn't a 'consequence'; this was a design decision.


> This wasn't a 'consequence'; this was a design decision.

A design decision with a sound reasoning: https://groups.google.com/forum/?fromgroups=#!topic/golang-n...


It's not the only reason. You can also just comment out some lines and it will still work just fine.


Come on, those are the two weirdest things about go syntax, especially for new comers.

(Honestly, why can you not 'for var x = 0; ...'? and only 'for var X := 0; ...; ...' but immediately below var x = 0; is just as valid. The := / var syntax in go is just plain weird).

Go is also the only place I've ever seen this syntax:

   if blah {
     ..
   } else {
     ..
   }
Maybe that's popular in some obscure places, but it is weird they made that the only valid syntax.

I mean, fair enough, Go has its own syntax, but these are pretty valid gripes.


   if blah {
     ..
   } else {
     ..
   }
> Maybe that's popular in some obscure places, but it is weird they made that the only valid syntax.

That is valid K&R syntax[0], which is used prevalently in C (e.g. Linux kernel). FYI, Rob Pike wrote a few books with Brian Kernighan (the K in K&R).

Go is designed for consistency and optimized for the compiler (e.g. mandatory braces, no unused import statements). Declaring a single canonical format (e.g. gofmt / PEP 8) solves a lot of syntax bikeshedding.

[0]: https://en.wikipedia.org/wiki/Indent_style#K.26R_style


PEP-8 isn't a "canonical format" though and people should stop treating it as one.


It should be. New languages should take a hard, firm but fair, stance on style when they are first created. It is the only opportunity they will get. You can always loosen it later if you really feel the need, but you can't tighten it later on (evidenced by attitudes exactly like yours.) I mean, unless you like endless style flamewars and bickering...

Even ignoring that benefit, taking a stance on style like Go has done allows style to be handled mechanically, which is more in line with the general hacker attitude anyway. Offload that stuff to the computer; let the programmer concentrate on doing the things the computer can't.


No, it pretty much is a canonical format. You don't have to use it, but then you are out of sync with members of the Python community who wish to adhere to the standard format


> Honestly, why can you not 'for var x = 0; ...'? and only 'for var X := 0; ...; ...' but immediately below var x = 0; is just as valid. The := / var syntax in go is just plain weird

Because var and := declaration+initialization are semantically different: when declaring multiple, variables, := allows redeclaration (which just overwrites an already declared variable's value instead of shadowing it), while var does not.

> Maybe that's popular in some obscure places

Err, K&R style (from which Go's style is derived and virtually identical, except for braces of functions) isn't exactly obscure... even the Java's Coding Convention (from 1999) does it exactly like that: http://www.oracle.com/technetwork/java/javase/documentation/...


> Go is also the only place I've ever seen this syntax:

Do you mean

    if blah {
        code
    } else {
        code
    }
as in parens-less if statement? Because I don't see anything odd in what you wrote, it's valid C or Java.

And if it's putting else, } and { on the same line, it's "standard" K&R, 1TBS, BSD KNF and java indent style/coding conventions.


I believe he's referring to the latter -- as opposed to:

    if blah {
        code
    }
    else {
        code
    }
Personally, I don't prefer the K&R way but I don't think it's either strange nor troublesome enough to worry about for more than a few seconds.


The argument is that putting anything between } and else breaks the else statement, so using } else { stresses that you cannot add statements either before or after the else.


it is weird they made that the only valid syntax


What you stated is not just that (which is not actually weird), but — quoting you

> Go is also the only place I've ever seen this syntax

compounded by

> Maybe that's popular in some obscure places

(thus calling Java's coding conventions or the K&R "obscure places")


Not, it's very pragmatic, based on a parser need (to make it simpler), and it's well explained in their docs.

Not to mention that's a well known style, has a lot of benefits (less wasted lines compared to the style that puts both brackets on empty lines, less potential for errors in than when you omit the brackets for a single statement), and, most importantly, puts and end to all bikeshedding.

Especially along with gofmt, go is a bikeshedding free language in regards to syntax.


It's because of arguments like this, that's why. They render a huge swath of subjective, unproductive discussions about style completely moot.


Well, that is the idea at least. Unfortunately it almost seems as though the style arguments will be replaced with the "pro/against enforced style" arguments.

Hopefully this new topic has less staying power.


I don't understand why this comment is being downvoted. I just learned something.

If Go enforces a specific coding convention at the compiler level, then that could legitimately be considered at least slightly unusual.

While it's true that this style is far from esoteric, it's also typically just that ( a coding style ). This strikes me as at least somewhat analogous to Python's whitespace indentation rules or Java's checked exceptions, in that what is typically a design choice is enforced by the compiler / interpreter.


It's a great choice for readability; cuts down on inconsistency.


That if/else syntax is used in K&R's The C Programming Language, the source of Unix (and thus of FreeBSD etc.), and it's pretty common in JavaScript. It may not be the most common syntax in modern C, but it's hardly weird or obscure.


> That if/else syntax is used in K&R's The C Programming Language, the source of Unix (and thus of FreeBSD etc.)

And it's part of Sun/Oracle's official java coding conventions.


Come on, those are the two weirdest things about go syntax, especially for new comers.

I don't really understand your 'come on'. I wasn't disagreeing with the OP about point #1, I was merely correcting what he said to make it clearer and I even agree with you (see my note about 'silly) that where you can and cannot use var and := is odd and unclear.

As for the concern about Go syntax and brace positioning, it will really depend where you come from. If have any experience of any note in any C-derived language (such as C++, Java, JavaScript, etc.) you will have seen people writing code like that for years.


>Go is also the only place I've ever seen this syntax

Then you should go read some more code. Because not only it's the one I've been using for ages (hah), but it's standard K&R style, one of the oldest and most established styles out there...


I use that conditional syntax all the time with Java.

K&R had it back in the 70s.


C was first released in 1972 and the first edition of K&R was published in 1978.


Corrected. :)


Because within the scope of that for loop x has been declared.


Many of these points are only really relevant to a Python developer new to statically-typed languages. For those points you could substitute s/Go/Java/g and it would be just as true, except that someone new to Java would probably lean on generics more than they should.

As for the other points, it would be nice to have more built-in types like a Set type, to be able to ignore "unused dependency" errors when running "go install", etc.

Oh, and I think he missed the most surprising thing about Go for newcomers: that "if" creates scope!


> Oh, and I think he missed the most surprising thing about Go for newcomers: that "if" creates scope!

Go is block scoped, and if statements are blocks. I don't see this as surprising.

I agree some set operations would be nice, maybe using an interface like Sort, but you can use a map as a basic generic set data structure. This is how many language implement a set anyway.


Go is block scoped, and if statements are blocks. I don't see this as surprising.

I meant surprising for someone used to Python, like the article author. I'm surprised he didn't mention it.


The real problem is that a set type needs to be built-in, i.e. you can't build satisfactory one yourself, because you don't have generics.


How many sane languages have function scope rules? Python has them, that's one. Javascript is a mess but might count. PHP is not sane at all. Most other things have block scope as far as I know.


Many languages have block scope, but not all.

Python, Ruby, and PHP have function scope, but idiomatic Ruby guarantees block scope for loops. In Python even list comprehensions leak scope.

JavaScript has function scope but has the `var` keyword for local scope. Lua has global scope but has a `local` keyword as well.

As I mentioned before, however, I was referring to developers principally familiar with Python (or at least dynamic, interpreted languages) coming to Go, since that is the basis of the article.


Yes, it's a good thing to mention for python devs, but I don't know if it's necessary in any other context.

Also your wording about javascript is weird. 'var' for scoping is function scope, what is your 'but' for? And proper lua doesn't use globals for temporary variables, it's firmly in the 'block scope' camp.


Yes, it's a good thing to mention for python devs, but I don't know if it's necessary in any other context.

The article's title is "What Python developers need to know before migrating to Go". I don't know how many times I need to repeat this. I can't go back and edit the original post to clarify.

Anyway, about JS, you are right; I was thinking "var" was like "local" or "my", but it isn't. Oh well.


'let' is coming up for that purpose.


This seems more like a list of things developers need to know if they've only ever used python.

Go has different syntax and rules than python, but so does C, Java, Erlang, and so on. I don't get why this is such a surprise. Don't approach a new language assuming you can directly translate from your last language du jour, and you'll be much happier.


I hope that "how to handle getting hackernewsed" is on the list. Text-only cache:

http://webcache.googleusercontent.com/search?q=cache:http://...


No constructors, so common idiom is to create NewType() functions that return the struct you want

It would be nice to see official constructors in Go, to encourage consistency, it feels a little ad hoc at the moment.

You can’t have mixed type data structures. Maybe it’s not kosher, but sometimes in Python I’ll have a dictionary where the values are a mix of strings and lists. Not in Go, you have to either clean up your data structures or define custom structs

I didn't understand this point. If you want you can use a map[string]interface{} to store arbitrary mixed types in a map (dictionary), though obviously no type checking is then done on the dictionary, but you could define an interface Inter which both types conform to and use map[string]Inter instead so that you know what you're getting and that it will respond as you expect.

If I want a list of just the keys or just the value, as in dict.keys() or dict.values(),

It'd be nice to see some enhancements to map for common operations like this, it's something I missed from Ruby. It'd be nice to have an ordered map in the standard library as well.

Else (or else if) has to be formatted properly, where the else is on the same line as the curly bracket from the if clause. Weird.

This sort of grammar quibble mystifies me - one of the nicest things about go is gofmt and the recommended formatting - I like that, for trivial points of grammar like this, there's only one way to do things which is considered correct. This isn't the style I'd personally use elsewhere (in C for example), but it's great that all Go code is formatted in exactly the same way - it makes it easier to read, and really is not hard to pick up.

If you’re using JSON and your JSON is a mix of types, goooooood luck. You’ll have to create a custom struct that matches the format of your JSON blob

This does have the advantage that you know what you're getting, and can't unmarshal unexpected objects by mistake when fed malicious/broken JSON.


I wrote a little wrapper while at OkCupid for dealing with adhoc JSON objects in Go, available here: https://github.com/okcupid/jsonw


Switching from Python to GO is a big boost in speed and a big sacrifice in terms of third party code.


In terms of third party code built in the same language, perhaps. Calling C is pretty straight-forward in Go (http://golang.org/doc/articles/c_go_cgo.html) and there are starting to be more and more 'native' libraries available (http://go-lang.cat-v.org/pure-go-libs for some, but by no means all).

So perhaps it is more of a sacrifice that is getting smaller day by day?


Why is it necessary to 'switch' at all? Can you only hold one language in your head at once?


I wasn't distinguishing between switching completely and switching just a part of the infrastructure to go, for brevity's sake.


map[rhubarb]bool is how Go does sets and []interface{} is how Go does heterogenous lists.

Also you can unmarshal JSON into an interface{} variable and get a mix of map[string]interface{} and []interface{} that you can deconstruct via type assertion if you know what to expect, so you can be a bit python-ish about JSON if you don't want to read it into structs.


> map[rhubarb]bool is how Go does sets

Actually, you should use map[rhubarb]struct{} since a struct{} requires no storage. You can test membership with this:

    _, ok := m[strawberryRhubarb]


[deleted]


Haskell has tuples. It also has pattern matching, which is destructuring done right. So I'm not sure exactly what you're getting at.


I just jumped into Go a couple of days ago. Was minding my own business when I suddenly arrived at its homepage. The online tutorial seemed interesting and I began completing it. Well, hello, where have you been all of my life? Go is quite something. To me, is like the right mix of C and Python. It reads very well, and is very minimal. I have been spending all of my night learning it. Have had so much much, in fact, more fun than I ever remember. Right now, I'm not very productive with it, but give me a few days. I never paid much attention to it, because what could be better than Lisp or Python? Go is not better, but its in the same category as those two (for me, at least).


> If you’re using JSON and your JSON is a mix of types, goooooood luck. You’ll have to create a custom struct that matches the format of your JSON blob, and then Unmarshall the raw json into an instance of your custom struct. Much more work than just obj = json.loads(json_blob) like we’re used to in Python land.

I believe you can use json.NewEncoder().Encode() to arbitrarily deal with interface{}'s


If only the site would load.


This. I've been trying it off and on for half an hour now, how did all these other people manage to see it?


By viewing the Google web cache of it.


Did you use Python bindings for libsvm?


the link doesn't work for me. anyone knows why?


One thing I can't wait to see (maybe when the Go ecosystem is more mature) is Gojure, a Clojure that runs on top of the Go environment. That would be badass.

ETA: I realize that it just looks like I'm spouting opinions if I don't get into why it would be badass. Essentially, Go is a language designed for production systems in one of the most demanding large-scale software environments on earth. Compilation is rapid, and the language does a lot of things that force code quality. The problem is that it still feels a bit verbose. Putting a Lisp on top of that (and Clojure is my favorite Lisp) would be really interesting.


Out of curiosity, are there any particular reasons why you like Clojure more than other Lisps/Schemes? I've played with it a little and found it kind of weird due to no car/cdr/cons, no TCO, loop/recur/trampoline, the usage of [], and various other quirks. It's a Lisp but you can't just write Lisp code in it, it requires learning new idioms. But I'm not good enough at Clojure yet to know what advantages it has over other Lisp family languages, aside from the Java libraries. What features of Clojure do you particularly like?


No.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: