On Fri, Jan 12, 2018 at 11:23 PM, Peter Mogensen <a...@one.com> wrote:

>
>
> On 2018-01-12 22:22, Axel Wagner wrote:
> > Yes, you can *test* if the dynamic value has a specific type (and
> > extract it if so). That is not the same as operating on the dynamic
> > value (e.g. by dereferencing it) *without* knowing its type.
>
> I know I can test the type. But the issue was specifically to
> dereference the first pointer while keeping the actual object.
>
> > Go does not have parametrically polymorphic types - and even if it had,
> > there wouldn't be any sensible type you could assume here, given that
> > it's only known at runtime. There simply is no type that the extracted
> > value could have. Like, what would the type of t be in your example, in
> > the **<Something> case?
>
> It seems we are constantly talking pass each other. There was two
> questions here
> 1) Can it be done in Go as the Go spec is now?
> 2) Is it in general an ambigious task?
>
> So let's assume we already have answered 1) with "no". (I guess)
> It seems you are trying to argue that the answer to 2) is "YES", but
> doing it with reference to current Go spec.
>

But the answer to 2 is "no, not in a type-safe way". It necessarily
requires reflection. Even if we'd assume we somehow magically know that the
dynamical value of the interface is some pointer type. That doesn't
actually help us, in any reasonable way. We can dereference it, but we
wouldn't know what the thing it's pointing to is. Or to put it another way:
To dereference a pointer, you'd have to know - at the very least - the size
of the thing it's pointing to. And to do it in a type-safe way, you'd have
to know the *type* of the thing it's pointing to.

Yes, in theory, the compiler an inspect the type-info of the interface, see
that it's a pointer-type and then construct a new interface-value, with
dynamic type "type of the pointee" and dynamic value "pointee" - that's
reflection. I.e. the compiler would emit code for the equivalent of
v := reflect.ValueOf(v).Elem().Interface()
That is the best you can do, but in particular, you don't have any static
information about what the value is you are operating on, so you can't call
any methods on it, you can't dereference it, you can't do… anything with
it, really. Like, you can't actually do any better than what reflection
gives you - and reflection already works.

That's why I say that, if you know the type, use that knowledge to get
static assertions on it. If you don't use reflection. And that is
fundamentally all you can do in a statically typed language.

Your request is essentially equivalent to reflection as a language-feature,
which is essentially equivalent to making Go a dynamically typed language.

I'm perfectly aware that in a case in a type switch like this
>
> switch t := i.(type) {
> }
>
> ... t needs to have a type in each case clause, and the only type it can
> have in lack of a specific type mentioned, is interface{}
>
> But still ... that's an argument for 1) - not for 2)
>
> > Yes, it is in general ambiguous what is meant.
>
> No, I don't think so.
>
> There nothing ambigious about generic operation of turning **T into *T.
> The only reason it cannot be done here is because the deference operator
> needs to operate on a concrete type and we have an interface{}.
>
> It might not be meaningful to define an actual generic function
> mechanism for this, since for the compiler to check the types there is
> not much more than the dereferencing which can be done
> But it is possible to state this in C++:
>
> template<class T>
> T *f(T **p) {
>     return *p;
> }
>

This is not the same. In the case of this C++ code, the actual type of T is
statically known. In your Go case of getting passed an interface{}, you
have no static information about the type (or rather: You have the
information that it's an interface{} value). This is what I meant when I
said, parametric polymorphism alone wouldn't even help you a priori; unless
it's instantiated at runtime (say, like in Python).

I don't know enough C++ to talk about this competently, but a quick
googling suggests the rough equivalent to Go's interfaces in C++ (in terms
of implementation) are polymorphic objects: Objects that keep dynamic type
info around. And I assume, if you'd actually try to do it using that, you'd
run into similar problems and would end up having to use typeid() - which
is the equivalent to reflection. But yes, as I said, I can't talk
competently about C++.

-- 
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