I am wondering if it is possible to extract the type of a type parameter. For example I want to be able to do something like:
case list[&T] _: println("list of <&T> type");
What I am looking to do is match various patterns that look the same but may have different types and use the specific type.
Is this possible? Or is there another way to achieve this?
You are looking for typeOf, described in the Rascal Tutor. A function that prints the type of its argument can be defined as follows (remember to add import Type; to your Rascal source file):
void printMyType(&T a) { println("<typeOf(a)>"); }
Examples:
rascal>printMyType(3)
int()
ok
rascal>printMyType("abc")
str()
ok
Related
I'm confused as to the uses of "as" keyword.
Is it a cast operator or alias operator?
I encountered the following code on the internet which looked like a cast operator:
var list = json['images'] as List;
What does this mean?
as means different things in different contexts.
It's primarily used as a type cast operator. From the Dart Language Tour:
as: Typecast (also used to specify library prefixes)
It links to an explanation of how as is also used to add a prefix to an imported library to avoid name collisions. (as was reused to do different things to avoid needing extra keywords.)
just to add the as keyword is now flagged by the linter and they prefer you to use a check like is
if (pm is Person)
pm.firstName = 'Seth';
you can read more here https://github.com/dart-lang/linter/issues/145
As the language tour says:
Use the as operator to cast an object to a particular type if and only if you are sure that the object is of that type.
Following with your example:
var list = json['images'] as List;
You would use as here to cast or convert json['images'] into a <List> object.
From another SO post (talking about explicit cast vs. as):
as ... is more like an assertion, if the values type doesn't match as causes a runtime exception.
You can also use it when importing packages. A common example is the dart:convert as JSON which then can be reached final foo = JSON.jsonDecode(baz)
It's casting, your code is similar as:
List list = json['images'];
I'm trying to pass a type in order to make use of the type information, but that types doesn't appear to be pass through.
I went back to the docs to double check that Dart generics are in fact reified and according to the docs, they are:
I call hydrate on a response which morphs the content of response object:
response.hydrate<BoqVO>();
I'm expecting T to be of type BoqVO:
class Response {
...
void hydrate<T>() {
print(T.runtimeType); // always prints _Type
if (T is BoqVO) {
print("IF");
} else {
print("ELSE"); // always goes into ELSE block
}
}
...
}
... but it's not.
Replacing response.hydrate<BoqVO>(); with response.hydrate(new BoqVO()); and changing the method signature to
void hydrate(T t) {
works if i now use lowercase t, but one shouldn't have to instantiate the object in order for reified generics to be available.
Any ideas why Dart is doing this or what i'm missing for reified generics to work correctly?
PS: I'm not on Dart 2 yet, currently on Dart 1.24.3
As Günther Zöchbauer has said, the type parameter doesn't work in Dart 1.24.
The following explains what would happen if you tried the same code in Dart 2.0, where it would also not work, because it uses the type parameter incorrectly.
The code T.runtimeType treats T as an expression. When a type, including a type parameter, is used as an expression, it evaluates to an instance of the class Type. What you print is the runtime type of that Type object (where _Type is an internal platform implementation of Type).
To print the real type, just print(T) (that still converts T to a Type object, but one representing the type BoqVO and with a toString that includes the BoqVO name).
Likewise for T is BoqVO, you evaluate T to a Type object, and since Type doesn't implement BoqVO, that test is always false. There is no simple way to test if the type of a type parameter implements a specific other type, but you can hack around it as <T>[] is List<BoqVO>.
Generic collections were supported from the beginning and they got some type support, but generic methods were only experimental in Dart 1 and reified type parameters were only added in Dart 2 pre releases.
I remember I read somewhere about something that's more or less like this:
class Process <T> {
var data: Array<T> = [];
func addData (element: T) { data.append(T); }
}
This way, I can instantiate the object like this:
let objInt = Process <Int>
objInt.addData (100);
let objString = Process <String>
objString.addData ("Hello");
I want to know what is this "T", how it works, how to implement it, and how to create a class that is partially based on this dynamic type "T". But I don't know what is the keyword to search on the internet for this. I search for dynamic type in Swift, but all google returns me is about identifying and printing class' run-time dynamic type. Can somebody helps? Thanks.
Generics
From Swift programming language book
"Generic code enables you to write flexible, reusable functions and types that can work with any type, subject to requirements that you define. You can write code that avoids duplication and expresses its intent in a clear, abstracted manner."
The generic version uses a placeholder type name (called T or any other name) instead of an actual type name (such as Int, String, or Double). So in your case Process class can hold data of any type which is specified by T parameter.
You mean generics. Here is the link
When trying to initialize a Type to \int(), as found in http://tutor.rascal-mpl.org/Rascal/Libraries/analysis/m3/Core/modifiers/modifiers.html#/Rascal/Libraries/lang/java/m3/AST/Declaration/Declaration.html , rascal throws an error saying "Expected Type, but got TypeSymbol".
This is the code I used:
Type inttype = \int();
What is the proper way to initialize a Type variable to \int()?
To solve the problem you can write:
Type myIntType = Type::\int();
More explanation follows. The \int() constructor is defined at least twice in different places:
In the abstract syntax tree definition of Java types that are used in Declarations. It is the representation of the word int in source code.
In the TypeSymbol definition in java::lang::m3::Core. There \int() represents a symbolic type.
They have the same name because they point to the same concept, but in different representations. The first is just used for a direct representation of source code, the second is used for its abstract symbolic interpretation.
To distinguish between the two representations you should either import the module that defines the AST nodes, or import the module that defines the TypeSymbols. If you happen to have both imported, you should choose a representation explicitly:
Type myIntType = Type::\int();
TypeSymbol mySymbol = TypeSymbol::\int();
So to finally explain the error message, the system chose the second kind of \int()` in TypeSymbol to build a value, and you tried to assigned it to a variable of the first kind.
\int() is a TypeSymbol, I think you're looking for
Type inttype = int();
Let's say I have a function which does something pretty complicated and it is implemented with the help of subfunctions. To make things easier, instead of tuples I would like to use some intermediate structures which are private to the implementation of this function.
I don't want the declaration of these structures to leak outside. So I want something like this:
let someComplexFun p =
type SomeRecord = {i:int; x:int; y:int;}
type SomeOtherRecord = {...}
let innerFunctionA (x:SomeRecord) = ...
let innerFunctionB (x:SomeOtherRecord) = ...
...
I tried it but of course the compiler doesn't let me do this. I looked at the documentation and I can't see anywhere quickly that the types must be declared at the module level.
In LISP for example, it seems that it's all entirely legal, e.g.:
(defun foo (when)
(declare (type (member :now :later) when)) ; Type declaration is illustrative and in this case optional.
(ecase when
(:now (something))
(:later (something-else))))
So, am I missing something? Is this possible if F# at all?
To verify that this is not allowed according to the specification, take a look at the grammar of F# expressions in the specification: Section 6: Expressions. It lists various constructs that can be used in place of expr and none of them is a type declaration type-defn (described in Section 8: Type Declarations).
The (simplified) syntax for function declarations is let ident args = expr, so the body has to be an expression (and you cannot declare types inside expressions).
Types can only be declared at module or namespace scope in F#.
(You can use access modifiers like internal or signature files to hide types from other components.)
What Brian said.
heres a link to some more information http://www.ctocorner.com/fsharp/book/ch17.aspx