Okay, so, my assumptions where more or less spot on, then :) It seems, you
are mostly aware of the complexities of your proposal. But let me go a
little deeper.

If you are able to use a custom implementation as a map[A]B, then any
*user* of map[A]B would need to know how to access the elements of that
map, so you'd need to also provide a way to do that (say, a method).
Similarly, for any other operation on maps (range, index-expressions,
delete). Similarly for slices (len, cap, append, copy, range, index
expressions, simple slices, full slices. Somehow the notion of capacity,
which is strongly coupled to the current implementation of slices, would
need to be included and made sense of) and channels (send, receive, both
with and without comma-ok, close, select - who knows how that last one
would look). You'd need to specify the signature/type of whatever
constructor is passed to make somehow, which is going to be kind of a
beast, given that it'll have to somehow include all of this. Next, slices,
maps and channels can be compared to nil. Currently, that's easy - they are
represented by structures with a well-defined size, so it just means
comparing a couple of words to nil. Would we need to overload that too?
Would we need to tag custom implementations with a size and how would the
zero value of such a thing look, before we even know what it's size is
going to be? Next up, users of those types would need to *find* all of
these custom implementations, so we'd need to add an additional tag to all
slices, maps and chans, similar to how interfaces work. And for the same
reasons that interfaces currently always indirect (so the GC knows what
memory locations contain pointers without needing to inspect additional
tags), that would need to work as an additional indirect, so we are
actually talking something pretty close to java-like boxed generics. How
would the signature of, say, an overloading of map[A]B actually look? Like,
say I want to have

type RBTreeMap struct {
    // whatevs
}

func (t *RBTreeMap) IndexExpr(?) ?

what would the types be of that method/function/whatever? If it's
interface{}, that throws all the advantages out the window that we'd expect
in the first place (compile-time checks and tight packing, i.e. losing the
indirection of interface). So, does this mean we need some way to declare
these methods generically? Not to mention the types itself - after all,
that RBTreeMap will have some kind of buckets and those buckets needs to
know what they're storing.

Overall, as simple as "adding a factory function to make" may sound - what
you are describing seems to have pretty much the exact implementation
complexity of full-blown generics and significantly *more* spec-complexity.
While only providing a limited subset of the functionality - if even that.
And that leaves aside the obvious follow-up question - if we are already
overriding ~70-80% of the operators and language constructs for this, why
are we not going all the way and also add operator overloading *in general*?

I don't think any of this is at all a good tradeoff.

(On a personal note, this would also be adding generics to exactly the part
where I *don't* want them. I am totally on board with having generics to be
able to implement something like Flume
<https://research.google.com/pubs/pub35650.html>/Cloud Dataflow
<https://cloud.google.com/dataflow/> in a type-safe way. Or Monarch counters
<https://medium.com/@sameer_74231/go-experience-report-for-generics-google-metrics-api-b019d597aaa4>.
Or Graph libraries. Or whatever high-level, domain specific abstraction one
might want to offer. But I don't want them all over my code in every.
single. datastructure. ever. used. But those are just my 2ยข)

On Tue, Aug 29, 2017 at 9:20 PM, RogerV <roger.dewa...@gmail.com> wrote:

> make() lets me specify a key and element type for a map collection but
> there's only one implementation of map. What about expanding on make() to
> where custom implementations of map can be specified instead? make() would
> accept a new argument that would let me indicate a factory mechanism to use
> to instantiate that map - but the types of the custom map would be those I
> specified in the call to make()
>
> IOW, this is a proposal for leveraging an enhanced make() function as a
> way to get the advantage of compile-time enforced types - as generics
> provide in other languages - at least for collections. Maybe sets and list
> could be added as something that make() can instantiate as well.
>
> Of course, it's not exactly that simple as the custom implementation would
> need to be able to operate on the actual type in an appropriate way for
> that type.
>
> Which means things like keys would need to implement traits for comparison
> and hashing, etc.
>

FWIW, this is the one thing that's less complicated than you are imagining.
The language already has these under the hood and uses them. There isn't
really a downside to specify, just like it is done now, that the compiler
will complain about constructing a map with types that are not comparable
if statically known and there will be a runtime-check with panic if not.
And the hash of a key can just be passed as an additional argument to
whatever methods are needed.

No traits needed.


>
> Or the dichotomy that Java has where generic type arguments can be
> references types but not primitive types - well, as long as the Go compiler
> always sees the full source code of the custom implemented collection, and
> things like a key type honored a trait that all keys should abide by, then
> that disctinction would need to be there in Go (perhaps).
>
> Am just blue saying thinking of augmentations that could be done to Go to
> get some of the benefit of generics without buying into full blown generics
> support.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to