@paperwing said:
Stuff about exceptions
In this case, errors are much more verbose than exceptions, and has no advantages over exceptions. Exceptions are cleaner and easier to code against. You can still catch errors and deal with them the same way, and you don't have to bubble them up in a critical path. They're also harder to forget. Exceptions are easy to use in concurrent code, and (at least in C#) it's easy to know what state is valid (as long as you don't do something like modify the parameters in the method).
@paperwing said:
For a less silly example, what if I'm processing a big file line-by-line, and one line has weird data in it that I don't care about, because all the other lines are still valid? I can't stop for one measely line that has a misplaced semicolon in it. So I ignore the error. As long as the processing function recognises the invalid data and doesn't corrupt the program state, it's cool. And what if I do report the error? Well, what if all the lines are weird? Then I end up spamming the log or the console. That's bad too. I remember using an mp3 player that did exactly that, spamming the console when it hit a damaged MP3 header.
You should be doing validation on your lines as you process them, not blindly processing and then throwing an exception when it fails. Or if a line being formatted correctly is an exceptional case, then you can catch that exception, possibly store it somewhere, and continue. Errors has no benefits over this.
@paperwing said:
But if you're writing a program that is gonna be presented to a user with little to no programming ability (and especially with no incentive to debug your code), then why show them a stacktrace at all?
As has already been pointed out, you have this idea that if you throw an exception, it will eventually be shown to the user. This couldn't be further from the truth. Maybe quit using crappy programs in a crappy OS? ;)
@paperwing said:
You can implement an interface however you like. You can decide whether to use a pointer receiver or a value receiver
What's the purpose of having a pointer to a type inherit an interface? What is the "thing" that is actually implementing it? You might be able to convince me that this is a good idea, but I certainly can't see why it ever would be.
@paperwing said:
If the language didn't have shadowing, we would end up thinking about local variable names a lot more in order to use descriptive ones.
Shadowing is one of the worst language features you can possibly have. You don't have method overloading, but you have variable shadowing?? You would have to think about different names?? How long are your methods that you need so many similar variables?
@paperwing said:
Shadowing is convenient, if sometimes a bit confusing.
So to you, it lets you program faster with more bugs?
@paperwing said:
True, no classes. No type hierarchy either, i.e. no inheritance. That's by design, and with good reasons (see this, if you are curious: <font color="#698d73">http://www.youtube.com/watch?v=sln-gJaURzk</font> ). You can still have methods, though, and interfaces, and embedding (which is subtly but significantly different from inheritance).
You're going to have to do better to convince me that no classes and no type hierarchy is a good thing without saying "watch this hour long video."
@paperwing said:
You are confusing some terms.
Well, no, he's not. From Wikipedia: "In different programming languages a subroutine may be called a
procedure, a
function, a
routine, a
method, or a
subprogram." The difference can be summarized as a static function/method or an instance function/method.
@paperwing said:
You can have your "member functions" on structs too, yes. And you can even define normal functions, of which the first parameter can be a struct, that is true too.
Ok, so you can still define your functions related to the class inside the class? That's good, although the syntax for declaring an instance method is pretty verbose.
@paperwing said:
True, go doesn't have constructors, because constructors are just an unnecessary special case of functions.
Er, no, they're not. They define what happens when you create a new instance of an object. If anybody can call "new foo()" and you don't get to define what happens when they do that, then (as he said) you have no way to guarantee a consistent state of the object.
@paperwing said:
Your claim about inconsistent state is false.
No it's true, see above.
@paperwing said:
Name your function differently. For example, in the os package there's
Oh, so you can be extremely creative when naming functions (where you can actual need a lot of similarly/identically named things) but not with variables?
@paperwing said:
It simplifies the language and speeds up the method lookup when using interfaces, I think.
First off, if you don't know that it speeds up the method lookup, then don't say that it does. Second, has anyone had a performance problem with languages doing method lookups? Then it's not a problem that needs fixing. Third, it doesn't simply the language at all. If I want to print something, I'll type "Print" and look at the different lists of arguments that it can take, easy as pie. In your method, I have to know ahead of time the different name that matches the arguments I want to give it. Not easy.
@paperwing said:
the uncapitalized print and println functions (without any package qualifier either) are there for bootstrapping purposes.
I wanted to see in the docs for printf and println if it said "don't use these". It doesn't.
@paperwing said:
The go lang developers were careful not to define any methods on built-in types, by design. That is because it keeps the type system clean and simple.
How in the world could you possibly think that??
@paperwing said:
str += string(ch1) + string(ch2)
"Go doesn't implicitly anything."
I understand why, but there are some things that are good to have done implicitly. Char->string conversion is one of them.