GopherCon 2014 Videos
confreaks.com
confreaks.com
I mean, there is a precedent for this sort of thing.
http://iubio.bio.indiana.edu/soft/util/gopher/gophercon1.txt
[1]: https://en.wikipedia.org/wiki/Gopher_%28protocol%29
[2]: gopher://gopher.floodgap.com/
[3]: https://addons.mozilla.org/en-US/firefox/addon/overbiteff/
[4]: gopher://sdf.lonestar.org/
Finally, the relative numeric success of Gopher over WWW was discussed (there are orders of magnitude more Gopher servers than WWW servers out there): Gopher seems to have won out primarily because of the ease of entry (it's much harder to put up a WWW server than a Gopher server), although another factor may be that a hierarchical presentation is more appropriate than hypertext for the broad-based audience of a CWIS.
:)
> Ken: p.s. one of larrys comments was "why isnt function spelled func?
> Rob: fine with me. seems compatible with 'var'
> Rob: anyway we can always say, "larry said to call it 'func'"
The joke about the profound error of using whitespace just shows how partisan these discussions are. In go, with the semi-colon insertion rules and with gofmt, there is an implicit whitespace rule all over again.
Personally, I like whitespace because its how my mind reads code. Its nice in Python, mostly because of how concise Python is to read. Its a bit of a bind in Java, where you don't trust tools to roll-up functions but on the other hand they all seem so long and full of boilerplate. With gofmt, the go world lives in a significant whitespace world they just don't want to admit it :)
Can you explain what this means?
Note that in languages that don't mandate the open brace be on the same line as the code that opens the new scope, this can happen during a merge:
// original code
if (foo)
{
printf("foo is true!")
}
// after the merge
if (foo)
someFunction()
{
printf("foo is true!")
}
Now this code will always print "foo is true!". Because Go requires the open brace to be on the same line as the if, this type of bug is impossible in Go.Gofmt will never change the behavior of your code, so you don't have to "worry" about what it will do. It only makes cosmetic changes to code, never functional.
As willvarfar points out, I feel Rob Pike is being disingenous when he talks about this. Golang uses less significant whitespace than Python, but it exists, the difference is in degree. If he prefers to minimize the impact of whitespace in Go code, that's fine. But why does he have to talk about it as an error or misjudgment?
If significant whitespace is such a bad idea, why do exist keywords that require whitespace around them in Go (package, func, type, etc.? Why can't I use whitespace in names in Go? This didn't happen in good old FORTRAN ;)
func (){
a := 1
return a
}
while ugly, this still compiles just fine. It would compile just as fine if you randomly flipped some of the spaces into tabs.Whitespace is not significant in Go.
The difference between significant whitespace and requiring "some" whitespace is that if you did something like that in Python, you could end up with a program with different logic depending on which spaces were flipped to tabs. This is why mixing spaces and tabs in Python is verboten.
In go, you can mix spaces and tabs all you want, wherever you want in your code and it will never ever change the logic of your code, period. (obvious exceptions for changes inside string literals)
So, it's not really a matter of degrees, and Python's method is completely broken if you ever mix tabs and spaces, which as Rob Pike points out, are completely indistinguishable in the default views of most editors.
def my_func ( ) :
a = 1
return a
It will run without a problem because only leading space is significant. Then you can mix tabs and spaces, add the space you want, blank lines, etc.The Python coding style guideline (PEP 8) is very specific in that it recommends the use of 4 leading spaces per level. You can use a very simple program with regular expressions to solve any problem you could have in the mix of tabs and spaces in your files.
Now, try this example in FORTRAN.
parameter(x=2)
print*,"The parameter is ",x
Why can't I use commas or parentheses to delimit all the tokens in Go? Why does it insert semicolons without asking? Is such an arbitrary and problematic decision as the significant leading whitespace in Python. def my_func():a=1;return a;
Try it, it works!Yes, it's just leading spaces that are different in Python, I know. I actually like python, but the space indenting is fragile.
if (a == 1) {
return a }
else { return b }
This won't compile in Go. But whitespace wasn't significant in Go, right? Take out the curly braces, add a couple of colons and this will run without a problem in Python.My point is, there isn't such a big difference between Go and Python. Significant whitespace doesn't mean "whatever Python does differently", it means that whitespace is syntactically meaningful. Any whitespace in any part of your program has the potential for changing the meaning of it. If it does, then it's significant.
It's trivial to make a text editor show tabs and insert spaces even if you press tab. It's trivial to make a program that will switch leading tabs for the number of spaces that you want from a file. I don't say it's trouble-free, but it isn't such a big issue; and automatic semicolon insertion isn't trouble-free either, as you can see. You won't have problems with any of them if you take a little care.
In Python, leading whitespace and newlines are syntactically significant. In Go, newlines are in many cases syntactically significant. In both of them space around many keywords is significant (try to write packagemain in Go, see how it goes), and you can't put whitespace in names.
Other than lisps, most languages have significant whitespace -- treating, for instance, newlines as having an important distinctions from other whitespace.
So this is technically correct (and I had never though about that before, so thank you for pointing that out!). However, I think '\n' and '\r' are not directly comparable to '\t' and ' ' characters.
All whitespace is only visible by its boundaries (kinda like certain 70s minimalist sculpture, actually). Newlines affect vertical structure, whereas tabs and spaces affect horizontal structure. So far it's the same.
However, we don't read text vertically, we read it horizontally (I know there are exceptions, but not in any significant programming languages that I know of). As a result we don't group characters by vertical whitespace the same way as we group characters by horizontal whitespace: in most natural languages, the difference is paragraph separation vs word/sentence separation. Programming languages also follow this coarse/refined level. Think about how we construct indented text in programming languages: relative to the vertical position.
So I would say that while both cases have the problem that we can only observe whitespace by the characters that surround them, in the vertical whitespace that happens at a coarser, less ambiguous level than horizontal whitespace. And I think that's why using significant newlines should be less failure prone than significant tabs/spaces.
I think we do read code vertically and it is significant in all programming languages, and I think that it is a core problem with acceptance of Lisps, because they unusually strongly avoid leveraging the two-dimensional nature of typical code editing environments in favor of having pretty much the perfect purely-horizontal syntax.
> So I would say that while both cases have the problem that we can only observe whitespace by the characters that surround them, in the vertical whitespace that happens at a coarser, less ambiguous level than horizontal whitespace.
I do think there is an ambiguity difference, but its not because we read horizontally but not vertically, but because horizontal whitespace in common use -- i.e., that people are used to using on a keyboard in the context of programming -- is limited to newlines (and, while there are different means of expressing newlines, they are mostly driven by platform rather than personal preference and are, in any case, easy to account for), whereas tab/space holy wars are as old as line oriented PLs that allow indentation (whether they are sensitive to it or not).
Of course it is significant, I was agreeing with you there! But my point was:
d
o
_
y
o
u
_
e
v
e
r
_
w
r
i
t
e
_
c
o
d
e
_
l
i
k
e
_
t
h
i
s
?
But maybe I should have worded it differently: we read text in "row-major order", not "column-major order". That's basically the difference I talk about.
Also, there is another difference between newlines and indentation: newlines only go "forward" (next line), whereas with indentation you go back and forth into levels of indentation. It's not the same. The closest thing I can think of is that one language where you could write the exponent of a formula on a line before, faking superscript, or the index of a formula on the next, faking subscript. Making mono-typed source code look like math formulas basically (and probably a pain to type out). That's the only programming context I can think of where newlines are actually significant in a similar fashion to indentation.
Dependency management for Go is definitely on people's radar. https://github.com/tools/godep has been getting some traction.
There is a big discussion between those that think a language without dependency management tooling does not make sense in modern times.
And those that think it should be abolished from the face of earth and replaced with git revisions and pure open source, regardless of industry needs.
Only works for source code packages, not binary dependencies.
There isn't a way to specific source code versions/tags in a portable way. Also makes the import paths dependent on your repositories.
> [go get] Only works for source code packages, not
> binary dependencies.
There's no such thing as a binary dependency in the Go ecosystem. (At least, not without stretching some definitions.) It's one of Go's greatest strengths, actually. > There isn't a way to specific source code versions/tags
> in a portable way.
Well, the best practice is to vendor[0], and there are plenty of third-party tools like godep[1] that can manage it for you.___
[0] http://peter.bourgon.org/go-in-production/#dependency-manage...
I am on the side for proper dependency management.
> It's one of Go's greatest strengths, actually.
Which will keep it outside the boring closed source enterprise commercial library tooling.
Does not seem very supportive of vendoring.
> I am on the side for proper dependency management.
Vendoring is one of several proper dependency management options. It's also the option most suited to the Go ecosystem at this time."X? We don't need no stinkin' X".
Along the same lines, my mother used to always buy cars that were manual transmission and without power windows or locks, because they were features which made the car cost more, broke often, and were expensive to fix. The minor conveniences they afforded were not worth the costs.
I don't quite know what he is talking about when he talks about main and initialization. Can anyone elaborate on this for me?
I hate to say this because I feel like a jerk in doing so, but I'm about 25 minutes in and the little gopher that scrolls across the screen (some sort of advertisement, I think) is so distracting. It is awful.
For example: http://play.golang.org/p/tvlX7cqaaB
This is important for package level variables such as arrays. Since there are only a very limited number of types which can be constants in Go, everything else which you'd use like a constant needs to be initialized.
I guess in Go you can also have relatively elaborate static initialization, so it has a similar problem as C++? Interested if any Go users can elaborate on this.
There are executed before control reaches main, and you need to have import relationships into consideration.
Path to getting generics thus becomes:
1. A preprocessor that eats ggo (generic go) files and emits go. This is is like the original C++ which translated to C for compilation.
2. Someone integrates ggo into go to speed it all up.
No. He said there were no plans for generics, which has been the story for some time. The official FAQ still states [0]:
> Generics may well be added at some point. We don't feel an urgency for them, although we understand some programmers do.
> Generics are convenient but they come at a cost in complexity in the type system and run-time. We haven't yet found a design that gives value proportionate to the complexity, although we continue to think about it. Meanwhile, Go's built-in maps and slices, plus the ability to use the empty interface to construct containers (with explicit unboxing) mean in many cases it is possible to write code that does what generics would enable, if less smoothly.
It is my understanding that what Mr. Pike means by there being no plans for generic is in relation to the sentence
> We haven't yet found a design that gives value proportionate to the complexity, although we continue to think about it.
Predictably, he is asked about generics (54 mins in). His reply is very clear:
"There are no plans for generics. I said we're going to leave the language; we're done."
No, the official apologist story is: we will add them as soon as we find a way to avoid all tradeoffs of the 3 different approaches to generics.
And when asked how are they going to find this "magic bullet" solution since noone seems to be looking for it, some Go devs wrote HN comments to say that "we are looking into them [generics]".
I'm a little offended, because nobody admitted what Rob said at the conference -- and they even tried to convince us of the contrary. That was like 2-3 months ago.
Other than that, I spend my time with other languages.
Rob said something interesting at the end, it appears they are leaving the language to the community and stepping out.
> Rob said something interesting at the end, it appears
> they are leaving the language to the community and
> stepping out.
He said nothing to imply that at all.E.g an app that would process a multimedia file offline (so latency is of no concern) still runs circles around most other languages if its done i C or C++.
And of course 90% or something of desktop apps are written in C/C++.
People act as all those apps, which is what we use everyday, don't exist: browsers, editors, media players, terminals, OSes, mailers, etc etc. Even web apps use those as their substrate.
Just wanted to highlight that most desktop programs people use by the millions are in fact written in C/C++ (statistically) -- and it's not all about GC, web programming and services.
Any compiler for any language can have SIMD support, it is just a matter of the compiler writers bothering to provide such support.
And if the language does not support it, I don't see why developers are so afraid of touching a Macro Assembler.
(If you don't believe me, note that not everything in Java is actually an Object - since there are multiple typekinds[0], that means that not every type can be used where Java expects to see an Object). That is part of the reason for the mess surrounding the so-called wrapper types like Integer (which are themselves neither objects (wrappers are passed by value, not reference) nor primitives (they are in most[1] cases unboxed to primitives, but are not themselves the same things as primitives).
Aside from the fact that Java didn't add generics until 1.5 (if I remember correctly), which certainly didn't stop its popularity, it cannot be emphasized enough that the need for generics is dramatically reduced if one actually understands how to use interfaces idiomatically in Go and understands how they are different from "interfaces" in Java or other languages[2].
While I occasionally run into a situation in which Java-like generics would make things marginally easier, they're few and far between; interfaces bridge far more of the difference than non-Go programmers often realize. And has has been explained to death already (both at Gophercon and on the mailing list) - generics are not out of the question for a hypothetical Go 2, but there are going to be no more changes to the language syntax for Go 1.
[0] I counted either 5 or 6 at one point when I was using Java heavily in university, but that was several years ago so don't quote me on that exact number.
[1] emphasis on "most" - there are some very "fun" edge cases that you can find here!
[2] I'm reminded of how Haskell has both "class" and "return" as keywords that have nothing to do with their Java counterparts - I think Go's "interface" is along the same lines - it's the same identifier/term, but a very different meaning.
It's still not true that interfaces are generics, though.
> Aside from the fact that Java didn't add generics until 1.5 (if I remember correctly)
But that was a big mistake in Java: they had to implement them using type erasure and primitives didn't work with them (due to backwards compatibility), and they had to duplicate the collections library to have non-generic and generic collections (again due to backwards compatibility).
> [2] I'm reminded of how Haskell has both "class" and "return" as keywords that have nothing to do with their Java counterparts - I think Go's "interface" is along the same lines - it's the same identifier/term, but a very different meaning.
I don't think the difference is that stark—interfaces in Java and interfaces in Go are essentially the same thing. The facts that all values can be wrapped in an interface (which is also true for C#, I believe) and that interface matching is structural instead of nominal are relatively minor.