Go at SoundCloud(backstage.soundcloud.com) |
Go at SoundCloud(backstage.soundcloud.com) |
I have always wondered, however, that if moving to a new language seems great because of the language, or because you have such a better understanding of the implementation of the problem you are trying to solve.
New is fun. Exploration is fun. I think a lot of people will swear by a new language simply because it's not old and probably doesn't suffer many of the same deficiencies they're used to in their "every day," language.
This to me is an illusion however. One must remain skeptical and treat new, untested languages with even more scrutiny than an old one. Many of these new languages will make extraordinary claims. Discovering the evidence to support these claims is often left as an exercise to the programmer.
That being said, new has a lot of advantages. It's free to try to break away from past paradigms that perhaps limited programmers. Stability can always come later once the core ideas have been fleshed out. And it's always fun to work on fresh ideas rather than refining the same old ones that we're plagued with.
Personally I wouldn't use a language and compiler that only just reached 1.0 this year in a production system. If I was really interested in Go I'd certainly hack with it and perhaps on it, but I wouldn't trust it to be reliable. Maybe that makes me an old, stodgy fart but I trust wisdom over brilliance when it comes to building systems that are dependable and robust.
With Go 1.0 there is an even greater focus on stability: http://golang.org/doc/go1compat.html
Go is also quite different from most 'new' languages, many people find it to be the most fun language they have used in a long time (even after using many other new languages).
This might be in part because one of the things that makes Go special (and my favorite "feature") is not just the features it has, but all the stuff it doesn't have.
Go is simple and doesn't get on the way and lets you focus on the problem, other "new" languages are often described as "powerful", but much of the work involves using their "features", when Go is more often described as productive, the focus is not in the language and its features but on the problem you are trying to solve and the language gets out of the way.
Certainly it deserves more faith than any random language designed for the exploration of new paradigms and features and which is only used by its maker?
Like any other compiled language would do.
(Yes, I will commit to finish the rest of the series)
How would you make something like a GUI without being able to specialize classes by overriding certain methods?
Have I misunderstood his point?
http://code.google.com/p/goclipse/ https://github.com/nsf/gocode
I am using the evaluation version of pycharm and I must say it is quite impressive, although paying for an editor does seem odd after using emacs for so many years but it is a well designed software and I think worth the price.
That said I have been asked to give sublime text a try and I must say it looks a lot better than pycharm, I think will give it a try next (it is certainly a lot cheaper and if I understand correctly has much wider language support than pycharm).
It took us 25 years to begin to see that the king is naked!
UPDATE: I have a feeling that in 25 years we'll be dissing the current fad du jour - functional programming.
> UPDATE: I have a feeling that in 25 years we'll be dissing the current fad du jour - functional programming.
In 25 years, we will be laughing at the present for sure. I just disagree on what that fad is (functional programming is hardly popular enough to be called a "fad", but it's been bubbling under for 30+ years). I think it is dynamic programming languages like Ruby and Python, which to some degree are great but fall apart quickly. Another candidate is Node.js -style asynchronous programming, which will be laughed at once a mainstream language ships with a proper async model like the IO manager of Haskell or Erlang.
Eliminating side effects sounds brilliant until you start interacting with filesystems or networks. What, you can't memoize those ops or split them across a pmap?
That king is an impostor. http://c2.com/cgi/wiki?AlanKayQuotes
> UPDATE: I have a feeling that in 25 years we'll be dissing the current fad du jour - functional programming.
Only if unwashed masses start doing a half-baked version of FP without really understanding it. This is what happened to OO. It's similar to what happens to musical genres.
especially, as most new engineers on Go projects lament, during error handling
Does any have pointers to reading material or care to explain the lack of error handling in Go? ..., err := doStuff()
if err != nil {
return err
}
The usual text editor features, like templates, reduce the typing, but the point is that the programmer must think, each time, about what they want to do when a function fails. This can become either a really good habit, or a distraction, depending on your perspective and problem domain.When people say Go poor or no error handling, this is probably what they are complaining about. The fundamental properties offered by try/catch/throw are unpacked by Go into defer, recover and multiple value returns and type switches. Go's designers make the argument that when used thoughtlessly, exceptions encourages error handling antipatterns.
This requires some flow analysis, but brings real benefit and safety.
I don't see how the latter is true. What's the practical difference between wrapping a function call in a try/(no-op)catch and entirely ignoring the error return value?
Where are the moving parts?
There's always many problems that aren't immediately apparent but difficult.
Why would this bother you that they are trying new things and learning?
The only situation you positively need operator overloading is when doing arithmetic, and you should do that using the built in types. This, of course, sucks when the built in types are inadequate, and you e.g. want to use a arbitrary precision library such as BigDecimal in Java.
This, of course, is an opinion, and I'm not shy to admit it's been shaped by being burned by Lift, the Scala web framework which makes heavy use of symbolic function names which makes it incredibly difficult to talk about or search for answers online.
Those guys seem to manage the flexibility pretty well.
I personally like overloading, but I think it's probably too easy to abuse, and I can see how it would cause problems with a team size larger than 5.
As far as I can see, whenever the Go team encountered a language feature that could possibly be abused, they always deferred to leaving it out. Whether that is good or bad I'm not sure we will know until we have years of experience with it.
All features can be abused.
The Go philosophy is more to leave out features that obscure the meaning and understanding of code (what is also known as "magic").
Also part of the Go philosophy is to not include any feature unless it is clear that its benefits are greater than its costs, and which might interact in unpredictable ways with other existing features.
In other words, the default is to leave things out, rather than to include them, the opposite of a kitchen sink approach.
However, operator overloading is very much needed for when creating user defined types that have arithmetic properties, such as bigint, or matrix.
As for the confusion about whether + means "add" or "concatenate", that is unresolvable. The D programming language deals with it by introducing the ~ binary operator to mean "concatenate". No more problems.
Although in D one can overload operators to mean any crazy thing one wants to, the consensus in the community is to eschew non-arithmetic use in the same manner that the C community has condemned:
#define BEGIN {
#define END }In go you get polymorphism via interfaces and you can share implementation via embedding. http://golang.org/doc/effective_go.html#embedding
addClickHandler(myFunction)
Any customization you could do with inheritance could be done with a callback function instead, provided that the object has the hook you want.In Go, there is also an "interface" which is basically a set of methods.
By reading the code "foo + bar" you can't know what is really doing internally.
He is talking about operator (+-*=[]&) overloading. Not method overloading.
Briefly, functional programming is good at one use case (adding new operations over the data type) and weak at one use case (adding new data type variants), while OO is the opposite (adding new data type variants is easy, while adding new operations is not). You have to choose between OO and FP based on which notion of extensibility is more important to you for the problem at hand (unless you use the relatively exotic solutions of multimethods or the generics trick that Wadler originally proposed).
My takeaway is that OO and FP both have their time and place, and the pragmatic programmer will learn when to use one or the other instead of choosing one camp and bashing the other side.
I think it works because people don't usually just go around wantonly pushing objects onto each other. It's usually part of a DSL that's used deliberately. Some of the craziest I've seen were things like _why's Hpricot library, which made a sort of xpath-like DSL:
doc / :div / ".foo"
If I saw it out of context I'd assume it was some sort of pseudocode....that doesn't accurately describe a flaw in Go at all, and stems from a common misconception of Go's type system; namely that it is Java's type system, which it is decidedly not. The interfaces make a big difference.
An interface is simply a set of methods. Any object that implements those methods implements that interface. Adhering to an interface is implicit; you never have to say "type Stanley implements the Cat interface". If the Cat interface is just a "Meow" method, and Stanley can "Meow", Stanley is a Cat.
Take, for example, the io.Writer interface. io.Writer is a method set that contains a single method: the write method. This is the definition for io.Writer:
type Writer interface {
Write(p []byte) (n int, err error)
}
This interface definition says "a Writer is any object that has a Write method. The Write method must accept a slice of bytes as its only argument, and it returns an integer and an error". Any object that implements this method also implements io.Writer. Therefore, any function that accepts an io.Writer may accept any object that defines this method. (when accepting io.Writer, the object's type is io.Writer; the only thing you can do with an io.Writer object inside of a method that accepts an io.Writer parameter is utilize its Write method, since that's the only thing you know it has).So, for example, in the encoding/json package, there is an Encoder object. The Encoder object has just one method: the Encode method. This is the signature for the Encode method:
func (enc *Encoder) Encode(v interface{}) error
this method definition reads "the function for the * Encoder type called Encode accepts an interface{} v and returns an error". interface{} is the empty interface; all objects implement at least zero methods, so any object can be supplied; it is valid to pass any object into the Encode method. The returned "error" value will let us know if something has gone wrong.Now then. We know that we're encoding data to the json format, but to where is it being encoded? Where is the output going? The io.Encoder object embeds an io.Writer object; encoded items are written into the writer. That's a big leap. How do we know which io.Writer to write to? We inject the io.Writer when we create the encoder. This is the signature for the function that creates a json encoder:
func NewEncoder(w io.Writer) *Encoder
It has only one argument; io.Writer. io.Writer has only one method; the Write method. That means that for any data target at all, if you define a Write method, you can encode json to it.So what io.Writers are commonly found? There is an io.Writer for a UDP socket, a TCP socket, a websocket, an http response, a file on disk, a buffer of bytes, etc. The list goes on.
With this one Encode method, and this one Write interface, we are able to Encode json data to arbitrary targets. There's none of that JSONFileWriter, JSONHTTPResponseWriter, JSONUDPSocketStreamer stuff like you would get in other statically typed languages.
go's error handling is nice, but since it doesn't force it on you, it leads to errors of omission.
The only problem with OOP is people using OO without taking the time to learn it properly.
Of course Go is already in production at Google because the Go team designed it to fit particular pain points that Google was having, so it's going to have the libraries that are needed to solve those problems. The question is whether the current libraries are there to solve your problems, and, as others noted, it's not that cut-and-dried.
Personally, I'm not as worried about reliability as I am roadblocks. Say, for instance, we spend a month moving our framework over to Go. Then we find a problem that is yet unsolved. Either we solve it ourselves at an unknown cost or we have to just ... wait.. until another group solves it while we make payroll in other ways.
I'm lacking any real evidence here, maybe Go doesn't have a library for our Message Queue (not true, just an example). Now we aren't just porting, we're writing a pooling message queue interface that is beyond our pay grade in the language.
> spend a month moving our framework over to Go
Seems a little extreme. Just use it for small, discrete projects. No need to bet the farm.I think for experienced devs, a text editor is quicker for dynamic languages (less experienced people will get good mileage from an IDE). Go is sort of weird in that it reads like a dynamic language, so a text editor is Good Enough, while the static compiler helps to catch the sort of bugs that float up when you're doing manual (and hence, human-error-prone) refactoring work, like changing the type of something, which IDEs tend to automate for you before compile time. That's why GoSublime really is all you need for Go, as far as I can tell. (NOTE: I've not written anything like even a medium project in Go).
It hits the sweet spot between emacs and pycharm quite nicely and I am at this point inclined to buy a license, I think an IDE is more useful for languages like java or scala but for python sublime text will do for me.
Re. the use cases for an IDE, my point was that as my side projects keep growing in size, I need something which is smart about things like refactoring, comprehensive autocomplete, support for debugging etc.
As for Java, Python the context in the page likely to point to its intended audience (and it helps they have been around for ages etc). Otoh, " go " is likely to be used in a lot of literature, including other programming related texts.
Try searching for something with clojure, and then try go -- the quality of results is usually substantially different, and my unsubstantiated hunch is that not all of it has to do with lack of go-related content.
Seems to be getting better though..
For example, in Javascript: "Hello" + " " + "World!". What the operator there is doing is concatenating the strings, so if you had a method to do it you wouldn't call it add - you'd call it concat.
In ruby you can implement certain numerical methods including +
In smalltalk + is a binary method, you can give your methods all sort of symbol names. Same with Scala I think.
Hmm, are we talking about (user defined) operator overloading as a language feature, or about overloaded operators? For example, I hate that 1/2 and 1.0/2 are different things in most languages, but I haven't heard anyone call this operator overloading in the context of C.
Not really. HTML/CSS/JavaScript combination is not really OO, but works really really well.
In general, I think that any "programming language" for GUI is a fail - we need to develop a declarative approach to GUI (like HTML/CSS, but with more features (e.g. effects) and more emphasis on Application Development (e.g. it's still really hard to create a photoshop-like interface in HTML), less on text presentation).
An interesting approach to declarative GUI programming from Adobe.
HTML+HTTP works really well as a way to scale up client / server GUI over a high latency / low bandwidth network. That's its strong point; not that it makes for a good UI in terms of human factors.
C's multiple-arguments-but-only-one-return-value always was a bit weird. Does anyone know how C's authors decided on this feature?
The problem is it's no better than C
Multiple return values are pretty clearly better than C. The comma-OK or comma-err idiom is verbose, but powerful and unambiguous.http://www.reddit.com/r/programming/comments/w1ig0/things_i_...
It might seem petty, but whilst I understand rust avoiding overloading functions entirely (due to type problems and code obfuscation), it was enough to turn me off entirely, in this case sending back to D.
Bear in mind this is not to say Rust is a bad language - there's plenty to like about it. ;)
trait MatrixMultiplyRHS<Result> {
fn mul(matrix: Matrix) -> Result;
}
impl<RHS:MatrixMultiplyRHS<Result>,Result> Matrix : Mul<RHS, Result> {
fn mul(rhs: RHS) -> Result {
rhs.mul(self)
}
}
impl float : MatrixMultiplyRHS<Matrix> {
fn mul(matrix: Matrix) -> Matrix {
// ...implementation of matrix scalar multiply...
}
}
impl Vector : MatrixMultiplyRHS<Vector> {
fn mul(matrix: Matrix) -> Vector {
// ... implementation of matrix multiply for vectors ...
}
}
impl Matrix : MatrixMultiplyRHS<Matrix> {
fn mul(matrix: Matrix) -> Matrix {
// ... implementation of matrix multiply for matrices ...
}
}
It's admittedly a bit awkward, but maybe that's OK to discourage overloading unless you actually need it. Still, your point was very interesting -- I didn't realize this was possible! -- and I'll spread it around the team.Just as a warning, I've already aired this topic on github, so maybe that might be a good place to discuss it: https://github.com/mozilla/rust/issues/2961
I don't want to cause a fuss. While Rust might not work for my needs/wants/desires, that's ok. I highly respect those who don't attempt to please everyone. :)
Did you have a look at the Eigen library (C++)?
http://eigen.tuxfamily.org/dox/TutorialMatrixClass.html
I have never worked with this library but it seems to me that they have not the problems you described. Maybe having a look at it brings up some new ideas...
Whether you agree with that latter point is moot. Go's designers were and are fully aware of sum types; they chose to omit them from Go for a reason, not because they were ignorant of their existence.
function Parent() {
// somestuff
}
function Child() {
Parent.call(this);
}
Child.prototype = new Parent();
Child.prototype.constructor = ChildBtw, you can also do classes with JavaScript: http://mootools.net/docs/core/Class/Class
JavaScript's prototype-based OOP is a superset of class-based OOP.