can a type member which is a type be a target? - fortran90

Suppose I have the following setup
type BarType
integer :: i
end type
type FooType
type(BarType) :: bar
end type
I want to have another type
type BazType
type(BarType), pointer :: barPtr
end type
and set barPtr to point to foo%bar. To do this I would have to declare type(BarType), target :: bar, but I got an error. I didn't investigate further, and decided to change strategy, but just for curiosity, do you know if this is allowed ?

I'm not an expert on the standard, but the way I read it, a derived-type component can not have the target attribute; if you want to associate a pointer with such a component, you have to declare the parent object as target.

Related

ClassTag in Scala

In Scala, during type erasure, the generic variable is replaced by 'Object' type wherever the generic variable appears in type position.
E.G: val x T; --> is replaced by val x Object;
Due to this, the details of exact type which is passed, will become unavailable during runtime.
To overcome this (to get the exact type during runtime), it is mentioned that ClassTag will help us.
Can you please help me how ClassTag gets the type information during runtime ?
When ClassTag is mentioned , that is also written with a generic type in context bound.
E.G: def method[T:ClassTag] {...}
So I think, the 'T' mentioned here too, will be erased. But ClassTag somehow keeps the type info.
I am bit puzzled how this works.. (similarly TypeTag and WeakTag as well)
This is not correct:
E.G: val x T; --> is replaced by val x Object;
The type of x is not lost; you can look at the value of x at runtime and determine what type it is. Objects retain their runtime type.
Type erasure affects values of a parameterised type Y[T]. The runtime holds a single type for an object so it cannot hold T as well as Y and "erases" T from the type. If I have an instance of Y[T] I can tell at runtime that it is type Y but cannot tell which T it was parameterised with.
Thus I can distinguish List[T] from Vector[T] but cannot distinguish List[T] from List[U]. But an element of that List retains its type and can be matched against T or U. And a member val x: T can be matched directly to determine the type of the object.
A ClassTag is value that represents a type, so if you store the ClassTag of T in your object then you can match that to work out the type of T without having to look at any of the values of type T inside the object. You are explicitly storing the type information for T that was previously erased.
[ Useful discussion in the comments about this really being about classes rather than types ]

Scala - How is a variable of type Any stored in memory?

How is it possible to create variable of type Any?
And why does isInstanceOf[Int] print true?
I declared x to be Any, not Int.
How does it work? What is happening behind the scenes?
val x = 4: Any // OK
x.isInstanceOf[Int] // true
x.isInstanceOf[String] // false
[EDIT] Maybe to rephrase my question:
How does val x = 4: Any look like in memory?
And once it is stored in memory as Any type, how can I later say that this particular blob of bytes is Int, but not say String?
Does it come along with some kind of information what was the "original" type? Here for example if I typed 4 AND LATER said this is Any type, would it store this original type of 4 as an Int?
Scala language is defined to support the notion of inheritance polymorphism. In other words, if there is some type T which inherits from type U, then any value of type T can be assigned to a variable of type U:
class T extends U
val x: U = new T // compiles
Same thing with Any and Int: in Scala, Int inherits from Any, therefore it is possible to store an integer in an Any variable:
val x: Any = 4 // essentially the same as your example
Also, all of the runtimes Scala runs on know what type of value is actually stored in a variable, regardless of the static type of this variable. This is important for many features of the language, in particular, virtual method overrides, but it also allows you to do manual checks and downcasts, which is what your code does (the checks). In other words, the isInstanceOf method checks the runtime type of a value stored in a variable, not the static type known at the compile time (which would be quite pointless).

Purescript default `Show` instance for records

I saw this question:
Force show a record in PureScript
where I found out I can use purescript-debug to print it, e.g. by using:
> traceAny {a:1} id
{ a: 1 }
unit
I was wondering however what is the rationale behind not having a default Show instance for records:
> {a:1}
Error found:
in module $PSCI
No type class instance was found for
Data.Show.Show { "a" :: Int
}
Show is just implemented as library code, so there's no way an instance can be written that can accomodate every possible record. There would need to be some kind of constraint where you could say "the type of every value in this record must also have a Show instance", for example. The actual implementation would need to be somewhat magic too, since you can't iterate over the labels in a record either.
There have been a few discussions about reforming Show, such as this one, that would potentially solve this, by making Show entirely magic, and only usable for debugging purposes.
Although this doesn't really solve the case you have here, it is possible to rely on Generic deriving to make a Show instance for a newtype'd record, which can take some of the pain out of this kind of thing:
import Data.Generic (class Generic, gShow)
newtype MyRecord = MyRecord { a :: Int }
derive instance genericMyRecord :: Generic MyRecord
instance showMyRecord :: Show MyRecord where
show = gShow
And if you derive Newtype too it makes the record easier to work with as you can use the various operations that help with wrapping/unwrapping/operating under the newtype, etc.

