Go 1.3 beta 1 released(tip.golang.org) |
Go 1.3 beta 1 released(tip.golang.org) |
http://tip.golang.org/pkg/sync/#Pool
There are a lot of cases where people write their own version of this (myself included, but also the connections in database/sql for example). It will be great to have an implementation in the standard library. This technique has been very, very useful in StatHat's production code as we have grown.
I understand your pain, but this is nowhere near a real issue for systems that Go is designed to help build.
I mean, in the thread that announces a new version of a language whose designers made it abundantly clear that it is intended to solve Google's problems, the top comment is about how to interpolate strings? I think they made a very good move by ignoring most syntax requests (There are a lot) and move on. Even better is their decision to harmonize formatting and build the formatter right into the language.
Syntax is extremely overrated, and evidence for it has been provided years ago. [1]
[1] http://c2.com/cgi/wiki?ProgrammingLanguagesAnInterpreterBase...
Edit: typos.
I spend most of my day designing and coding the sorts of systems which Go was designed to help build. I'll agree that this isn't a major issue, but it is affecting whether or not I actually enjoy using Go.
If you really want named variables in format strings you can make a template like "My name is {{.Name}} and surname is {{.Surname}}", and render the template with either a map of strings to strings, or a struct with the right named values.
"My name is #{name} and surname is #{surname}"
and this: "My name is " + name + " and surname is " + surname
or this: fmt.Println("My name is %s and surname is %s", name, surname)
Except the first one is much more readable.String interpolation seems like a small thing, but I find myself wanting to use it all the time. It's definitely not a "magic" feature. Javascript really needs it as well.
String interpolation is both practical and useful.
The intention of the programmer and the result is actually even more explicit than passing the values as arguments to some printf function.
As we slowly, oh so slowly, but surely move into languages where buffer overflows are not possible to write (or at least require scary excursions into some sort of "unsafe" package), easy string interpolations that allow the programmer to believe they don't have to think about the correct encoding of the value become the next most pressing security threat. Pretty much every "injection" is due to over-simplified string interpolation.
Unfortunately, if your string interpolation syntax is as easy is "This is an interpolated $string"... it's also wrong. Dead wrong, very wrong, run away screaming wrong wrong wrong! String interpolation is actually a very hard problem, and this must irreducibly manifest itself in the API. ImJasonH's example, while it isn't "string interpolation" in the Ruby/Perl/etc. sense, does involve using a template system with sensible escaping mechanisms... it's HTML-specific, though, but for HTML it's incredibly powerful and easy to use correctly. In fact Go's HTML templating is the most powerful and easy-to-use correct HTML templating system I've ever seen that isn't in Haskell. Presumably there are others out there, but I've seen a lot of the competition and most of them will sit by, twiddling their thumbs and whistling idly, while you put 100 injections of every kind into your HTML page.
My guess is Go will never grow this style of string interpolation, pretty much because it is so very, very frequently wrong. The way Go is already doing it is as easy as it can feasibly be, without encouraging wrongness.
Could I use it to allow developers to make plugins for a product in Go and C++ in a secure way, instead of using say Lua?
I'm open to suggestions.
s := make(map[string]struct{})
s["foo"] = struct{}{}
if _, ok := s["foo"]; ok {
// exists
}
There are varying amounts of fluff you can put on top of this, but that's the basic approach. Wrap it up in a type with methods if you're using it a lot in a program.Perhaps you also want built-in union, intersection, difference, etc. I personally find I need a set with simple membership testing about 10x as often as I need more advanced set operations, so from my perspective it's fine to leave those to third-party libraries.
If you are at GopherCon, I'll be giving a lightning talk on Saturday 11:40am on things I've learned by contributing to fsnotify and other open source projects. Happy to chat more about fsnotify afterwards.
We're still figuring out what os/fsnotify will look like.
https://github.com/pkulak/simpletransport
It sure would be nice to reuse connections without memory blowing up!
gccgo is also supposed to produce better code for certain computationally heavy workloads.
Unfortunately, this is very seldom true. Gccgo could potentially generate faster floating point code, but its lack of escape analysis grinds it to a halt.
http://dave.cheney.net/2013/11/19/benchmarking-go-1-2rc5-vs-...
https://groups.google.com/forum/#!topic/golang-dev/2YRmu_AWz...
If you have one version where you have a good grasp of how it compares to C++, that should provide an answer, right?
contains no language changesNot the best example to justify adding generics late.
I'm all of the day generics is finely added (and yes I missed it a lot when I was new to Go a couple years ago), but it is much less of a issue then some people make it out to be.
I personally prefer vim, and use the vim support delivered with Go plus gocode for code completion, that's really all I need for development. Unlike with Java, I never felt the need for an IDE with Go.
1. Quickly run/restart your application 2. Run specific unit test (all in package, all in file or specific one) 3. Parameter and func signatures are more detailed via CTRL+P (parameter info) than what you would get with GoSublime and GoCode.
There's only one thing so far I found a bit quirky:
Say you got a function with the signature func() (err error) and pass it as a parameter to another function that has the signature func F(f func() error), it will complain that the signatures don't match, but it will still compile.
http://dominik.honnef.co/posts/2013/03/writing_go_in_emacs/
http://dominik.honnef.co/posts/2013/08/writing_go_in_emacs__...
Not so much an IDE, dependent on your definition. More of a set of editor extensions, but useful so far.
Of course IDE availability should be low on the list of selection criteria for any language...
I work with SQL mostly, and in find common table expressions very useful to simplify and (in some cases) enhance performance. When faced with a choice between MySQL and PostgreSQL, I could either 1) choose to gripe about the lack of CTEs in MySQL, or 2) use PostgreSQL.
Something about generics make so many people on HN choose the equivalent of (1).
I don't know enough go to interpret what 'might be deallocated' means in this part of http://tip.golang.org/pkg/sync/#Pool:
"Any item stored in the Pool may be removed automatically at any time without notification. If the Pool holds the only reference when this happens, the item might be deallocated."
Is there some interface{} similar to C++ destructors, or is that a reference to the fact that the garbage collector need not deallocate unreachable objects?
type PoolObject interface {
Destroy()
}
And have it interact with that. The NewPool func would look like: func NewPool(func() PoolObject) Pool
EDIT: Changed my code a bitI wouldn't hold my breath, though.
It might be a little harder to read, but that's a lot different than explicit.
fmt.Sprintf("Hello %s!", username) is very explicitly using the username variable from the local scope, and nothing but the username variable can ever get included in the output string. At most, a user could put a %s in their string, and get the username to appear somewhere else in the output... but they wouldn't be revealing data that wasn't already intended to be printed out.
In comparison, interpolation is opening a door to let anyone extract whatever variables happen to be in scope at the time by putting #{password} or #{secret_key} in their string. By moving the definition of what variables get printed out into the data, you're opening a really big hole in your code... it also makes it a lot harder for the compiler to check for correctness.
A language like Ruby will only perform interpolation on string literals, so there isn't a way (that I know of) for data to inject interpolated strings.
Interpolation isn't the same thing as eval.
It's the kind of feature that is useful when you write an application but not that useful when you're trying to debug it.
If you're genuinely confused by it's behaviour then I'd suggest steering clear of the Printf (and even the vanilla Print/Println functions which does concatenation and automatic type conversion).
Or perhaps, a better suggestion would be to read the language specs and learn interpolation's behaviour since this "magic" is almost always well documented [hint: it's actually less complicated than Printf ;)]
It's largely used in log messages and the like where it's used for debugging issues after the fact. I've yet to encounter a case where anyone was ever confused by the behaviour.
Question to answer then is: Where does the plumbing stop and the kitchen begin?
Nothing complex about generics that the average modern day programmer can't grasp. We're not talking about some '00s enterprise drones that were never exposed to those concepts.
People used to talk like this about closures in Java too -- "too complex, who needs them", etc. Didn't turn out very well for the language's mindshare about the new generation of programmers...
C# has had generics since 2.0, so ALL is a bad choice of words there.
One of many posts about generics history in .NET:
http://blogs.msdn.com/b/dsyme/archive/2011/03/15/net-c-gener...
Honestly, in the medal positions for sloppily expressed programming sentiments, complex/simple occupy the bronze/silver positions just behind the ultimate... "elegant".
I say they come from building APIs that don't require a statement of the correct way to escape output. Of course if your API doesn't require it, it doesn't happen.
Even the way you phrase it is dangerously wrong... validation of input and escaping of output are two entirely different things. I've implied this in my phrasing but let me spell it out, validation happens on the way in and is related to your local semantic domain (business rules, legal values of "an IP address" or "an email", etc), and escaping happens on the way out and is performed by the string "interpolation" or template system. If you've got them munged in your head into one concept, you're probably not writing correct code.
(For what it's worth, I see this formulation of the "root problem" more often than I see the right one. I really ought to write this up as a blog post.)
I'm looking out on the world and seeing what is there, which is a steaming mass of code that incorrectly manages strings. The fact that it is theoretically possible to correctly manage them is not that interesting of a fact, because observationally, it doesn't happen.
Yes, they are, but preventing injection attacks is the domain of the former more than the latter, and your suggestion that it is the other way is dangerously wrong. There are security risks addressed by the latter, but if you are relying on it to prevent injection attacks in the usual case [1], it means you are allowing untrusted unvalidated external data into your system and doing general processing on it and just trying to avoid a problem on output.
You prevent injection attacks by preventing malformed data from being injected into the system (at least, from such data making it past a validation component), not by allowing it freely into the system and trying to mitigate certain of its harms by escaping output.
Its true that proper escaping may help to limit injection attacks where imperfect validation has failed to prevent bad data from being accepted and processed, but even there more complicated APIs for string building don't make it more likely that people will do it right.
[1] the one place where it may be a proper mechanism for addressing injection attacks is when you are reporting the rejection of malformed input data, in which case you may have a legitimate need to use (some part of) the malformed data in the error report.
So programmers _will_ use Sprintf, because it's one of the first things they'll have been taught, and Sprintf doesn't make dealing with encoding any easier or explicit than string interpolation.
Having string interpolation doesn't mean people can't or won't use domain specific templating languages, and not having it won't make it any more likely that they will.
Shame :(
"abc #{x} def" would desugar to "abc"+x+"def"
Because it's happening at the compilation stage, it can only be done on string literals (which as we've seen is actually an advantage security wise).
The reality is actually a tad more complicated, because you can make efficiency improvements and only create one string instead of all the intermediate strings etc. but the effect is the same.
i += 1 means an extra line, but that extra line is very clear.
Ternary vs an if-else arguably loses on clarity except for the simplest of cases.
"Today's date is #{date}. Your balance on account #{account.Number} is #{account.Balance}"
"Today's date is " + date + " Your balance on account " + account.Number + " is " + account.Balance
The second is a mess of +'s and "'s to me, not to mention the awkwardness of formatting spaces before and after each quote. The first, you write a sentence and plug in the variables where they belong.
Not saying you're wrong, just what I would choose.
I disagree, especially in the presence of syntax highlighting editors.
String interpolation would be a redundant alternative to existing mechanisms (the above plus text/template for longer strings) and just make parsing more complex. I don't think it would fit in well with Go's philosophy of providing pleasant, minimalistic syntax.
It works really well in its current form, that is probably the general consensous.
> additional features are a source of evil
Some of us have walked down that path before (e.g. Perl, Scala) and think we have seen the light (or at least the darkness).
> up until the day when they are added, in which case they are suddenly evidence of the language's superiority
That sounded very much like flamebait. Could you name an example of a feature added to Go that was previously considered evil and then as evidence of Go's superiority?
Every syntax highlighter in an editor I've seen for Ruby handle highlighting string interpolation just fine.
I definitely don't have a problem with the Go developers keeping out random syntax additions unless they think its a really good idea.
Along the same lines, I really miss not having `map`, `reduce`, and `filter` in Go. However, it doesn't seem like those would be efficient in Go, or that they fit in with as well with systems programming, which Go was designed for. So I can't hate them for not including these.
map, reduce, filter, etc will be easy to code up once there are generics. There will almost certainly be generics in Go at some point, that point is just not right now (and almost certainly not before 2.0).
What is the Go best practise for i18n? A google search seems to provide various solutions but not one best practise.
> the third has ordering issues
In Go you can specify the order in format strings: fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
I do this unfortunately way more than I want to admit...
This only leaves us console programs and backdoors. I'm happy to give these two up for a stronger language.
I don't think such a micro-optimisation is enough to sway the argument though.
Then a representative from Microsoft started attending a couple of the biggest Java SIGs, and he would ask us how we would change Java if we could. We were happy to answer. A few of the suggestions were broadly desired by the groups.
He took lots of notes, and a year or so later C# was announced. It included several of those features. My impression is that most of us considered it a better Java, as a language design. (The Achilles Heel of its relationship to Microsoft was a huge, but separate, issue from the design of the language itself.)
The Java Team suddenly had a whole new attitude about their fossilized masterpiece, and features we had been told for years were bad ideas were touted as evidence of Java's ongoing spirit of innovation with each new version of Java.
>> additional features are a source of evil
> Some of us have walked down that path before (e.g. Perl, Scala) and think we have seen the light (or at least the darkness).
We've walked down that path and have been very happy and productive with Scala. Each to his own I guess.