Paradigm | Object oriented |
---|---|
Designed by | Francisco Ortin [1] |
Developer | Computational Reflection research group [2] of the University of Oviedo |
First appeared | 2007 |
Stable release | 2.2.1 / 11 May 2022 |
Typing discipline | Hybrid static and dynamic typing, gradual typing, strong, inferred |
Implementation language | C# |
Platform | Common Language Infrastructure (.NET Framework) |
License | MIT License [3] |
Website | reflection |
Major implementations | |
C# | |
Influenced by | |
C#, OCaml, StrongTalk, Boo |
StaDyn is an object-oriented general-purpose programming language for the .NET platform that supports both static and dynamic typing in the same programming language.
The StaDyn compiler gathers type information for the dynamically typed code. That type information is used to detect type errors at compilation time and to perform significant optimizations. For that purpose, it provides type reconstruction (inference), flow-sensitive types, union and intersection types, constraint-based typing, alias analysis and method specialization. Its first prototype appeared in 2007, as a modification of C# 3.0. Type inference was supported by including var
as a new type, unlike C#, which only offers var
to define initialized local variables. Flow-sensitive types of var
references are inferred by the compiler, providing type-safe duck typing. [4] When a more lenient approach is required by the programmer, the dynamic
type could be used instead of var
. Although type inference is still performed, dynamic
references behave closer to those in dynamic languages.
StaDyn is designed by Francisco Ortin [1] from the University of Oviedo. The language has been implemented by different members of the Computational Reflection research group, [2] including Miguel Garcia, Jose Baltasar García Perez-Schofield and Jose Quiroga, besides Francisco Ortin.
The name StaDyn is a portmanteau of static and dynamic, denoting its aim to provide the benefits of both static and dynamic typing.
Just like dynamic languages, variables may hold different types in the same scope:
usingSystem;classProgram{publicstaticvoidMain(){Console.Write("Number: ");varage=Console.In.ReadLine();Console.WriteLine("Digits: "+age.Length);age=Convert.ToInt32(age);age++;Console.WriteLine("Happy birthday, you are "+age+" years old now.");intlength=age.Length;// * Compiler error}}
The age
variable is first inferred as string, so it is safe to get its Length
property. Then, it holds an integer, so age++
is a valid expression. The compiler detects an error in the last line, since Length
is no longer provided by age
.
The generated code does not use a single Object
variable to represent age, but two different variables whose types are string and int. This is achieved with a modification of the algorithm to compute the SSA form. [5] This makes the generated code to be more efficient, since runtime type conversions are not required.
var
and dynamic
variables can hold flow-sensitive types:
usingSystem;classProgram{publicstaticvoidMain(String[]args){varexception;if(args.Length>0)exception=newApplicationException("An application exception.");elseexception=newSystemException("A system exception.");Console.WriteLine(exception.Message);}}
It is safe to get the Message
property from exception
because both ApplicationException
and SystemException
provide that property. Otherwise, a compiler error is shown. In this way, StaDyn provides a type-safe static duck-typing system.
In the following program:
usingSystem;classProgram{publicstaticvoidMain(String[]args){varexception;switch(args.Length){case0:exception=newApplicationException("An application exception.");break;case1:exception=newSystemException("A system exception.");break;default:exception="This is not an exception.";break;}Console.WriteLine(exception.Message);// * Compiler error with var, but not with dynamicConsole.WriteLine(exception.Unknown);// * Compiler error}}
The Message
property is not provided by String
, so a compiler error is shown for exception.Message
. However, if we declare exception
as dynamic
, the previous program is accepted by the compiler. dynamic
is more lenient than var
, following the flavor of dynamic languages. However, static type checking is still performed. This is shown in the last line of code, where the compiler shows an error for exception.Unknown
even if exception
is declared as dynamic
. This is because neither of the three possible types (ApplicationException
, SystemException
and String
) supports the Unknown
message. [6]
Although dynamic
and var
types can be used explicitly to obtain safer or more lenient type checking, the dynamism of single var
references can also be modified with command-line options, XML configuration files and a plugin for Visual Studio. [7]
var
and dynamic
types can be used as object fields:
classWrapper{privatevarattribute;publicWrapper(varattribute){this.attribute=attribute;}publicvarget(){returnattribute;}publicvoidset(varattribute){this.attribute=attribute;}}classTest{publicstaticvoidMain(){stringaString;intaInt;Wrapperwrapper=newWrapper("Hello");aString=wrapper.get();aInt=wrapper.get();// * Compiler errorwrapper.set(3);aString=wrapper.get();// * Compiler erroraInt=wrapper.get();}}
The Wrapper
class can wrap any type. Each time we call the set
method, the type of attribute
is inferred as the type of the argument. Each object has a potentially different type of attribute
, so its type is stored for every single instance rather than for the whole class. In this way, the two lines indicated in the code above report compilation errors. A type-based alias analysis algorithm is implemented to support this behavior. [8]
Let's analyze the following method:
publicstaticvarupper(varparameter){returnparameter.ToUpper();}
The type of parameter
and the function return value are inferred by the compiler. To that aim, a constraint is added to the type of the upper
method: the argument must provide a ToUpper
method with no parameters. At each invocation, the constraint will be checked. Additionally, the return type of upper
will be inferred as the return type of the corresponding ToUpper
method implemented by the argument. [9]
The programmer may use either var
or dynamic
to declare parameter
, changing the way type checking is performed upon method invocation. Let's assume that the argument passed to upper
holds a flow-sensitive type (e.g., the ApplicationException
, SystemException
or String
exception
variable in the code above). With var
, all the possible types of the argument must provide ToUpper
; with dynamic
, at least one type must provide ToUpper
.
The type information gathered by StaDyn is used to perform significant optimizations in the generated code: [10] the number of type inspections and type casts are reduced, reflection is avoided, frequent types are cached, and methods with constraints are specialized. The point of all the optimizations is to reduce the number of type-checking operations performed at runtime, which is the main performance penalty of most dynamic languages. Many of those type checks are undertaken earlier by the StaDyn compiler. A detailed evaluation of the runtime performance of StaDyn is detailed in. [4]
In computer programming, a type system is a logical system comprising a set of rules that assigns a property called a type to every term. Usually the terms are various language constructs of a computer program, such as variables, expressions, functions, or modules. A type system dictates the operations that can be performed on a term. For variables, the type system determines the allowed values of that term.
Type inference, sometimes called type reconstruction, refers to the automatic detection of the type of an expression in a formal language. These include programming languages and mathematical type systems, but also natural languages in some branches of computer science and linguistics.
In computer science, boxing is the transformation of placing a primitive type within an object so that the value can be used as a reference. Unboxing is the reverse transformation of extracting the primitive value from its wrapper object. Autoboxing is the term for automatically applying boxing and/or unboxing transformations as needed.
In computer science, type safety and type soundness are the extent to which a programming language discourages or prevents type errors. Type safety is sometimes alternatively considered to be a property of facilities of a computer language; that is, some facilities are type-safe and their usage will not result in type errors, while other facilities in the same language may be type-unsafe and a program using them may encounter type errors. The behaviors classified as type errors by a given programming language are usually those that result from attempts to perform operations on values that are not of the appropriate data type, e.g., adding a string to an integer when there's no definition on how to handle this case. This classification is partly based on opinion.
This article compares two programming languages: C# with Java. While the focus of this article is mainly the languages and their features, such a comparison will necessarily also consider some features of platforms and libraries.
The syntax of Java is the set of rules defining how a Java program is written and interpreted.
C# is a general-purpose high-level programming language supporting multiple paradigms. C# encompasses static typing, strong typing, lexically scoped, imperative, declarative, functional, generic, object-oriented (class-based), and component-oriented programming disciplines.
Platform Invocation Services, commonly referred to as P/Invoke, is a feature of Common Language Infrastructure implementations, like Microsoft's Common Language Runtime, that enables managed code to call native code.
Oxygene is a programming language developed by RemObjects Software for Microsoft's Common Language Infrastructure, the Java Platform and Cocoa. Oxygene is based on Delphi's Object Pascal, but also has influences from C#, Eiffel, Java, F# and other languages.
Haxe is a high-level cross-platform programming language and compiler that can produce applications and source code for many different computing platforms from one code-base. It is free and open-source software, released under an MIT License. The compiler, written in OCaml, is released under the GNU General Public License (GPL) version 2.
C++11 is a version of a joint technical standard, ISO/IEC 14882, by the International Organization for Standardization (ISO) and International Electrotechnical Commission (IEC), for the C++ programming language. C++11 replaced the prior version of the C++ standard, named C++03, and was later replaced by C++14. The name follows the tradition of naming language versions by the publication year of the specification, though it was formerly named C++0x because it was expected to be published before 2010.
Generics are a facility of generic programming that were added to the Java programming language in 2004 within version J2SE 5.0. They were designed to extend Java's type system to allow "a type or method to operate on objects of various types while providing compile-time type safety". The aspect compile-time type safety required that parametrically polymorphic functions are not implemented in the Java virtual machine, since type safety is impossible in this case.
Anonymous types are a feature of C# 3.0, Visual Basic .NET 9.0, Oxygene, Scala and Go that allows data types to encapsulate a set of properties into a single object without having to first explicitly define a type. This is an important feature for the SQL-like LINQ feature that is integrated into C# and VB.net. Since anonymous types do not have a named type, they must be stored in variables declared using the var
keyword, telling the C# compiler to use type inference for the variable. The properties created are read-only in C#, however, they are read-write in VB.net.
This article describes the syntax of the C# programming language. The features described are compatible with .NET Framework and Mono.
Cobra is a discontinued general-purpose, object-oriented programming language. Cobra is designed by Charles Esterbrook, and runs on the Microsoft .NET and Mono platforms. It is strongly influenced by Python, C#, Eiffel, Objective-C, and other programming languages. It supports both static and dynamic typing. It has support for unit tests and contracts. It has lambda expressions, closures, list comprehensions, and generators.
In computer science, manifest typing is explicit identification by the software programmer of the type of each variable being declared. For example: if variable X is going to store integers then its type must be declared as integer. The term "manifest typing" is often used with the term latent typing to describe the difference between the static, compile-time type membership of the object and its run-time type identity.
The programming language C# version 3.0 was released on 19 November 2007 as part of .NET Framework 3.5. It includes new features inspired by functional programming languages such as Haskell and ML, and is driven largely by the introduction of the Language Integrated Query (LINQ) pattern to the Common Language Runtime. It is not currently standardized by any standards organisation.
Nemerle is a general-purpose, high-level, statically typed programming language designed for platforms using the Common Language Infrastructure (.NET/Mono). It offers functional, object-oriented, aspect-oriented, reflective and imperative features. It has a simple C#-like syntax and a powerful metaprogramming system.
Swift is a high-level general-purpose, multi-paradigm, compiled programming language created by Chris Lattner in 2010 for Apple Inc. and maintained by the open-source community. Swift compiles to machine code and uses an LLVM-based compiler. Swift was first released in June 2014 and the Swift toolchain has shipped in Xcode since Xcode version 6, released in September 2014.
Nim is a general-purpose, multi-paradigm, statically typed, compiled high-level system programming language, designed and developed by a team around Andreas Rumpf. Nim is designed to be "efficient, expressive, and elegant", supporting metaprogramming, functional, message passing, procedural, and object-oriented programming styles by providing several features such as compile time code generation, algebraic data types, a foreign function interface (FFI) with C, C++, Objective-C, and JavaScript, and supporting compiling to those same languages as intermediate representations.