Using the TYPE keyword in Pascal - pascal

I'm trying to understand the definition of the keyword TYPE in pascal. I understand that typedef in C just gives a new name to the type (alasing). But as I understand TYPE in Pascal does not work that way. It will create a new unique type.
I was trying to search and create a simple example which shows the mechanism of TYPE. I tried to create an example which creates some types and a function. After that, it pass each time one of the types to that function. It should fail because the function should get only one type, which proves that those types are not just aliasing. Due to my lack of knowledge of Pascal syntax, I failed each time.
Could you share a simple short program which proves the power of TYPE?
EDIT:
I have created the following example:
program Check;
TYPE
Meters = Real; Seconds = Real;
VAR
m: Meters; s: Seconds;
Procedure PRINT_SEC(s: Seconds);
Begin
WriteLn(s, ' sec');
end;
Begin
PRINT_SEC(s);
PRINT_SEC(m);
end.
Output:
0.0000000000000000E+000 sec
0.0000000000000000E+000 sec
But why it does not fail? I passed m which has type Meters no? Also, How can I initialize those variables?

First a minor point, in Pascal, the keyword TYPE does not create types. The keyword TYPE must occur before type definitions, but it is the type definitions which MAY create types. Not all type definitions create types.
The Pascal Standard says the following:
A type-definition shall introduce an identifier to denote a type.
which means a type definition introduces (i.e. creates or redefines) an identifier which denotes (i.e. is an alias for) a type.
The Pascal Standard defines a type definition as:
type-definition = identifier '=' type-denoter
type-denoter = type-identifier | new-type
new-type = new-ordinal-type | new-structured-type | new-pointer-type
Which means that a type definition is a identifier, followed by the equal side, followed by a type denoter. A type denoter is either a type identifier or a new type.
So a type identifier introduces an identifier that denotes (i.e. is an alias for) either another type identifier or a new-type. A type is created only in the case where the type denoter is a new type.
So in your example:
TYPE
Meters = Real; Seconds = Real;
The type denoter in both type definitions is the type identifier Real, so Meters and Seconds are both aliases for Real.
Yes, in Pascal, Real is not a Type, it is a built-in type identifier for the real type.
The Pascal Standard says
The required type identifier real shall denote the real-type.
So real is actually a type identifier and not a type. It is as if, there is an invisible type definition.
TYPE
Real = real-type;
where real-type is the actual real type.

Variables like m and s are defined by a type. In this case both types origins from a real type. That is called a type alias. They are compatible, both as a type and by assignment.
If you want a distinct type (in Freepascal and delphi), define:
type Seconds = type real;
That would have made the print procedure to only accept the Seconds type argument. Note that variables of Seconds and Meters declared as distinct types still are assignment compatible.
To initialize variables, just assign a value:
s := 42.0;
Note: most types are named starting with a T. Like TSeconds. Just to distinct them from variables. It is a common convention (in pascal).

Related

Get the underlying type from a string in go? [duplicate]

Is there a way to use the reflection libraries in Go to go from the name of a type to its Type representation?
I've got a library where the user needs to provide Type representations for some code generation. I know it must be possible (in a sense) because they can just create a variable of that type and call the TypeOf function, but is there a way to circumvent this and just get representation from the name?
The question is not quite explicit, it can be interpreted in 2 ways, to one of which the answer is no, not possible; and the other to which the answer is yes, it's possible.
At runtime
If the type name is provided as a string value, then at runtime it's not possible as types that are not referred to explicitly may not get compiled into the final executable binary (and thus obviously become unreachable, "unknown" at runtime). For details see Splitting client/server code. For possible workarounds see Call all functions with special prefix or suffix in Golang.
At "coding" time
If we're talking about "coding" time (source code writing / generating), then it's possible without creating / allocating a variable of the given type and calling reflect.TypeOf() and passing the variable.
You may start from the pointer to the type, and use a typed nil pointer value without allocation, and you can navigate from its reflect.Type descriptor to the descriptor of the base type (or element type) of the pointer using Type.Elem().
This is how it looks like:
t := reflect.TypeOf((*YourType)(nil)).Elem()
The type descriptor t above will be identical to t2 below:
var x YourType
t2 := reflect.TypeOf(x)
fmt.Println(t, t2)
fmt.Println(t == t2)
Output of the above application (try it on the Go Playground):
main.YourType main.YourType
true

