What are the record type struct and classes different use cases? - c#-record-type

Why are the struct and class variant of a record type different. And what would be use cases for both?

Related

Golang SQL rows.Scan function for all fields of generic type

I want to use the Scan() function from the sql package for executing a select statement that might (or not) return multiple rows, and return these results in my function.
I´m new to Golang generics, and am confused about how to achieve this.
Usually, we would use the Scan function on a *sql.Rows and provide the references to all fields of our expected 'result type' we want to read the rows into, e.g.:
var alb Album
rows.Scan(&alb.ID, &alb.Title, &alb.Artist,
&alb.Price, &alb.Quantity)
where Album is a struct type with those five fields shown.
Now, for the purpose of not writing a similar function N times for every SQL table I have, I want to use a generic type R instead. R is of generic interface type Result, and I will define this type as one of N different structs:
type Result interface {
StructA | StructB | StructC
}
func ExecSelect[R Result](conn *sql.DB, cmd Command, template R) []R
How can I now write rows.Scan(...) to apply the Scan operation on all fields of my struct of R´s concrete type? e.g. I would want to have rows.Scan(&res.Field1, &res.Field2, ...) where res is of type R, and Scan should receive all fields of my current concrete type R. And do I actually need to provide a 'template' as argument of R´s concrete type, so that at runtime it becomes clear which struct is now relevant?
Please correct me on any mistake I´m making considering the generics.
This is a poor use case for generics.
The arguments to the function sql.Rows.Scan are supposed to be the scan destinations, i.e. your struct fields, one for each column in the result set, and within the generic function body you do not have access to the fields of R type parameter.
Even if you did, the structs in your Result constraint likely have different fields...? So how do you envision writing generic code that works with different fields?
You might accomplish what you want with a package that provides arbitrary struct scanning like sqlx with facilities like StructScan, but that uses reflection under the hood to map the struct fields into sql.Rows.Scan arguments, so you are not getting any benefit at all with generics.
If anything, you are making it worse, because now you have the additional performance overheads of using type parameters.

What do member numbers mean in Microsoft Bond?

Using Microsoft Bond (the C# library in particular), I see that whenever a Bond struct is defined, it looks like this:
struct Name
{
0: type name;
5: type name;
...
}
What do these numbers (0, 5, ...) mean?
Do they require special treatment in inheritance? (Do I need to make sure that I do not override members with the same number defined in my ancestor?)
The field ordinals are the unique identity of each field. When serializing to tagged binary protocols, these numbers are used to indicate which fields are in the payload. The names of the fields are not used. (Renaming a field in the .bond file does not break serialized binary data compatibility [though, see caveat below about text protocols].) Numbers are smaller than strings, which helps reduce the payload size, but also ends up improving serialization/deserialization time.
You cannot re-use the same field ordinal within the same struct.
There's no special treatment needed when you inherit from a struct (or if you have a struct field inside your struct). Bond keeps the ordinals for the structs separate. Concretely, the following is legal and will work:
namespace inherit_use_same_ordinal;
struct Base {
0: string field;
}
struct Derived : Base {
0: bool field;
}
A caveat about text serialization protocols like Simple JSON and Simple XML: these protocols use the field name as the field identifier. So, in these protocols renaming a field breaks serialized data compatibility.
Also, Simple JSON and Simple XML flatten the inheritance hierarchy, so re-using names across Base and Derived will result in clashes. Both have ways to work around this. For Simple XML, the SimpleXml.Settings.UseNamespaces parameter can be set to true to emit fully qualified names.
For Simple JSON, the Bond attribute JsonName can be used to change the name used for Simple JSON serialization, to avoid the conflict:
struct Derived : Base {
[JsonName("derived_field")]
0: bool field;
}

Difference between modules and existentials

It's folk knowledge that OCaml modules are "just" existential types. That there's some kind of parity between
module X = struct type t val x : t end
and
data 'a spec = { x : 'a }
data x = X : 'a spec
and this isn't untrue exactly.
But as I just evidenced, OCaml has both modules and existential types. My question is:
How do they differ?
Is there anything which can be implemented in one but not the other?
When would you use one over the other (in particular comparing first-class modules with existential types)?
Completing gsg's answer on your third point.
There are two kinds of way to use modules:
As a structuring construct, when you declare toplevel modules. In that case you are not really manipulating existential variables. When encoding the module system in system-F, you would effectively represent the abstract types by existential variables, but morally, it is closer to a fresh singleton type.
As a value, when using first class modules. In that case you are clearly manipulating existential types.
The other representations of existential types are through GADT's and with objects. (It is also possible to encode existential as the negation of universal with records, but its usage are completely replaced by first class modules).
Choosing between those 3 cases depend a bit in the context.
If you want to provide a lot of functions for your type, you will prefer modules or objects. If only a few, you may find the syntax for modules or objects too heavywheight and prefer GADT. GADT's can also reveal a the structure of your type, for instance:
type _ ty =
| List : ty -> ty list
| Int : int list
type exist = E : 'a ty * 'a -> exist
If you are in that kind of case, you do not need to propagate the function working on that type, so you will end up with something a lot lighter with GADT's existentials. With modules this would look like
module type Exist = sig
type t
val t : t ty
end
module Int_list : Exist = struct
type t = int list
let t = List Int
end
let int_list = (module Int_list:Exist)
And if you need sub-typing or late binding, go for the objects. This can often be encoded with modules but this tend to be tedious.
It's specifically abstract types that have existential type. Modules without abstract types can be explained without existentials, I think.
Modules have features other than abstract types: they act as namespaces, they are structurally typed, they support operations like include and module type of, they allow private types, etc.
A notable difference is that functors allow ranging over types of any (fixed) arity, which is not possible with type variables because OCaml lacks higher kinded types:
module type M = sig
type 'a t
val x : 'a t
end
I'm not quite sure how to answer your last question. Modules and existentials are different enough in practice that the question of when to substitute one for the other hasn't come up.

