What about memory layout means that []T cannot be converted to []interface in Go? - interface

So I've been reading these two articles and this answer
Cannot convert []string to []interface {} says that the memory layout needs to be changed.
http://jordanorelli.com/post/32665860244/how-to-use-interfaces-in-go says that understanding the underlying memory makes answering this question easy, and
http://research.swtch.com/interfaces, explains what is going on under the hood.
But for the life of me I can't think of a reason, in terms of the implementation of interfaces as to why []T cannot be cast to []interface.
So Why?

The article "InterfaceSlice" try to detail:
A variable with type []interface{} is not an interface! It is a slice whose element type happens to be interface{}. But even given this, one might say that the meaning is clear.
Well, is it? A variable with type []interface{} has a specific memory layout, known at compile time.
Each interface{} takes up two words (one word for the type of what is contained, the other word for either the contained data or a pointer to it). As a consequence, a slice with length N and with type []interface{} is backed by a chunk of data that is N*2 words long.
See also "what is the meaning of interface{} in golang?"
This is different than the chunk of data backing a slice with type []MyType and the same length. Its chunk of data will be N*sizeof(MyType) words long.
The result is that you cannot quickly assign something of type []MyType to something of type []interface{}; the data behind them just look different.
"why []string can not be converted to []interface{} in Go" adds a good illustration:
// imagine this is possible
var sliceOfInterface = []interface{}(sliceOfStrings)
// since it's array of interface{} now - we can do anything
// let's put integer into the first position
sliceOfInterface[0] = 1
// sliceOfStrings still points to the same array, and now "one" is replaced by 1
fmt.Println(strings.ToUpper(sliceOfStrings[0])) // BANG!

Read the blog article The Laws of Reflection, section The representation of an interface.
A variable of interface type stores a pair: the concrete value assigned to the variable, and that value's type descriptor. To be more precise, the value is the underlying concrete data item that implements the interface and the type describes the full type of that item.
So if you have a value of []T (a slice of T) where T is not an interface, the elements of such a slice only stores values of type T, but it does not store the type information, it belongs to the slice type.
If you have a value of type []inteface{}, the elements of such a slice holds the concrete values and the type descriptors of those values.
So elements in a []interface{} require more info (more memory) than in a non-interface []T. And if the occupied memory of those 2 slices are not the same, they cannot be just "looked at" differently (looked at as a differnet type). Producing one from the other requires additional work.

Related

How to define `last` iterator without collecting/allocating?

Using the example from the Julia Docs, we can define an iterator like the following:
struct Squares
count::Int
end
Base.iterate(S::Squares, state=1) = state > S.count ? nothing : (state*state, state+1)
Base.eltype(::Type{Squares}) = Int # Note that this is defined for the type
Base.length(S::Squares) = S.count
But even though there's a length defined, asking for last(Squares(5)) results in an error:
julia> last(Squares(5))
ERROR: MethodError: no method matching lastindex(::Squares)
Since length is defined, is there a way to iterate through and return the last value without doing an allocating collect? If so, would it be bad to extend the Base.last method for my type?
As you can read in the docstring of last:
Get the last element of an ordered collection, if it can be computed in O(1) time. This is accomplished by calling lastindex to get the last index.
The crucial part is O(1) computation time. In your example the cost of computing last element is O(count) (of course if we want to use the definition of the iterator as in general it would be possible compute it in O(1) time).
The idea is to avoid defining last for collections for which it is expensive to compute it. For this reason the default definition of last is:
last(a) = a[end]
which requires not only lastindex but also getindex defined for the passed value (as the assumption is that if someone defines lastindex and getindex for some type then these operations can be performed fast).
If you look at Interfaces section of the Julia manual you will notice that the iteration interface (something that your example implements) is less demanding than indexing interface (something that is defined for your example in the next section of the manual). Usually the distinction is made that indexing interface is only added for collections that can be indexed efficiently.
If you still want last to work on your type you can either:
add a definition to Base.last specifically - there is nothing wrong with doing this;
add a definition of getindex, firstindex, and lastindex to make the collection indexable (and then the default definition of last would work) - this is the approach presented in the Julia manual

Swift Disadvantages Array of Any

If I store a Tuple
var person = ("Steve", 22)
I cannot add more data easily into the structure.
However, if I use an array of Any
let steve: [Any] = ["Steve", 22]
I can easily add the elements.
Surely there are no real advantages to using a Tuple and we just always use an array of Any?
Any is weakly typed so you lose all of the static type checking guarantees that you get with strong types, including tuples. In addition, you cannot index out of bounds at run time on a tuple like you can with an array since the compiler knows how many components there are and it will fail to compile, and since a tuple is basically an anonymous struct, you can also name the components to make them more meaningful, which you cannot do with an array. You also pay a performance penalty for the array of Any since your data has to be boxed in the Any where as a tuple is just a struct and its components are not boxed.

How to get the value from the byte array object using ICorProfilerInfo2