How to get Type representation from name via reflection?

Is there a way to use the reflection libraries in Go to go from the name of a type to its Type representation?
I've got a library where the user needs to provide Type representations for some code generation. I know it must be possible (in a sense) because they can just create a variable of that type and call the TypeOf function, but is there a way to circumvent this and just get representation from the name?
The question is not quite explicit, it can be interpreted in 2 ways, to one of which the answer is no, not possible; and the other to which the answer is yes, it's possible.
At runtime
If the type name is provided as a string value, then at runtime it's not possible as types that are not referred to explicitly may not get compiled into the final executable binary (and thus obviously become unreachable, "unknown" at runtime). For details see Splitting client/server code. For possible workarounds see Call all functions with special prefix or suffix in Golang.
At "coding" time
If we're talking about "coding" time (source code writing / generating), then it's possible without creating / allocating a variable of the given type and calling reflect.TypeOf() and passing the variable.
You may start from the pointer to the type, and use a typed nil pointer value without allocation, and you can navigate from its reflect.Type descriptor to the descriptor of the base type (or element type) of the pointer using Type.Elem().
This is how it looks like:
t := reflect.TypeOf((*YourType)(nil)).Elem()
The type descriptor t above will be identical to t2 below:
var x YourType
t2 := reflect.TypeOf(x)
fmt.Println(t, t2)
fmt.Println(t == t2)
Output of the above application (try it on the Go Playground):
main.YourType main.YourType
true

How is type inference implemented in a language like C++11 or Go?

I saw this question here, but it doesn't answer what I had in mind in particular detail.
If languages like Go or C++11 don't use an inference algorithm like Damas-Milner, what exactly do they do? I don't think it's as simple as taking the type on the right hand side because what if you had something like:
5 + 3.4
How would the compiler decipher what type that is? Is there any algorithm that isn't as simple as
if left is integer and right is float:
return float;
if left is float and right is integer:
return float;
etc... for every possible pattern
And if you could explain things in simple terms that would be great. I'm not studying compiler construction or any of the theoretical topics in great detail, and I don't really speak functional languages or complex mathematical notation.
I don't think it's as simple as taking the type on the right hand side
For basic type inference of the form auto var = some_expression;, it is exactly that simple. Every well-typed expression has exactly one type and that type will be the type of var. There will be no implicit conversion from the type of the expression to another type (as there might be if you gave an explicit type for var).
what if you had something like:
5 + 3.4
The question "What is the type of 5 + 3.4?" isn't specific to type inference, C++ compilers always had to answer this question - even before type inference was introduced.
So let's take a step back and look at how a C++ compiler typechecks the statement some_type var = some_expression;:
First it determines the type of some_expression. So in code you can imagine something like Type exp_type = type_of(exp);. Now it checks whether exp_type is equal to some_type or there exists an implicit conversion from exp_type to some_type. If so, the statement is well-typed and var is introduced into the environment as having the type some_type. Otherwise it is not.
Now when we introduce type inference and write auto var = some_expression;, the equation changes as such: We still do Type exp_type = type_of(exp);, but instead of then comparing it to another type or applying any implicit conversions, we instead simply set exp_type as the type of var.
So now let's get back to 5 + 3.4. What is its type and how does the compiler determine it? In C++ its type is double. The exact rules to determine the type of an arithmetic expression are listed in the C++ standard (look for "usual arithmetic conversions"), but basically boil down to this: Of the two operand types, pick the one that can represent the greater range of values. If the type is smaller than int, convert both operands to int. Otherwise convert both operands to the type you picked.
In code you'd implement this by assigning each numeric type a conversion rank and then doing something like this:
Type type_of_binary_arithmetic_expression(Type lhs_type, Type rhs_type) {
int lhs_rank = conversion_rank(lhs_type);
int rhs_rank = conversion_rank(rhs_type);
if(lhs_rank < INT_RANK && rhs_rank < INT_RANK) return INT_TYPE;
else if(lhs_rank < rhs_rank) return rhs_type;
else return lhs_type;
}
Presumably the rules for Go are somewhat different, but the same principles apply.

Use a type before it's declared in VHDL (2008)

