How about writing
import "foo"
f := foo.Foo{foo.INIT}
And if most Foos are INIT,
f := foo.Make()
(Yes, I realise some of those choices work for Java too.)
Chris
--
Chris "allusive" Dollin
Is this "stuttering"? Maybe you picked a bad example, or maybe we just
see things different, but I think os.Error, io.Reader and bytes.Buffer
are very appropriate names. I don't feel any need to short them,
removing the package name removes valuable information.
--
- yiyus || JGL . 4l77.com
> How about writing
>
> import "foo"
>
> f := foo.Foo{foo.INIT}
>
> And if most Foos are INIT,
>
> f := foo.Make()
Or ensure that foo.INIT is zero.
"Namespaces are one honking great idea -- let's do more of those!"
- import this
It's generally a good idea to actually use the package name as part of
the name of something.
foo.FOO_INIT is kind of silly, and would be better to be just foo.INIT
foo.Foo could be obtained with foo.Make() or foo.New() etc.
hiding the namespaces seems like a great idea now, saving you a few
characters. But you'll cry later as your program gets bigger and
things start to clash.
Hiding well known types behind your own types makes reading your code
that much harder.
People will curse.
- jessta
--
=====================
http://jessta.id.au
jessta, I think you're missing the point of your own Python reference.
Yes, namespaces are great, but even Python found it important to allow:
from other.namespace import Foo
Which is exactly what I'm asking for.
Oh, and as for the sanctity of naming, it's already the case that if I want to import "foo/x" and "bar/x", I have to rename to avoid x clashes.
I don't see this as any different.
On 6 Dec 2010 14:04, "Jessta" <jes...@jessta.id.au> wrote:
Which x was this?
Chris
--
Chris "curious" Dollin
I'll concede that the first "bytes.Buffer" I see is somewhat useful, but after I know which Buffer we're using, I'd really prefer to abbreviate this to just Buffer, or pick my own name, like:
import BBuffer "bytes.Buffer"
The inability to do this seems to have already led to some questionable naming choices in the Go packages. For example, if it was possible to do this:
import ( Bench "testing.Benchmark")
Then I bet nobody would have let the testing package get away with a type called B. (I'm not alone in my distaste for "testing.B", am I?)
BTW, I'll repeat my request: is there anything like my interface trick...
type MyName interface { otherpkg.Name }
...that works for structs/consts/vars?
I stand corrected: the Python equivalent of what I asked for is:
from other.namespace import TheirName as MyName
I think the point is still roughly the same: is it that unreasonable to want to bring frequently used names into my namespace, on my terms, to avoid "testing.B"?
On 6 Dec 2010 14:31, "Mickey Killianey" <mic...@killianey.com> wrote:jessta, I think you're missing the point of your own Python reference.
Yes, namespaces are great, but even Python found it important to allow:
from other.namespace import Foo
Which is exactly what I'm asking for.
>
> On 6 Dec 2010 14:04, "Jessta" <jes...@jessta.id.au> wrote:
>
> On Tue, Dec 7, 2010 at 12:36 AM,...
In Java, as far as I remember, only Static declarations can be
imported. And I don't se the reason why Math.PI is worse than PI.
In go you don't need to rename you packages (you can, but this is
required only when two packages have the same name).
Different from python which you need to reference the entire
namespace, in go only the last package name goes public, if two
packages have the same name create an alias for one of them.
In Go, you can reference everything with a <namespace>.<thing> this is
very nice. In java for instance, if you have two classes one of then
you import and reference using only the classname and the other you
need to write the entire namespace.
import br.com.foo.Bar
bar = new br.com.foo2.Bar(); // this is not practical.
--
André Moraes
http://andredevchannel.blogspot.com/
So what's your reaction to testing.B?
On 6 Dec 2010 14:54, "Matt Joiner" <anac...@gmail.com> wrote:
I think the stuttering indicates the module system is being used incorrectly. If you're exporting Foo from foo, you should probably be treating the module as the object, this leaves you with:foo := foo.New(foo.INIT)Then you want to use the zero-values as your init, or the fact that New is now a function:foo := foo.New()And then if you're calling your Foo, foo, it implies you probably only have one of them:foo.GlobalOr that you may have more than one, and need to refine your name:bar := foo.New()While I find the python import syntax handy, I think there's real value in aggregating type names and using the module they're found in. There's nothing worse than reading someone else's code and seeing BBuffer and having to dig that type up to find it's a typedef, or an from X import Y as Z. Seeing math.PI will never lead to confusion (and if it does the author of the code needs a stern talking to), but PI could be anything.
The reverse situation is what happens in C++, where its impossible to get anything done without typedefs and namespace assigns due to the ridiculously long signatures floating about. Just look at any Boost library. I look forward to seeing code with such names as gtk.Window, http.Get, fuse.Operations, and knowing exactly what is meant without having to check imports, headers and typedefs.
On Tue, Dec 7, 2010 at 1:35 AM, Mickey Killianey <mic...@killianey.com> wrote:
>
> Oh, and as for ...
Jessta's point was that reducing io.Reader to Reader would be an affront, because io.Reader is, somehow, its "true" name.
My point is that there will always be collisions in package names. I'll discover that I'll need to use "github.com/apache/ioutil" and "io/ioutil" in the same file, and only one could get to be the "ioutil" namespace. But that's too crude...I'd really rather do:
import (
ReadNormalFile "io/ioutil.ReadFile"
ReadGzippedFile "my/ioutil.ReadGzipFile"
)
So that it isn't a choice of which package I want...it's a choice of what symbols I want.
On 6 Dec 2010 14:40, "chris dollin" <ehog....@googlemail.com> wrote:
On 6 December 2010 14:35, Mickey Killianey <mic...@killianey.com> wrote:
> Oh, and as for the sancti...
Well, opinions clearly differ; it's a nice straightforward locally-controlled
mechanism useful in infrequent situations.
I think that the Go package naming technique is a really good
95% solution for namespacing and I'm not really worried about the
5% left over.
(I happen to have devised a very similar solution for a programming
language I was co-designing more than ten years ago, so I'm biased.)
Chris
--
Chris "numbers made up on demand" Dollin
And create variables to point to things:
const myconst = otherpkg.ConstName
var printf = fmt.Printf
One of the big laugh lines in early Go presentations was this one:
foo.Foo *foo = new foo.Foo(foo.FOO_INIT)
and yet I'm finding out that my Go code is suffering from exactly this
problem...it seems to have merely shuffled around the foos:
import foo "foo"
foo := foo.Foo{foo.FOO_INIT}
My opinion is that testing.B is just one example of a category of poor naming choices encouraged by the namespace syntax (and I'm still convinced that anyone who doesn't find the name testing.B at least a *little* wrong should get themselves tested for toxic levels of Go Kool-Aid).
If there would have been a groundswell of support for this, I would have suggested "hey, isn't this a great opportunity to work on a deprecation mechanism for Go, and give it a test run by renaming testing.T and B to...well...just about *anything* else?"
However, I'm willing to concede that my viewpoint seems to be in the minority, so rather than rail against the language, I'll return to my original question: is there a way to achieve this today *within* Go's syntax?
With interfaces, I think I'm content with:
type Foo interface { foo.Foo }
As in:
type DAG interface { graphs.ArrayBackedDirectedAcyclicGraph }
Not only is this easier for me to type and read, but if I want to switch to graphs.NodeBasedDirectedAcyclicGraph during development, I can make that change with a minimum of fuss...switch the type declaration and fix whatever doesn't compile.
But with consts and vars, I'm at a loss...I think the best I can do is use a reference:
var SWAVLN = &foo.SomethingWithAVeryLongName
And dereference it at runtime, which is mostly fine.
And with structs...I think the best I can manage is:
type FooRef *foo.FooStructWithPrivateFields
Which means that I can't accept or return by value.
Anyone got better suggestions for the non-interface cases?
On 6 Dec 2010 15:12, "Matt Joiner" <anac...@gmail.com> wrote:
I should add that testing.B would be more familiar than import BenchmarkRunInstance as MyPreferredName, where MyPreferredName differs by author's taste, and time of year.
On Tue, Dec 7, 2010 at 2:08 AM, Matt Joiner <anac...@gmail.com> wrote:
>
> It looks to me like t...
Thanks for the reminder about func s...good point.
As for const FOO = other.FOO, does that always work, or could it end up that FOO points to a separate copy of other.FOO, so that:
FOO == other.FOO
But
&FOO != &other.FOO
Is there a runtime guarantee one way or the other?
Again, thanks for the thoughtful response, both you and everyone else...this group has been really helpful as I've gotten started in Go!
On 6 Dec 2010 15:35, "Jessta" <jes...@jessta.id.au> wrote:
On Tue, Dec 7, 2010 at 1:28 AM, Mickey Killianey <mic...@killianey.com> wrote:
> BTW, I'll repeat my...
Think about other people please.
import (
MegaThing "bytes.Buffer"
)
I don't want to see a code like this. In the Go language you can rename
package names, that is ok, but you can't rename other things. It is
amazing.
And your FOOish example is really bad. Rob Pike's example as far as I
understand was partly a joke. But you know, all jokes are 50% truth.
There is a problem with verbosity in Java, it's not just about
initializing things and there is no such problem in Go. I think you've
been coding too much Java lately.
consts in Go are rather limited; numbers or strings.
(And you can't take their addresses either.)
So no separate copies ...
It's been said in some form already, but this is a terrible example.
Go packages aren't structured or used in this way. (And, a minor
point, you don't need to specify the name 'foo' in your import line.
The package should do that itself.)
When authoring a go package it is the convention to consider your
exported names will be prefixed by the package name. When I wrote the
archive/zip package, I named the type that reads from zip files
Reader, not ZipReader. That's because the package is imported as
'zip', and so the type appears to its clients as zip.Reader. I don't
see any stuttering here.
I find your particular criticism surprising, as IMO Go's approach to
imports is one of the sanest I've seen in any language. I guess I'm
biased, though.
This type of python import line
from other.namespace import Foo
is A Bad Idea and has, in my experience, led to some truly unreadable code.
With that said, you can achieve the same effect in Go (with functions
or variables) like so:
import "package"
var Foo = package.Foo
To address your point of conflicting package names: In all the go code
I've written to date I've never once had to rename an import unless I
was doing something really weird. Doing weird things _should_ feel
weird; we shouldn't tailor the language to odd edge-cases.
Andrew
On 7 December 2010 00:36, Mick Killianey <mickey.k...@gmail.com> wrote:It's been said in some form already, but this is a terrible example.
> import foo "foo"
> foo := foo.Foo{foo.FOO_INIT}
Go packages aren't structured or used in this way.
When authoring a go package it is the convention to consider your
exported names will be prefixed by the package name. When I wrote...
Other people have said it in the beginning of the thread, but it bears
repeating, you almost never see a ring.Ring or a list.List, you
usually do:
r := ring.New() or l := list.New()
Vectors are a slightly different case because you genuinely need them
because of the different vector types, vector.IntVector etc...
Have you looked through any of the go programs in $GOROOT/src/cmd like
goinstall, gofmt or godoc? I think they would go a long way towards
making you feel better about the verbosity of the language.
Noah
No, Vectors are different because you should not be using Vectors, you
should be using slices.
uriel
Rob's example was intentionally terrible, but it came from *real*
code, substituting Foo for whatever the original library was. IIRC it
was C++, but it might have been Java. The terribleness was an
unintentional byproduct of the C++ naming style.
You've recreated the terribleness in Go code, but as many people have
already noted, real Go code should not look like that.
Yes, the foo package in this example is awkward to use...Rob wrote it that way intentionally, and yes, I translated the awkwardness intentionally. But those of you who continue to criticize the package...you're missing the point.
Just as it is possible to write *elegant* libraries in Go (as in Java or C++ or Python or whatever Rob's example is), it is also possible to write *awkward* APIs in Go (as in any of those other languages). There's nothing magical about Go that disallows mediocre code.
Not all programmers write elegant code all of the time, and there will be times when you find yourself needing to use a mediocre Go library, because, for better or worse, it works. Complaining that "real Go code doesn't look like this" is counterfactual idealism.
This thread merely asks what one can constructively do to make life better when you're stuck as the *user* of a package with a clunky API.
Other languages have explicit mechanisms that you can use to rename on import to improve local readability. Yes, it's possible to abuse those mechanisms. But calling them evil (as some did on this thread) is being a bit overdramatic.
Go only has one explicit mechanism (the import declaration), but this thread discussed several *implicit* mechanisms that fall out of the language spec. These tricks are worth knowing, not because you expect to do it often, but because on the unusual occasion that merits it, it's a handy tool to have.
On 12 Dec 2010 01:10, "Nigel Tao" <nigel.t...@gmail.com> wrote:
On 10/12/2010, Mickey Killianey <mickey.k...@gmail.com> wrote:
> On 6 December 2010 23:49, Andr...
Uriel,
The underlying types for the vector package types are slices.
On Dec 11, 6:14 am, Uriel <ur...@berlinblue.org> wrote:
> Vectors are different because you should not be using Vectors, you
> should be using slices.
Peter
Okay. I would suggest you write a wrapper library that makes the
clunky API cleaner. Or, better still, fix the clunky API and push the
changes upstream.
Making bad code easier to use does little more than encourage
people to write bad code. Let's not complicate the language for that
purpose.
> Other languages have explicit mechanisms that you can use to rename on
> import to improve local readability. Yes, it's possible to abuse those
> mechanisms. But calling them evil (as some did on this thread) is being a
> bit overdramatic.
Perhaps not "evil", but definitely not in the spirit of the Go language.
Andrew