DXE7: "type A = type B" and var x (of type A):= A.create leads to E2010 incompatible type compile error. Why?

A. Short summary of the problem:
type
A = class(TObject)
end;
B = type A;
The compiler error E2010 incompatible types: 'B' and 'A' is shown, when you instantiate a variable of class B in the following style:
var
TheB: B;
begin
TheB:= B.Create;
..
I can avoid that problem by removing the second "type", so the declaration is the standard one:
type
A = class(TObject)
end;
B = A;
But in my opinion, the error should not come, even WITH the second "type", because A is not directly used (The second "type" tells the compiler to see both classes as individuals, see http://docwiki.embarcadero.com/RADStudio/Seattle/en/Declaring_Types for details). Can someone explain, because of what reason the error ignores my opinion? (o;
B. Complete history and more complex details:
First of all: The error:
[dcc32 Fehler] gboDHL.pas(165): E2010 Inkompatible Typen: 'Origin' und 'CountryType'
(which means "incompatible types" in english),
occurs in the following line of code:
AShipmentOrder.Shipment.Shipper.Address.Origin:= DHL_geschaeftskundenversand_api_2.Origin.Create;
Now here is the background:
I try to communicate with the "new" DHL Geschäftskundenversand API v2.2 which still uses SOAP to create a shipment order. DHL_geschaeftskundenversand_api_2 is the completely generated unit from the integrated delphi xe7 WSDL generator for that service.
AShipmentOrder is the instance which represents the top level xml node of the request.
The class "Origin" is implemented/generated this way:
type
CountryType = class(TRemotable)
private
Fcountry: country2;
Fcountry_Specified: boolean;
FcountryISOCode: countryISOType;
Fstate: state;
Fstate_Specified: boolean;
Fcountry_: country;
Fcountry__Specified: boolean;
FcountryISOCode_: countryISOType;
Fstate_: state2;
Fstate__Specified: boolean;
procedure Setcountry(Index: Integer; const Acountry2: country2);
function country_Specified(Index: Integer): boolean;
procedure Setstate(Index: Integer; const Astate: state);
function state_Specified(Index: Integer): boolean;
procedure Setcountry_(Index: Integer; const Acountry: country);
function country__Specified(Index: Integer): boolean;
procedure Setstate_(Index: Integer; const Astate2: state2);
function state__Specified(Index: Integer): boolean;
published
property country: country2 Index (IS_OPTN) read Fcountry write Setcountry stored country_Specified;
property countryISOCode: countryISOType read FcountryISOCode write FcountryISOCode;
property state: state Index (IS_OPTN) read Fstate write Setstate stored state_Specified;
property country_: country Index (IS_OPTN) read Fcountry_ write Setcountry_ stored country__Specified;
property countryISOCode_: countryISOType read FcountryISOCode_ write FcountryISOCode_;
property state_: state2 Index (IS_OPTN) read Fstate_ write Setstate_ stored state__Specified;
end;
Origin = type CountryType; { "http://dhl.de/webservice/cisbase"[GblElm] }
The "property" Origin of AShipmentOrder.Shipment.Shipper.Address is implemented/generated this way:
type
NativeAddressType = class(TRemotable)
...
published
...
property Origin: Origin Index (IS_OPTN or IS_REF) read FOrigin write SetOrigin stored Origin_Specified;
...
end;
If it is unclear, let me say, that ´AShipmentOrder.Shipment.Shipper.Address´ is of class NativeAddressType
I'm using Delphi XE7 on Windows 10, 64bit, compiling to 32bit.
The delphi WSDL generator has different problems, which I had to manage before, and it is really not "nice" that in the output the property names are identical to the class names, but that is not changeable, it seems.
The class "Origin" is not the only class in that generated unit which is named as the property it belongs to, but the error only occurs, when such a class is implemented as
type
A = type B
I tried to find a description of that special declaration variant, but that is quite hard, because the keywords are too often used.
On http://www.delphibasics.co.uk/RTL.asp?Name=Type I found the following explanation:
1.type Name = Existing type  
Refers to an existing type, such as string by a new Name.
 
2.type Name = type Existing type  
This has the same effect as above, but ensures that at run time, variables of this type are identified by their new type name, rather than the existing type name.
If I understand that correctly, that means that in my example the class Origin is not identified anymore as CountryType, but as Origin. That should be fine, because the property Origin is declared as to be of class Origin.
While going on to try to understand that problem, I manually renamed The class "Origin" in the generated unit to OriginType (delphi used that postfix "Type" with several other classes in that unit, not clear, why it has not used it with the Origin-Type). After that, I can exclude a name-conflict, because now the error is
[dcc32 Fehler] gboDHL.pas(165): E2010 Inkompatible Typen: 'OriginType' und 'CountryType'
There seems to be no reason because of what that error occurs.
After some hours without some ideas I found this Embarcadero WIKI entry: http://docwiki.embarcadero.com/RADStudio/Seattle/en/Declaring_Types
After reading and thinking about that, I understood, that the "type" in A = type B is not necessary in that case, because there is no need to handle class A in another way than class B, so I removed that manually in the generated unit and now, it works fine.
I also understand, that a special option in the generator was checked to prevent "name conflicts". If this option is not checked, this problem also should be solved (but maybe some others come around (o; ).
Maybe this helps someone to spent more time outside than with a problem like that (o;
But in the end, I do not understand what was the problem here, because all properties were of type "Origin" and later of "OriginType", also this type was created with Origin.Create and later with OriginType.Create. So the "CountryType" was never used, except for the class declaration of "Origin" / "OriginType". In my opinion this should not lead to that problem, but it does.
Can somebody explain that?
Thank you in advance
Kai
You are getting: E2010 Incompatible types: 'Tb' and 'Ta', which might seems odd:
type
Ta = class
end;
Tb = type Ta;
var
b: Tb;
begin
b := Tb.Create; // E2010 Incompatible types: 'Tb' and 'Ta'
end.
Ta and Tb are two distinct types.
From Type Compatibility you can see that none of the conditions listed indicates that the two distinct types are compatible.
Type Compatibility
Every type is compatible with itself. Two distinct types are compatible if they satisfy at least one of the following conditions.
They are both real types.
They are both integer types.
One type is a subrange of the other.
Both types are subranges of the same type.
Both are set types with compatible base types.
Both are packed-string types with the same number of characters.
One is a string type and the other is a string, packed-string, or Char type.
One type is Variant and the other is an integer, real, string, character, or Boolean type.
Both are class, class-reference, or interface types, and one type is derived from the other.
One type is PAnsiChar or PWideChar and the other is a zero-based character array of the form array[0..n] of PAnsiChar or PWideChar.
One type is Pointer (an untyped pointer) and the other is any pointer type.
Both types are (typed) pointers to the same type and the {$T+} compiler directive is in effect.
Both are procedural types with the same result type, the same number of parameters, and type-identity between parameters in corresponding positions.
The reason for the compiler error is thus: When you call Tb.Create, the compiler identifies that with Ta.Create and since b is of a distinct non-compatible type, it is not accepted.
You can call that a flaw, but it follows strict type rules and can easily be corrected like shown below.
Declaring Tb = class(Ta) would resolve the compiler error since Tb is derived from Ta.
Also declaring Tb = Ta would resolve the compiler error, since they would denote the same type (not two distinct types) and thus assignment compatible.

How to define superclass?

How does one define a super class in Haskell? My situation is that I have defined a class StringHashed that maps members to their names as a String. I wish to implement, en mass, all t from Show t by making the string name simply return show t. Am I right in saying that StringHashed is now a superclass of Show? Here is what I would like to be able to write:
class StringHashed t where
stringHash :: t -> String
instance Show t => StringHashed t where
stringHash = show
But Haskell complains about an invalid instance declaration. I have also tried instance StringHashed (Show t) and other syntactical dribble; none have worked for me. I have also read a proposal on the GHC wiki that provides no solution. This is the one. I have concern about using -XFlexibleInstances simply because it is not default. Is there a proper way to achieve a general instance declaration? Or am I being too demanding of Haskell's type system?
Haskell superclasses cannot be added after the fact - they need to be mentioned in the subclass's declaration. And defining an instance like you do in the question, while possible with extensions, can create subtle overlap problems.
FlexibleInstances itself is not the problem - it's one of GHC's most innocuous extensions. The problem is that GHC's instance lookup method means that
instance Show t => StringHashed t where ...
defines this instance to hold for all types t - the Show t restriction is only an afterthought checked after lookup. So it will overlap with all other instances you can make, and while there is an extension OverlappingInstances to allow this, it is considered somewhat dubious to use.
However GHC has a feature DefaultSignatures, which is designed for use cases similar to yours:
{-# LANGUAGE DefaultSignatures #-}
class StringHashed t where
stringHash :: t -> String
default stringHash :: Show t => t -> String
stringHash = show
instance StringHashed Int
This allows you to write a default for the method which only works for some instance types. Note however, that you still need to write an actual instance declaration for each type - but its body can be empty.