Is it possible in any version of VHDL, maybe in 2008, to use a type before it's declared?
E.g. I have this array declaration in the architecture of an entity:
type my_array is array (integer range <>) of my_type;
And still in the same architecture section, but later in the file I have this:
type my_type is record
my_field: signed(31 downto 0);
end record;
Now this gives the following error in Vivado:
[Synth 8-1031] my_type is not declared
The solution is of course to move the record declaration above the array declaration. However this gets very complicated and messy with the number of types increasing (since you basically have to topologically sort your types taking their dependencies into account).
Something like this is supported in every major programming language so I figured maybe it would also exist in VHDL. I also vaguely remember reading about this having been added to VHDL 2008 but can't find any resources about it and my quick test with VHDL 2008 was negative.
So is it possible to use a type in VHDL before its declared, given that the type is declared still in the same architecture, same file, but a few lines below?
Is it possible in any version of VHDL, maybe in 2008, to use a type before it's declared?
No.
IEEE Std 1076-2008 6. Declarations
6.1 General
The language defines several kinds of named entities that are declared explicitly or implicitly by declarations. Each entity’s name is defined by the declaration, either as an identifier or as an operator symbol or a character literal.
...
For each form of declaration, the language rules define a certain region of text called the scope of the declaration (see 12.2). ...
12.2 Scope of declarations
The scope of a declaration, except for an architecture body, extends from the beginning of the declaration to the end of the immediately closing declarative region; the scope of an architecture body extends from the beginning to the end of the architecture body. In either case, this part of the scope of a declaration is called the immediate scope.
12.3 Visibility
A declaration is visible only within a certain part of its scope; this part starts at the end of the declaration except in the declaration of a design unit other than a PSL verification unit, a package declaration, or a protected type declaration, in which case it starts immediately after the reserved word is occurring after the identifier of the design unit, a package declaration, or protected type declaration. This rule applies to both explicit and implicit declarations.
It's the visibility rules stopping you from referencing a type before it's declared.
Also VHDL does not support forward declaration of types other than interface type declarations (generic types), but does for subtypes as your example my_array shows.
The generic types Brian indicates usefulness is limited lacking synthesis vendor support as well as limitations on operations of a type (see 6.5.3 Interface type declarations) summarized in Peter Ashenden's book VHDL 2008 Just the New Stuff:
1.1 Generic Types
VHDL-2008 defines a number of rules covering formal generic types and the ways they can be used. The formal generic type name can potentially represent any constrained type, except a file type or a protected type. The entity can only assume that operations available for all such types are applicable, namely: assignment; allocation using new; type qualification and type conversion; and equality and inequality operations. The formal generic type cannot be used as the type of a file element or an attribute. Moreover, it can only be used as the type of an explicitly declared constant or a signal (including a port) if the actual type is not an access type and does not contain a subelement of an access type. For signals, the predefined equality operator of the actual type is used for driver update and event detection.
Note that for access types there is a special case, where an incomplete type declaration can be references, in order to allow types for linked lists, like:
type value_cell; -- Incomplete declaration
type value_ptr is access value_cell; -- value_cell only for access type
type value_cell is record -- Full declaration
value : bit_vector(0 to 3);
next_cell : value_ptr;
end record value_cell;
However, this is not using the type before declared, and the access type is neither synthesizable, but it is a useful technique for test bench code.

Why literal value has no type?

Type Inference is a powerful attribute of Swift. It means the compiler can infer the literal's type from its value provided by the programmer, the explicit type specification is not needed.
For example var IntNum = 3; the compiler can infer that the variable IntNum is of type Int. In Xcode, If user hits the key and clicks on the variable name, here IntNum, then Xcode tells you what the type it is.
However, if I did that on the literal value 3, Xcode provides nothing. I guess, the literal value I put on the screen simply has no type at all, only the object variable and constant has the type property.
I just guess so, can someone explain that to me?
Cheers
SL
That's right.
From the documentation
Type Safety and Type Inference
Type inference is particularly useful when you declare a constant or
variable with an initial value. This is often done by assigning a
literal value (or literal) to the constant or variable at the point
that you declare it. (A literal value is a value that appears directly
in your source code)
...
If you combine integer and floating-point literals in an expression, a
type of Double will be inferred from the context:
let anotherPi = 3 + 0.14159
// anotherPi is also inferred to be of type Double
The literal value of 3 has no explicit type in and of itself, and so
an appropriate output type of Double is inferred from the presence of
a floating-point literal as part of the addition.

Resources