In programming language what is the difference between Inferred Type and Dynamic typing? I know about Dynamic typing but don't get how dynamic typing is differ from Inferred Type and how? Could someone please provide explanation with some example?
Inferred type = set ONCE and at compile time. Actually the inferred part is only a time saver in that you don't have to type the Typename IF the compiler can figure it out.
Type Inference is often used in conjunction static typing (as is the case with swift) (http://en.wikipedia.org/wiki/Type_inference)
Dynamic type = no fixed Type -> type can change at runtime
static & inferred example:
var i = true; //compiler can infer that i most be of type Bool
i = "asdasdad" //invalid because compiler already inferred i is an Bool!
it is equal to
var i: bool = true; //You say i is of type Bool
i = "asdasdad" //invalid because compiler already knows i is a Bool!
==> type inference saves you spell out the type if the compiler can see it
BUT if it were dynamic that would work (e.g. objC) as the type is only based on the content at RUNtime
id i = #YES; //NSNumber
i = #"lalala"; //NSString
i = #[#1] //NSArray
you can change data type on the fly for dynamic typing, but inferred typing does not require explicit data type declaration before use.
Static and dynamic typing tell you when the type of the variables is checked.
Static typing checks the type during compilation. Dynamic typing checks the type during runtime( on the fly)
Inferred and Manifest concerns whether you have to specify the type of the variable or not. Inferred means that the language will detect it for you. Manifest means that the type must be specified.
Related
To create a variable in Rust you'd use:
let var_name = 10;
This would also be valid:
let var_name: i32 = 10;
Constant variables are created like this:
const VAR_NAME: i32 = 10;
But if you tried to create a constant variable like this:
const VAR_NAME = 10;
You'd get an error that looks like this:
error: expected `:`, found `=`
--> src/main.rs:5:11
|
4 | const VAR_NAME = 10;
| ^ expected `:`
Having come from languages like JavaScript, Python & PHP this is kind of confusing to me.
Why is it that I have to specify a type definition when using const but not when I use let?
Currently, there is a rule "Constants must be explicitly typed." (for static: "A static item is similar to a constant").
But, you are right: the compiler could infer it. There is an open discussion about that: #1349, TL;DR:
We could technically infer the type of const and static variable
We do not use them very often so it's not very annoying to annotate the types
We should maybe limit type inference for constants/statics to only literal value
This could make error messages less accurate
Maybe limit type inference for constants/statics to local scopes like function bodies
For integers, const FOO = 22 would infer to i32 so probably not the type one would expect. So we'd end up writing const FOO = 22usize.
When the variable is initialized with a const-fn, the type should be inferred
When the variable is initialized with another variable typed explicitly
For arrays, the explicit type is very redundant
For variables which are only exported, we can end up not being able to infer their types (so it would be a compile-time error "type needs to be specified")
It may be worth mentioning that one of the guiding principle of type inference in Rust is that type inference should be local. This is the reason why, unlike in Haskell, function signatures always need to be fully specified. There are multiple reasons for this, notably it means easier reasoning for human readers and better error messages. This puts module level const in a tough spot, inference-wise. Matthieu M.
So far, there is still not a proposed RFC, so this issue stays open.
See also:
Why does Rust not permit type inference for local constants?
I read how to init embed type, and a related Q&A.
What my problem is when compile this code, I got :
[Error] unknown field 'feature.DefaultSshHelper' in struct literal of type dala02
type FDH feature.DefaultSshHelper
type dala02 struct {
Md5_v string
feature.DefaultSshHelper
//FDH
}
var x_01_h1_p = &dala02{
Md5_v: "",
feature.DefaultSshHelper: feature.DefaultSshHelper{
//FDH: FDH{
// blabla
},
}
// use it by a interface []feature.CmdFioHelper{x_00_h1_p}
At first time, I thought it was an Exported problem, so I added this line 'type FDH feature.DefaultSshHelper'. Now, we have this error :
[Error] cannot use x_01_h1_p (type *dala02) as type feature.CmdFioHelper in array or slice literal:
*dala02 does not implement feature.CmdFioHelper (missing Getnextchecker method)
But a pointer of feature.DefaultSshHelper does implement feature.CmdFioHelper ( a interface ). So pointer of dala02 should also implement that, right? (reference form effective go)
There's an important way in which embedding differs from subclassing. When we embed a type, the methods of that type become methods of the outer type, but when they are invoked the receiver of the method is the inner type, not the outer one.
Question is how to fix this compile error, which line is wrong? I'm not a expert for golang, thanks for your advice :). BTW I do find some workaround.
When you refer to embedded fields, you have to leave out the package name of the embedded type, as the unqualified type name acts as the field name.
Spec: Struct types:
A field declared with a type but no explicit field name is an anonymous field, also called an embedded field or an embedding of the type in the struct. An embedded type must be specified as a type name T or as a pointer to a non-interface type name *T, and T itself may not be a pointer type. The unqualified type name acts as the field name.
So simply write:
var x_01_h1_p = &dala02{
Md5_v: "",
DefaultSshHelper: feature.DefaultSshHelper{
// blabla
},
}
Your other attempt type FDH feature.DefaultSshHelper falls short as this type declaration creates a new type with zero methods: the type FDH does not "inherit" the methods of feature.DefaultSshHelper. And thus any type that embeds FDH will also lack methods of feature.DefaultSshHelper.
Two questions.
First,
Below is strong type.
String msg = "Hello world.";
msg = "Hello world again.";
And, below dynamic
var msg = "Hello world.";
msg = "Hello world again.";
Is there any difference between the two 'msg's above?
Second, if I use 'new' keyword to initiate a variable as below,
Map myMap = new Map;
Why to indicate the variable 'myMap' is a Map instance(Map myMap) as 'new' keyword already include the same meaning? So, isn't it okay just,
myMap = new Map;
Because the 'new' keyword already implies the newly initiated variable is both variable and Map type, I can't understand why normally 'Map' keyword is with the variable name, even 'var' also.
Does anyone have any idea about this (seems a little bit redundant) Dart grammar?
In regard to the first question, there will be no difference in what each msg variable contains.
For the Map question, the reason for specifying the type of a variable that is constructed at declaration is to allow some flexibility with subclasses. Take for example the following code:
class SubMap extends Map {
SubMap() : super();
}
Map map = new SubMap();
Here we have a variable map which contains a SubMap object as its value, however we are allowing it to contain values of type Map (or other types which subclass Map) at later times.
The main thing to remember with Dart is that it is optionally typed. When running your code, none of your type annotiations make any difference at all (unless you run in checked mode). What the type annotations are for is to help your IDE and other tools provide autocomplete help, possible warnings, etc. which other fully dynamic languages like Javascript cannot.
String msg = "Hello world.";
msg = "Hello world again.";
msg = 1; // exception in checked mode - int can not be assigned to String.
var msg = "Hello world.";
msg = "Hello world again.";
msg = 1; // ok in checked mode
Checked mode is the developer mode where type annotations are checked and create runtime exceptions when code violates them.
In unchecked (production) mode it makes no difference if you add a type annotation and which one. This is for performance reasons because checked mode is slower.
The declaration Map myMap = new Map() does three things:
it declares a variable named myMap with type-annotation Map,
it creates a new object using the Map constructor, and
it assigns the object to the variable.
The type annotation means that myMap has static type Map. The static type can give you some warnings at compile time, but it doesn't change anything at runtime.
The type annotation also adds a type check in checked mode, where any assignment to the variable is checked for being assignable to Map.
The object you create could be any object using any constructor. I regularly use new HashMap() instead of new Map(), and still assign it to a variable typed as Map.
Then the object is assigned to the variable, and the type check succeeds, if in checked mode.
The variable is independent of the value used to initialize it. If you later assign a string to the myMap variable, it will fail in checked mode.
So, the difference between the two msg variables is that one has a static type and a type check in checked mode.
For the code you show, there is no difference in behavior.
If the next line was var y = msg + 42;, then the typed version would give a warning (msg has static type String, and String.operator+ has type String->String, so the 42 has an invalid argument type), where the untyped version wouldn't warn you (msg has type dynamic so you probably know what you are doing).
Dart Editor version 1.2.0.release (STABLE). Dart SDK version 1.2.0.
This source code produces runtime exception.
void main() {
test(new Base());
}
void test(Child child) {
}
class Base {
}
class Child extends Base {
}
I assumed that the analyzer generates something like this.
The argument type 'Base' cannot be assigned to the parameter type 'Child'
But I can only detect this error at runtime when occurred this exception (post factum).
Unhandled exception:
type 'Base' is not a subtype of type 'Child' of 'child'.
The analyzer is following the language specification here.
It only warns if a the static type of the argument expression is not assignable to the type of function the parameter.
In Dart, expressions of one type is assignable to variables of another type if either type is a subtype of the other.
That is not a safe type check. It does not find all possible errors. On the other hand, it also does not disallow some correct uses like:
Base foo = new Child();
void action(Child c) { ... }
action(foo); // Perfectly correct code at runtime.
Other languages have safe assignment checks, but they also prevent some correct programs. You then have to add (unsafe/runtime checked) cast operators to tell the compiler that you know the program is safe. It's a trade-off where Dart has chosen to be permissive and avoid most casts.
Let's try to be polite and answer the question without any prejudice.
I think I understand what you expected and here my angle on what the error means:
You are invoking the method with the argument of type Base
The method is expecting an argument of type Child
The Child is not equal to the Base, neither is a subtype of it (as a fact it is the Child that is a subtype of the Base)
It is working as expected as it makes only sense to provide object of the expected type (or it's subtypes - specialisations).
Update:
After reading again your question I realised that you are pointing out that editor is not finding the type problem. I assume this is due to the point that Dart programs are dynamic and hence certain checks are not done before the runtime.
Hope it helps ;-)
Are there any other ways of changing a variable's type in a statically typed language like Java and C++, except 'casting'?
I'm trying to figure out what the main difference is in practical terms between dynamic and static typing and keep finding very academic definitions. I'm wondering what it means in terms of what my code looks like.
Make sure you don't get static vs. dynamic typing confused with strong vs. weak typing.
Static typing: Each variable, method parameter, return type etc. has a type known at compile time, either declared or inferred.
Dynamic typing: types are ignored/don't exist at compile time
Strong typing: each object at runtime has a specific type, and you can only perform those operations on it that are defined for that type.
Weak typing: runtime objects either don't have an explicit type, or the system attempts to automatically convert types wherever necessary.
These two opposites can be combined freely:
Java is statically and strongly typed
C is statically and weakly typed (pointer arithmetics!)
Ruby is dynamically and strongly typed
JavaScript is dynamically and weakly typed
Genrally, static typing means that a lot of errors are caught by the compiler which are runtime errors in a dynamically typed language - but it also means that you spend a lot of time worrying about types, in many cases unnecessarily (see interfaces vs. duck typing).
Strong typing means that any conversion between types must be explicit, either through a cast or through the use of conversion methods (e.g. parsing a string into an integer). This means more typing work, but has the advantage of keeping you in control of things, whereas weak typing often results in confusion when the system does some obscure implicit conversion that leaves you with a completely wrong variable value that causes havoc ten method calls down the line.
In C++/Java you can't change the type of a variable.
Static typing: A variable has one type assigned at compile type and that does not change.
Dynamic typing: A variable's type can change while runtime, e.g. in JavaScript:
js> x="5" <-- String
5
js> x=x*5 <-- Int
25
The main difference is that in dynamically typed languages you don't know until you go to use a method at runtime whether that method exists. In statically typed languages the check is made at compile time and the compilation fails if the method doesn't exist.
I'm wondering what it means in terms of what my code looks like.
The type system does not necessarily have any impact on what code looks like, e.g. languages with static typing, type inference and implicit conversion (like Scala for instance) look a lot like dynamically typed languages. See also: What To Know Before Debating Type Systems.
You don't need explicit casting. In many cases implicit casting works.
For example:
int i = 42;
float f = i; // f ~= 42.0
int b = f; // i == 42
class Base {
};
class Subclass : public Base {
};
Subclass *subclass = new Subclass();
Base *base = subclass; // Legal
Subclass *s = dynamic_cast<Subclass *>(base); // == subclass. Performs type checking. If base isn't a Subclass, NULL is returned instead. (This is type-safe explicit casting.)
You cannot, however, change the type of a variable. You can use unions in C++, though, to achieve some sort of dynamic typing.
Lets look at Java for he staitically typed language and JavaScript for the dynamc. In Java, for objects, the variable is a reference to an object. The object has a runtime type and the reference has a type. The type of the reference must be the type of the runtime object or one of its ancestors. This is how polymorphism works. You have to cast to go up the hierarchy of the reference type, but not down. The compiler ensures that these conditions are met. In a language like JavaScript, your variable is just that, a variable. You can have it point to whatever object you want, and you don't know the type of it until you check.
For conversions, though, there are lots of methods like toInteger and toFloat in Java to do a conversion and generate an object of a new type with the same relative value. In JavaScript there are also conversion methods, but they generate new objects too.
Your code should actally not look very much different, regardless if you are using a staticly typed language or not. Just because you can change the data type of a variable in a dynamically typed language, doesn't mean that it is a good idea to do so.
In VBScript, for example, hungarian notation is often used to specify the preferred data type of a variable. That way you can easily spot if the code is mixing types. (This was not the original use of hungarian notation, but it's pretty useful.)
By keeping to the same data type, you avoid situations where it's hard to tell what the code actually does, and situations where the code simply doesn't work properly. For example:
Dim id
id = Request.QueryString("id") ' this variable is now a string
If id = "42" Then
id = 142 ' sometimes turned into a number
End If
If id > 100 Then ' will not work properly for strings
Using hungarian notation you can spot code that is mixing types, like:
lngId = Request.QueryString("id") ' putting a string in a numeric variable
strId = 42 ' putting a number in a string variable