Determining if a type is a reference type or value type

I've come from a Assembler and C/C++ background, so I understand the concept behind reference types versus value types in vb.net. Also, I've read Jon Skeet's article regarding references and value types and I understand all of that.
My question is: How can you tell if a given type is a reference type or a value type?
Is it simply that all integral types (ints, floats, etc.) are value types and all classes are reference types? (If so, where do strings fall?)
Question 2 (related): Is there a way to declare a class as a value class versus a reference class? For example (using extreme brevity):
Public Class MyClass1
Public Value As Integer
End Class
Using this class:
Dim test1 As New MyClass1
test1.Value = 1
Dim test2 As MyClass1
test2 = test1
test2.Value = 2
At the end of this code, the Value in Test1 is 2. Clearly, MyClass1 is a reference type. But, what is it that causes it to be such and not a value type?
In general - enums and structs are value types, classes interfaces and delegates are reference types.
As for declaring a class as a value type - this is not possible, but C# structs are very close to classes and are value types.
As for VB.NET, I believe the equivalent is the Structure statement:
The Structure statement defines a composite value type that you can customize.

What is the difference between the concept of 'class' and 'type'?

i know this question has been already asked, but i didnt get it quite right, i would like to know, which is the base one, class or the type. I have few questions, please clear those for me,
Is type the base of a programing data type?
type is hard coded into the language itself. Class is something we can define ourselves?
What is untyped languages, please give some examples
type is not something that fall in to the oop concepts, I mean it is not restricted to oop world
Please clear this for me, thanks.
I didn't work with many languages. Maybe, my questions are correct in terms of : Java, C#, Objective-C
1/ I think type is actually data type in some way people talk about it.
2/ No. Both type and class we can define it. An object of Class A has type A. For example if we define String s = "123"; then s has a type String, belong to class String. But the vice versa is not correct.
For example:
class B {}
class A extends B {}
B b = new A();
then you can say b has type B and belong to both class A and B. But b doesn't have type A.
3/ untyped language is a language that allows you to change the type of the variable, like in javascript.
var s = "123"; // type string
s = 123; // then type integer
4/ I don't know much but I think it is not restricted to oop. It can be procedural programming as well
It may well depend on the language. I treat types and classes as the same thing in OO, only making a distinction between class (the definition of a family of objects) and instance (or object), specific concrete occurrences of a class.
I come originally from a C world where there was no real difference between language-defined types like int and types that you made yourself with typedef or struct.
Likewise, in C++, there's little difference (probably none) between std::string and any class you put together yourself, other than the fact that std::string will almost certainly be bug-free by now. The same isn't always necessary in our own code :-)
I've heard people suggest that types are classes without methods but I don't believe that distinction (again because of my C/C++ background).
There is a fundamental difference in some languages between integral (in the sense of integrated rather than integer) types and class types. Classes can be extended but int and float (examples for C++) cannot.
In OOP languages, a class specifies the definition of an object. In many cases, that object can serve as a type for things like parameter matching in a function.
So, for an example, when you define a function, you specify the type of data that should be passed to the function and the type of data that is returned:
int AddOne(int value) { return value+1; } uses int types for the return value and the parameter being passed in.
In languages that have both, the concepts of type and class/object can almost become interchangeable. However, there are many languages that do not have both. For instance, I believe that standard C has no support for custom-defined objects, but it certainly does still have types. On the otherhand, both PHP and Javascript are examples of languages where type is very loosely defined (basically, types are either single item, collection/array/object, or undefined [js only]), but they have full support for classes/objects.
Another key difference: you can have methods and custom-functions associated with a class/object, but not with a standard data-type.
Hopefully that clarified some. To answer your specific questions:
In some ways, type could be considered a base concept of programming, yes.
Yes, with the exception that classes can be treated as types in functions, as in the example above.
An untyped language is one that lets you use any type of variable interchangeably. Meaning that you can handle a string with the same code that handles an int, for instance. In practice most 'untyped' languages actually implement a concept called duck-typing, so named because they say that 'if it acts like a duck, it should be treated like a duck' and attempt to use any variable as the type that makes sense for the code encountered. Again, php and javascript are two languages which do this.
Very true, type is applicable outside of the OOP world.