Go is PHP for the Backend(skife.org)
skife.org
Go is PHP for the Backend
http://skife.org/go/2012/11/18/go_part_1.html
70 comments
From what I was able to gather, the authors gripes tend to be with the lack of meaningful whitespace and "tabs".
Both the goto arguments of someone who lacks enough understanding of language fundamentals to point out any actual flaws.
Both the goto arguments of someone who lacks enough understanding of language fundamentals to point out any actual flaws.
For the sake of accuracy there was also some stuff in there about a conflict between first-class functions and the type system, and some stuff about errors being easy-to-ignore return values.
Yes, and those are pretty solid points. Too substantial to just sweep under the rug.
[deleted]
I'm a die-hard Python/PEP8 fan. Non-significant whitespace, I could take or leave, but tabs as indentation just make sense. You're separating form from content, which, as programmers, we should be all for.
As a pedant and an anal retentive person, I love gofmt. It's a big part of my coding peace of mind.
As a pedant and an anal retentive person, I love gofmt. It's a big part of my coding peace of mind.
As I describe language structure in Go to people, I keep telling them that "go fmt" is an amazing tool that you will wish you had for every language. I am met with many incredulous stares at the suggestion that a program that messes with your formatting could be a good thing... but it is!
>From what I was able to gather, the authors gripes tend to be with the lack of meaningful whitespace and "tabs".
Then you weren't able to gather enough. Besides tons of other stuff he mentions in the post, he has a comment below it adding:
- The existence of make() for the "our language is not powerful enough for us to express our language" tops the list for me. A couple more off the top of my head:
- Stack allocation is quietly converted to heap allocation iff a pointer to the stack allocated object escapes.
- Maps, channels, and slices are non-pointer reference "special" types.
- Struct literals require a dangling a comma, but you cannot use dangling commas elsewhere.
- make(), new(), and import() all look like function invocations, but are also syntax(ish) (and have special support in the parser). In the case of the first two, they even return values.
>Both the goto arguments of someone who lacks enough understanding of language fundamentals to point out any actual flaws.
Well, then again, the above looks like the goto response of someone that didn't really got the article (which show a great understanding of Go, even if we forget the added clarifications in the comment section).
Then you weren't able to gather enough. Besides tons of other stuff he mentions in the post, he has a comment below it adding:
- The existence of make() for the "our language is not powerful enough for us to express our language" tops the list for me. A couple more off the top of my head:
- Stack allocation is quietly converted to heap allocation iff a pointer to the stack allocated object escapes.
- Maps, channels, and slices are non-pointer reference "special" types.
- Struct literals require a dangling a comma, but you cannot use dangling commas elsewhere.
- make(), new(), and import() all look like function invocations, but are also syntax(ish) (and have special support in the parser). In the case of the first two, they even return values.
>Both the goto arguments of someone who lacks enough understanding of language fundamentals to point out any actual flaws.
Well, then again, the above looks like the goto response of someone that didn't really got the article (which show a great understanding of Go, even if we forget the added clarifications in the comment section).
The `make` function is an example of an inconcistency. The language does not have generics, yet this built-in function is a generic one.
As far as Go being safer and cleaner because it lacks modern language features, generics would make the language safer (compare to casting all over the place, which is less safe, and has a runtime cost). Some modern languages also don't have null pointers, further increasing safety.
As far as Go being safer and cleaner because it lacks modern language features, generics would make the language safer (compare to casting all over the place, which is less safe, and has a runtime cost). Some modern languages also don't have null pointers, further increasing safety.
I don't really view "make" as inconsistent - the fact that builtin functions have special powers doesn't strike me as particularly unusual. If they didn't I presume they'd just be part of the standard library.
Besides, it seems that the inconsistency (if any) is the fact that the rest of the language doesn't have generics - something that I hope will be resolved in the future, but without which I am coping surprisingly well.
Finally, null pointer dereference does not cause undefined behaviour, as in C, C++. Go will panic (and you can safely recover). I'm not convinced that removing null pointers will eliminate the cause of these bugs. I think the idea of "failing fast" would help diagnose bugs much faster - although I see reasons for disagreeing. I do not think Go is intended or recommended for safety-critical applications, where special languages such as Ada are used.
Besides, it seems that the inconsistency (if any) is the fact that the rest of the language doesn't have generics - something that I hope will be resolved in the future, but without which I am coping surprisingly well.
Finally, null pointer dereference does not cause undefined behaviour, as in C, C++. Go will panic (and you can safely recover). I'm not convinced that removing null pointers will eliminate the cause of these bugs. I think the idea of "failing fast" would help diagnose bugs much faster - although I see reasons for disagreeing. I do not think Go is intended or recommended for safety-critical applications, where special languages such as Ada are used.
> the fact that builtin functions have special powers doesn't strike me as particularly unusual. If they didn't I presume they'd just be part of the standard library.
It strikes me that the primary expectation of a built-in function is not having to import anything, and not having to namespace-qualify it on use. It circumventing the type system IS a surprise. In Go, I believe not only generic-ness appears, but also overloading.
Go as a complete package is very cool, though! I think the reason its warts get brought up disproportionately often is a reaction to its evangelists going a bit overboard in claims of simplicity/orthogonality.
It strikes me that the primary expectation of a built-in function is not having to import anything, and not having to namespace-qualify it on use. It circumventing the type system IS a surprise. In Go, I believe not only generic-ness appears, but also overloading.
Go as a complete package is very cool, though! I think the reason its warts get brought up disproportionately often is a reaction to its evangelists going a bit overboard in claims of simplicity/orthogonality.
> Finally, null pointer dereference does not cause undefined behaviour, as in C, C++. Go will panic (and you can safely recover). I'm not convinced that removing null pointers will eliminate the cause of these bugs. I think the idea of "failing fast" would help diagnose bugs much faster - although I see reasons for disagreeing.
Dereferencing nulls in Java is not undefined either, so what? And the notion of 'failing fast' is exactly why null pointers should be modeled in the type system. What faster way to catch bugs than at compile time? Furthermore, how do you know you will quickly hit a NPE in you code at runtime, if it happens to be in a code path that is infrequently accessed? Ironically in the OSCON talk mentioned in another comment here, Pike mentions that dynamic typing is pushing some compile time errors into runtime, which is exactly what is happening here.
Dereferencing nulls in Java is not undefined either, so what? And the notion of 'failing fast' is exactly why null pointers should be modeled in the type system. What faster way to catch bugs than at compile time? Furthermore, how do you know you will quickly hit a NPE in you code at runtime, if it happens to be in a code path that is infrequently accessed? Ironically in the OSCON talk mentioned in another comment here, Pike mentions that dynamic typing is pushing some compile time errors into runtime, which is exactly what is happening here.
The crucial difference is that static typing is a well understood problem.
The subset of "modern languages without null pointers" and "languages used to write a lot of serious software" is zero.
And notice "a lot" in this sentence. Majority of serious software is still written in languages like C++ or Java, which are either much less safe than Go or at about the same level of un-safeness.
While I'm sure someone wrote serious software in Haskell, very few (comparatively speaking) did. We can theorize why "modern languages without null pointers" failed to take off at the scale of Java or Python, but that they failed is a fact and that makes all their properties, including lack of null pointers, of questionable utility in the craft of actually writing useful software.
Go is a pragmatic, minimalistic languages, built on proven and well understood ideas.
The subset of "modern languages without null pointers" and "languages used to write a lot of serious software" is zero.
And notice "a lot" in this sentence. Majority of serious software is still written in languages like C++ or Java, which are either much less safe than Go or at about the same level of un-safeness.
While I'm sure someone wrote serious software in Haskell, very few (comparatively speaking) did. We can theorize why "modern languages without null pointers" failed to take off at the scale of Java or Python, but that they failed is a fact and that makes all their properties, including lack of null pointers, of questionable utility in the craft of actually writing useful software.
Go is a pragmatic, minimalistic languages, built on proven and well understood ideas.
> that they failed is a fact and that makes all their properties, including lack of null pointers, of questionable utility in the craft of actually writing useful software.
This seems like something akin to the just world fallacy. So far, no language with feature X has achieved mainstream success; therefore, feature X is of questionable utility. I don't think this makes much sense. Programming languages are combinations of a large number of features and design decisions, any of which (or none of which!) could be responsible for their unpopularity. Some features have value that is immediately obvious once you've experienced them, irrespective of the viability of the overall language they may be embedded in.
This seems like something akin to the just world fallacy. So far, no language with feature X has achieved mainstream success; therefore, feature X is of questionable utility. I don't think this makes much sense. Programming languages are combinations of a large number of features and design decisions, any of which (or none of which!) could be responsible for their unpopularity. Some features have value that is immediately obvious once you've experienced them, irrespective of the viability of the overall language they may be embedded in.
Every language that becomes popular, including Go, brings something new to the table that wasn't present in mainstream languages previously. In fact, it is precisely the languages that don't bring anything new that don't tend to become popular. There are many, many features that Go has that haven't appeared in mainstream languages before, and this is a good thing.
Besides, Scala code tends to avoid null (it's only in there for compatibility with the JVM), and it has quite a few users.
Besides, Scala code tends to avoid null (it's only in there for compatibility with the JVM), and it has quite a few users.
>I don't really view "make" as inconsistent - the fact that builtin functions have special powers doesn't strike me as particularly unusual. If they didn't I presume they'd just be part of the standard library.
It's not unusual (as it happens elsewhere too), but it IS inconsistent.
A builtin function should just mean: it's always available and not part of the importable library. Not "special behavior".
It's not unusual (as it happens elsewhere too), but it IS inconsistent.
A builtin function should just mean: it's always available and not part of the importable library. Not "special behavior".
Generics aren't included for two reasons:
1. They haven't figured out a way to implement them without impacting performance significantly
2. They're not as necessary as you might think.
While they're open to adding them if #1 changes, in response to #2, I find I don't miss them as much as I would have thought - and that's coming from a strong advocate of statically typed, functional languages. In idiomatic Go, I just don't need them as often as I would have thought, and the interfaces are well-designed enough to make up for much of the difference.
http://golang.org/doc/go_faq.html#Why_doesnt_Go_have_feature...
1. They haven't figured out a way to implement them without impacting performance significantly
2. They're not as necessary as you might think.
While they're open to adding them if #1 changes, in response to #2, I find I don't miss them as much as I would have thought - and that's coming from a strong advocate of statically typed, functional languages. In idiomatic Go, I just don't need them as often as I would have thought, and the interfaces are well-designed enough to make up for much of the difference.
http://golang.org/doc/go_faq.html#Why_doesnt_Go_have_feature...
I have read those same arguments over and over.
Just because generics do not come up as often does not mean they won't make programs safer and/or faster. Almost all of the workarounds I have seen for the lack of generics can easily be applied to Java for instance.
There were several questions that came up on the Go mailing list asking how to convert certain code to make it more "idiomatic". The resulting code had several layers of indirection, interfaces composed of interfaces, and so on, that ironically it would have looked much more concise, and would have been type safe in a more "traditional OO" language like Java.
Just because generics do not come up as often does not mean they won't make programs safer and/or faster. Almost all of the workarounds I have seen for the lack of generics can easily be applied to Java for instance.
There were several questions that came up on the Go mailing list asking how to convert certain code to make it more "idiomatic". The resulting code had several layers of indirection, interfaces composed of interfaces, and so on, that ironically it would have looked much more concise, and would have been type safe in a more "traditional OO" language like Java.
Not sure why you would expect to hear anything but the same thing over and over, in response to the same complaint being raise.. over and over.
I don't think anyone denies that adding generics, if done properly, would improve the language. The only real controversial thing being suggested is that generics are not worth an implementation that is not up to standards. Personally, I think that is a reasonable position.
I don't think anyone denies that adding generics, if done properly, would improve the language. The only real controversial thing being suggested is that generics are not worth an implementation that is not up to standards. Personally, I think that is a reasonable position.
[deleted]
When people mention that they don't find generics necessary, they should mention the type of work they do. For someone building an application, I can believe that one can do without generics, and still get a good application out. However, for someone writing a library, I think that their absence will be much more noticeable.
My least favorite feature is block scoping combined with the := operator.
For example, this works:
For example, this works:
var x Foo
x, err := doSomething()
if err != nil {
...
}
this does not: var x Foo
if x, err := doSomething(); err != nil {
...
}
This pattern (or some variant) introduces more bugs in my code than I would like to admit.What do you mean by 'does not work'? Your second example will work but the x declared in the if statement will be local to that statement (note not to the block but the entire statement).
In both cases you have redeclared x. In the second the scope is different.
See: http://play.golang.org/p/c9B-FXL0Fw
In both cases you have redeclared x. In the second the scope is different.
See: http://play.golang.org/p/c9B-FXL0Fw
var i = 0; <--- valid
i := 0 <--- Valid
for (i := 0; ...) <--- Valid
for (var i = 0; ...) <--- Invalid
No?I'm not sure how much you know about Go based on your comment, but you have a ; in the first line that is not legal in Go (and you haven't declared the type); you have parens on your for loop and that too is not valid.
If I rewrite your comment in correct Go I get
If I rewrite your comment in correct Go I get
var i int = 0 // valid
i := 0 // valid
for i := 0; ... { // valid
for var i int = 0; ... { // Not valid
Your final line there is only needed if you want to define the type of i at declaration time inside a for loop. That would be better written for i := int(0); ... {Actually, the following is valid syntax in Go 1.0 and later:
var i = 0
The use of "var" without a type is a common idiom when binding global variables, such as: var ErrTooLarge = errors.New("bytes.Buffer: too large")
Oddly, the := shortcut is not legal in the global context. Also fun: var (
i = 0
j = 0
)
So, going back to the original comment -- yes, Go has some odd little shortcuts and inconsistencies.Why is := not valid in the global context? I have been bitten by this time and time again. Is there a reason for it? It makes no sense to me.
I believe the answer is related to the simplicity of the parser.
I see, thank you. Too bad this wart is exposed, though.
Sure; I was just saying, the parent comment asked for an example of inconsistency there it is.
Either allow the use of var to declare a variable, or dont.
Dont mix and match in different contexts; this clearly violates the go goal of consistent syntax.
Edit, incidentally the use of var is perfectly legal like this:
Either allow the use of var to declare a variable, or dont.
Dont mix and match in different contexts; this clearly violates the go goal of consistent syntax.
Edit, incidentally the use of var is perfectly legal like this:
package main
import "fmt"
func main() {
var a = 10
b := 10
fmt.Printf("%d %d\n", a, b);
for i := 0; i < 10; i++ {
fmt.Printf("%d Value\n", i)
}
}"Go has a way of programming. Go is totally optimized for that way of programming, in fact. Programming any way other than Go’s way, with Go, will be that recipe for frustration I bounced my skull against."
I think this is something a lot of people think when they first come to Go. Especially if you come from a higher lang like ruby or js or something since on other places on the net its kind of being marketed as a nodejs alternative. However, in my experience the "frustration" hasn't been there at all. I came from c and I think you get basically just a vamped up "better" (I know bad word) c. I love having multiple return vals and error handling in my returns and message passing and threading to any types is so easy in Go it just makes life nicer.
These are all my biased opinions as an avid Go user of course, but honestly I find the language extremely expressive and powerfull, and not really that it forces you to do something the Go way, other than the sense that yes you need to know the syntax and not have type errors etc, but this is the case with every language.
I think this is something a lot of people think when they first come to Go. Especially if you come from a higher lang like ruby or js or something since on other places on the net its kind of being marketed as a nodejs alternative. However, in my experience the "frustration" hasn't been there at all. I came from c and I think you get basically just a vamped up "better" (I know bad word) c. I love having multiple return vals and error handling in my returns and message passing and threading to any types is so easy in Go it just makes life nicer.
These are all my biased opinions as an avid Go user of course, but honestly I find the language extremely expressive and powerfull, and not really that it forces you to do something the Go way, other than the sense that yes you need to know the syntax and not have type errors etc, but this is the case with every language.
I quoted the same paragraph, and I'd be interested to know how much people think it applies to other languages.
Obviously there are languages using whole other paradigms that you would struggle immensely in, try writing Prolog like Java! But I wonder if the "Go mindset" is really any stronger than the "Ruby/erlang/lisp mindset" - or whether it's just the proximity of Go's appearance to C,C++,Java that causes new Go programmers to try to port incompatible idioms.
Obviously there are languages using whole other paradigms that you would struggle immensely in, try writing Prolog like Java! But I wonder if the "Go mindset" is really any stronger than the "Ruby/erlang/lisp mindset" - or whether it's just the proximity of Go's appearance to C,C++,Java that causes new Go programmers to try to port incompatible idioms.
Woo Woo Woo...Am I missing something or isn't PHP also a back-end language?
About the article, I think you are just doing it wrong. I personally never used Go, like I never used many other languages, but I tried many. Everyone has it's own way, just because one does things differently and not your way doesn't mean it's wrong. It means is different. You know...taste...
About the article, I think you are just doing it wrong. I personally never used Go, like I never used many other languages, but I tried many. Everyone has it's own way, just because one does things differently and not your way doesn't mean it's wrong. It means is different. You know...taste...
PHP is weak for long running back-end services.
True, but if you have to:
https://github.com/shaneharter/PHP-Daemon
https://github.com/shaneharter/PHP-Daemon
From your link.
"Note: For many reasons PHP is not an optimal language choice for creating servers or daemons. I created this library so if you must use PHP for these things, you can do it with ease and produce great results. But if you have the choice, Java, Python, Ruby, etc, are all better suited for this."
Possible but not recommended.
"Note: For many reasons PHP is not an optimal language choice for creating servers or daemons. I created this library so if you must use PHP for these things, you can do it with ease and produce great results. But if you have the choice, Java, Python, Ruby, etc, are all better suited for this."
Possible but not recommended.
Yeah, it's my project. It's OSS so I figured a shameless plug wouldn't hurt anybody.
Interesting - hadn't seen that before. My own attempts at brewing something together with PHP's posix and pcntl libs were feeble.
Thanks for the link.
Thanks for the link.
i'm running beanstalkd workers in PHP using supervisord. Seems to work for me, at least for now...
Yeah, same. You really do need supervisord to manage the process, though.
My background processes lean on supervisor's functionality quite a lot. Most of them don't run any longer than 5 mins or so.
My background processes lean on supervisor's functionality quite a lot. Most of them don't run any longer than 5 mins or so.
My setup is like iron.io, and supervisord manages all of the PHP daemons.
* video encoding and thumb-nailing
* image conversion
* content upload to ftp, s3, rs cloud, etc
* address geocoding
* email notifications
* web scraping
All in all, very pleased. The next part is to build a unified control panel to watch my processes and workers. For now I use the one built into supervisord.> Everyone has it's own way, just because one does things differently and not your way doesn't mean it's wrong.
Did you read the article? That was exactly his point.
Did you read the article? That was exactly his point.
I think the terminology is just getting lost because one man's backend is another man's application. Someone who is building user interfaces for a website might say PHP powers the backend, but someone writing that PHP application would say C (MySQL) is what really powers the backend.
In recent times we have been hearing a lot about Twitter and Facebook's backends, both of which make heavy use of JVM-based languages despite still using PHP and Ruby respectively in the main web-facing application. I believe the article is drawing from that context to separate what the backend means.
You can, of course, write your backend code in virtually any language, but PHP isn't particularly geared towards the task for a number of reasons.
In recent times we have been hearing a lot about Twitter and Facebook's backends, both of which make heavy use of JVM-based languages despite still using PHP and Ruby respectively in the main web-facing application. I believe the article is drawing from that context to separate what the backend means.
You can, of course, write your backend code in virtually any language, but PHP isn't particularly geared towards the task for a number of reasons.
The fact that its often intermingled in the frontend and php-cli is weak and almost an afterthought probably lead him to say that.
>Idiommatic Go is to have several lines of boilerplate after every single function invocation which can possibly fail.
This is an issue in every language. If you want to do something that might fail, you have to handle the possibility of failure. There are only two ways to handle this - return values and exceptions - and they differ in style more than in functionality.
So what is this guy suggesting? Does he want Go to have exceptions? Or does he want every function to magically succeed somehow? I don't enjoy writing error handling either but I see no way around it.
This is an issue in every language. If you want to do something that might fail, you have to handle the possibility of failure. There are only two ways to handle this - return values and exceptions - and they differ in style more than in functionality.
So what is this guy suggesting? Does he want Go to have exceptions? Or does he want every function to magically succeed somehow? I don't enjoy writing error handling either but I see no way around it.
> There are only two ways to handle this - return values and exceptions - and they differ in style more than in functionality.
"There are only two" is a bit strong. Off the top of my head I can think of conditions and restarts in e.g. Common Lisp (to be fair, these are a generalization of exceptions) and monads in e.g. Haskell. I'm sure there are others I'm forgetting.
"There are only two" is a bit strong. Off the top of my head I can think of conditions and restarts in e.g. Common Lisp (to be fair, these are a generalization of exceptions) and monads in e.g. Haskell. I'm sure there are others I'm forgetting.
I think he wants a non-boilerplate way of doing operation b only if operation a succeeds. Instead of writing:
Ultimately, it's a problem of not enough abstraction. Users of traditional programming languages are held hostage by the control-flow abstractions that the language designers put in place. But if they weren't, then they'd simply write the top code block and call it "combine_failing_operations" or something and they'd write their program in terms of combine_failing_operations:
In languages where function application is the only syntax, though, this pattern shows up all the time.
For example, in Haskell, you normally combine two functions with the . operator. (f . g) x = f(g(x)). It follows that if you want to combine two functions that can fail, you'll just write that function. Haskell does exactly this and even gives you some syntax sugar: if you call your function >>=, then you can write:
Semantically this is what Go does, but the syntax isn't as nice. (Exceptions are certainly irritating when applied to Go's concurrency model, but at least they are fail-safe. I don't trust myself to get every line of code 100% correct, and I want my program to crash when it gets into a state I didn't write code to handle. Go makes this harder than it should.)
result = operation_a()
if not result:
return ERROR
result = operation_b()
if not result:
return ERROR
return result
He wants to write: operation_a()
return operation_b()
This is a logical thing to want, because the program is not semantically correct if operation b executes after a failed operation a. It is correct, however, if a failing operation_a causes the entire routine to fail by bailing out early. So it would make sense that that be the simplest thing to write, and then make the case where you ignore errors from operation_a be the thing that's a lot of lines of code.Ultimately, it's a problem of not enough abstraction. Users of traditional programming languages are held hostage by the control-flow abstractions that the language designers put in place. But if they weren't, then they'd simply write the top code block and call it "combine_failing_operations" or something and they'd write their program in terms of combine_failing_operations:
combine_failing_operations(
operation_a,
operation_b)
Of course, combine_failing_operations is itself a failing operation, so one can also write: combine_failing_operations(
combine_failing_operations(
operation_a,
operation_b),
operation_c)
The reason why people don't is because the resulting code is ugly and it's not encouraged by the langauge's style guide (which usually says, "I'm the programming language designer, if there's missing functionality it's because the functionality is wrong").In languages where function application is the only syntax, though, this pattern shows up all the time.
For example, in Haskell, you normally combine two functions with the . operator. (f . g) x = f(g(x)). It follows that if you want to combine two functions that can fail, you'll just write that function. Haskell does exactly this and even gives you some syntax sugar: if you call your function >>=, then you can write:
do
operation_a
operation_b
instead of "combine_failing_operations operation_a operation_b", which means you get both pretty code and context-specific only-written-once correctness.Semantically this is what Go does, but the syntax isn't as nice. (Exceptions are certainly irritating when applied to Go's concurrency model, but at least they are fail-safe. I don't trust myself to get every line of code 100% correct, and I want my program to crash when it gets into a state I didn't write code to handle. Go makes this harder than it should.)
The error handling is the single thing that annoys me about Go. If you look at every hello world tutorial, the error return of println is ignored. In languages that use exceptions an error would not be ignored.
A happy medium for me in Go would be if you ignored the error then an implicit "return error" is added at that point. That way errors you handle locally get handled, and those not get passed to the caller. This is somewhat semantically similar to exceptions, but is a lot less code to write. And as a bonus all the hello worlds will have error handling.
(Yes I am aware there are some implementation details.)
A happy medium for me in Go would be if you ignored the error then an implicit "return error" is added at that point. That way errors you handle locally get handled, and those not get passed to the caller. This is somewhat semantically similar to exceptions, but is a lot less code to write. And as a bonus all the hello worlds will have error handling.
(Yes I am aware there are some implementation details.)
Thanks, that looks like a good way to handle errors. Go does have a panic() function for your situation. It takes an argument of any type. You can catch it with recover(), or the application crashes. It's like throwing an exception except you can't catch a specific type.
>PHP is horribly inconsistent, breaks all the rules about programming language design, and is infuriating.
Some say that rules are made to be broken. In the context of Go, Rob Pike argues exactly that in this short talk on why they made Go: http://www.youtube.com/watch?v=5kj5ApnhPAE
Some say that rules are made to be broken. In the context of Go, Rob Pike argues exactly that in this short talk on why they made Go: http://www.youtube.com/watch?v=5kj5ApnhPAE
Rarely do I get to read articles that are that low on substance, facts or concrete examples. What is a "Go's particular way" and how does it differ from the author's way? What are these 'particular' structures and behaviour? What is this "particular way", and again "particular way", of solving design issues? Is it like Fight Club?
>PHP is horribly inconsistent, breaks all the rules about programming language design, and is infuriating.
I stopped reading upon the first bold statement.
I stopped reading upon the first bold statement.
I didn't even click on the link, I knew I was going to find hollow statements like that one.
After reading the fantastic article from patio11 that was reposted today, I can't read this kind of ----.
After reading the fantastic article from patio11 that was reposted today, I can't read this kind of ----.
Thanks for taking the time to write this insightful comment.
You guys should go find some corner to sit in and be negative. Jeering with no actual feedback is tacky and makes you look childish.
You guys should go find some corner to sit in and be negative. Jeering with no actual feedback is tacky and makes you look childish.
And yet somehow you couldn't resist playing along...
I had had some hope that there would be some actual feedback and a discussion about why Go is bad or why PHP deserves lauding.
And you were expecting what with your reply?
And you were expecting what with your reply?
>PHP is horribly inconsistent, breaks all the rules about programming language design, and is infuriating.
Can't read, didn't try.
Can't read, didn't try.
I enjoyed the article but came away frustrated by one thing -- it offers specifics about the problems with Go, but only generalities regarding what is good about Go.
I haven't tried Go, but I'm aware of things that seem like short-comings to me (most especially, the lack of exceptions). So I understood the first part of the article.
The second part was vague ... I could tell that the author decided that all those problems were OK, but I don't really know how that happened. He chalked it up to the "way of Go". I'd really like to hear some concrete descriptions of what that is.
I haven't tried Go, but I'm aware of things that seem like short-comings to me (most especially, the lack of exceptions). So I understood the first part of the article.
The second part was vague ... I could tell that the author decided that all those problems were OK, but I don't really know how that happened. He chalked it up to the "way of Go". I'd really like to hear some concrete descriptions of what that is.
> [go] gets out of your way and make building [services] easy
> stop programming my way, and start programming Go’s way
These are inconsistent assertions fundamental to the point the article tries to make.
> stop programming my way, and start programming Go’s way
These are inconsistent assertions fundamental to the point the article tries to make.
PHP is for the backend too.
PHP doesn't support multi-threading -- or concurrency of any kind at all because it's not thread-safe.
No threading is accurate, and that makes it less ideal than many languages.
But it does provide thin wrappers over process forking and implementations/wrapper of libraries necessary for IPC (eg SysV queues, shared memory, semaphores, pipes and sockets).
But it does provide thin wrappers over process forking and implementations/wrapper of libraries necessary for IPC (eg SysV queues, shared memory, semaphores, pipes and sockets).
PHP is generally geared towards the application, not the backend. The backend is comprised of things like database servers, message queue systems, etc. It is, of course, not impossible to implement those services with PHP, but I don't think it is very common. Java, C, and C++ have been the traditional languages for that level with a few other more esoteric ones mixed in on occasion for certain tasks.
I've run a symbolic analysis on this article, it came out empty.
[deleted]
A good summary of programming in Go.
However I would like you to give some examples of inconsistencies in Go. And I believe that leaving features out ("anything a modern programming language is supposed to include") makes Go cleaner, safer and more understandable than any other language I know of (IMO).