I'm using ICorProfilerCallback2 interface to profiler my application. On function enter hook I'm trying to read the value from byte array which is passed as an argument to a function. I've the argument info COR_PRF_FUNCTION_ARGUMENT_INFO from which I can get the starting address of the byte array argument.
If it is a string argument I can use "GetStringLayout" method from ICorProfilerInfo2 interface to get the bufferoffset and stringlengthoffset.
How can I find the offsets for byte array and how to read the values from it?
Where can I find the documents for those?
If you have the ObjectID (or COR_PRF_FUNCTION_ARGUMENT_RANGE) of the argument, you have an easy life (at least for Objects/Arrays, not for Value Types. You have to validate the parameter type using the metadata).
You can use ICorProfilerInfo::GetClassFromObject and ICorProfilerInfo::IsArrayClass to determine if it's an array. If so, IsArrayClass gives you the type of array. Arrays in .Net have a specific layout (I don't think it's in the official docs): It's always 8 bytes for ClassID, 8 bytes for size, and than all the elements, without padding (Note: Objects are stored by ObjectID, just like in other memory regions).
You can also use ICorProfilerInfo2::GetArrayObjectInfo to get the size (need to calculate from dimensions) and the starting address of the objects.
Relevant reads:
https://mattwarren.org/2017/05/08/Arrays-and-the-CLR-a-Very-Special-Relationship/
https://windowsdebugging.wordpress.com/2012/04/24/memorylayoutofarraysx64/

What does bindMemory(to:capacity:) actually do? [duplicate]

Can anyone explain what is difference between UnsafeRawPointer.assumimgMemoryBound(to:) and UnsafeRawPointer.bindMemory(to:capacity:)?
A practical example of compile or run time difference would be more then welcome.
Swift Doc says about bindMemory(to:capacity:):
This API allows a region of memory to hold unrelated types at different points in the program. Binding uninitialized memory to a type prepares the memory to store values of that type. Binding memory that is already initialized reinterprets the in-memory values as the new type. If the old values are either nontrivial (require destruction) or if they are ever read from memory before being overwritten, then the new type must be mutually layout compatible with the old type.
What does it mean Binding uninitialized memory to a type prepares the memory to store values of that type? It's allocated bytes, right? So what's different after bindMemory(to:capacity:) completes?
Allocated memory in Swift can either be:
Uninitialised raw memory
Uninitialised memory that's bound to a type
Initialised memory bound to a type
When you allocate memory with UnsafeMutableRawPointer.allocate(bytes:alignedTo:), you get uninitialised raw memory.
When you allocate memory with UnsafeMutablePointer<T>.allocate(capacity:), you get uninitialised memory that's bound to the type T.
bindMemory(to:capacity:) (re-)binds a pointer's memory to a new type, and gives you back a typed pointer to access it with. It can be called on a pointer to memory in any of the above states; though if the memory is initialised, the new bound type must be layout compatible with the old bound type, and both types should be trivial.
Note that this method doesn't perform allocation or initialisation; it merely changes the bound type of the memory.
assumingMemoryBound(to:) is a method for getting a typed pointer from a raw pointer that you already know points to memory bound to a given type. If the memory is not bound to this type, accessing memory through the typed pointer you get back is undefined behaviour.
One important thing to note here is that memory can only be bound to one type at a given time. You are free to rebind to other types (with the above restriction for initialised memory); however attempting to access memory bound to a given type as an unrelated type violates strict aliasing and is therefore undefined behaviour.
Another thing to note is that related types and layout compatible types are independent concepts:
The type T is layout compatible with the type U if memory bound to type U can be bitwise reinterpreted as having type T. Note that this isn't necessarily a bidirectional relationship. For example, Int is layout compatible with (Int, Int) if one 'instance' of (Int, Int) can be reinterpreted as being 2 x Int. The reverse can't be true though; you can't form an (Int, Int) value from a single Int.
Two types are related if you can alias overlapping memory with those types. For example, if you have an UnsafePointer<T> and an UnsafePointer<U>, if T and U are unrelated types, then they cannot point to memory that overlaps with each other.
However, I don't believe Swift has officially defined any rules for these terms yet (I expect this'll come with ABI stability).
So what's different after bindMemory(to:capacity:) completes?
Currently, nothing. As Andrew Trick says in the mailing list discussion that Martin linked to:
Binding memory communicates to the compiler that the memory locations are safe for typed access. Nothing happens at runtime--until someone writes a type safety sanitizer. It affects the abstract state of the memory location, independent of the pointer variable used to access that memory. Binding memory returns a typed pointer for convenience and clarity, but there’s nothing special about that particular pointer value.
For further reading on this subject, see the memory model explanation section of SE-0107, as well as this unofficial guide to strict aliasing in Swift.

How to define a variable length type in postgresql

I try to declare a variable length type which contains a numeric array,
the type looks like
typedef struct MyType {
double count;
double[] lower;
double[] upper;
} MyType;
I find some words in postgresql website as follows:
"To do this, the internal representation must follow the standard layout for variable-length data: the first four bytes must be a char[4] field which is never accessed directly (customarily named vl_len_). You must use SET_VARSIZE() to store the size of the datum in this field and VARSIZE() to retrieve it. The C functions operating on the data type must always be careful to unpack any toasted values they are handed, by using PG_DETOAST_DATUM."
These words confuse me. For example, how to convert the values to toasted values?
Could you give me some examples or some suggestions about how to implement it?
Thanks very much