Your SlideShare is downloading. ×
Maintenance of Dynamically vs. Statically typed Languages
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Maintenance of Dynamically vs. Statically typed Languages

4,300
views

Published on

Published in: Technology

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
4,300
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
0
Comments
0
Likes
1
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. CPSC 543 Dynamically and Statically typed Languages June 10, 2009 Submitted By Muhammad Bandeali Submitted to Prof. Allen Holliday California State University, Fullerton i
  • 2. Table of Contents Introduction....................................................................................................................................1 Data Types......................................................................................................................................1 1.1 Sound types..........................................................................................................................1 1.2 Explicit/Implicit types .........................................................................................................1 1.2.1 Implicit type..................................................................................................................2 1.2.2 Explicit type..................................................................................................................2 1.3 Structural types ....................................................................................................................2 1.4 Duck typing..........................................................................................................................2 Static Programming Languages......................................................................................................3 Dynamic Programming Languages.................................................................................................3 Core Differences.............................................................................................................................3 Languages.......................................................................................................................................4 Static to Dynamic...........................................................................................................................4 Type Inference and Binding............................................................................................................5 Sub-typing......................................................................................................................................5 Generics..........................................................................................................................................5 Reflection.......................................................................................................................................6 Maintenance....................................................................................................................................7 12.1 Packages/Namespaces........................................................................................................7 12.2 Contracts.............................................................................................................................7 12.3 New Requirements Testing.................................................................................................8 12.4 Refactoring.........................................................................................................................8 12.5 Reengineering.....................................................................................................................9 12.6 Reuse..................................................................................................................................9 12.7 Documentation.................................................................................................................10 Language Selection.......................................................................................................................10 13.1 Capability.........................................................................................................................10 13.2 Productivity......................................................................................................................10 13.3 Costs ................................................................................................................................10 13.4 Expectations.....................................................................................................................10 13.5 Development....................................................................................................................10 13.6 Support.............................................................................................................................11 13.7 Deployment......................................................................................................................11 13.8 Performance......................................................................................................................11 13.9 Scalability.........................................................................................................................11 13.10 Reliability.......................................................................................................................11 13.11 Hardware........................................................................................................................11 13.12 Ramp-Up Time ..............................................................................................................11 Conclusion....................................................................................................................................12 References....................................................................................................................................14 i
  • 3. Introduction For the last few years a major change has been taking place; more and more people have been transitioning from static system languages such as Java, C#, C++ to dynamic languages such as Perl, Python, etc. Even though many people are participating in the change, not many know why is it really happening? Do dynamic languages handle many of the programming tasks better than static languages? The answer to this phenomenon is not so simple. Static system programming languages were designed for creating data structures and algorithms in a bottom up manner by hand typing in the most primitive variables to high level abstract classes. Dynamic languages are designed for gluing the already built set of powerful components on static system programming languages. Hence, both dynamic and static languages could be complementary [4]. Static languages strive to minimize surprises at the runtime and therefore fix any errors at compile time. But the nature of design and implementation of these languages places constraints on the user that narrows any choices. Dynamic languages on the other hand minimize those constraints and let the user do anything they want by eliminating bookkeeping, organizations and declarations. That makes them a perfect candidate for prototyping ideas. However, performance have been a key issue in dynamic languages, while static languages have overcome that challenge by compiler code optimizations and further optimizations by their respective virtual machines (platforms). This paper is geared towards defining, comparing and contrasting dynamically typed languages to statically typed languages in their most basic traits. It will also shed light on the different aspects of those language types that assist or hinder in maintaining software. Data Types A data type is an abstraction. It is the common property of a set of similar data objects. This property is used to define a representation for these objects in a program. Objects are said to “have” or to “be of” that type to which they belong [1]. In a statically typed language, every variable and parameter has a fixed type that is chosen by the programmer. Thus the type of each expression can be deduced, and each operation type-checked, at compile-time. Most high-level languages are statically typed [2]. In a dynamically typed language, only the values have fixed types. A variable or parameter has no designated type, but may take values of different types at different times. This implies that the operands must be type-checked immediately before performing an operation at run-time. [2] These are the different forms of type systems: 1.1 Sound types A sound type system is one that provides some kind of guarantee for the user. Many modern type systems like JAVA and C# are sound; but older languages like C often do not have sound type systems by design; their type systems are just designed to give warnings for common errors [20]. 1.2 Explicit/Implicit types Implicit / explicit types refer to the extent to which a compiler will reason about the static types of a language. ML and Haskell have implicit types, in that no type declarations are needed. Java and Ada have very explicit types, and one is constantly declaring the types of things [20]. 1
  • 4. 1.2.1 Implicit type // i is compiled as an int var i = 5; 1.2.2 Explicit type // i is declared as an int Int32 i = new Int32(5); 1.3 Structural types This distinction is generally applied to static types with sub-typing. Structural typing means a type is assumed whenever it is possible to validly assume it. It also allows you to be a bit more explicit about your expectations on an object. // In scala the object f passed in this method should have the method called getName() def test(f: { def getName(): String }) { log(f.getName) } 1.4 Duck typing If it walks like a duck and quacks like a duck, it must be a duck. This is a concept that has become popular recently. It refers to the dynamic type analogue of structural typing in which an object’s current set of methods and properties determines the valid semantics, rather than its inheritance from a particular class or implementation of a specific interface [21]. //pseudo code for the calculate method function calculate(a, b, c) => return (a+b)*c //calculate method called with different parameters example1 = calculate (1, 2, 3) example2 = calculate ([1, 2, 3], [4, 5, 6], 2) example3 = calculate ('apples ', 'and oranges', 3) //printing the output from above print to_string example1 9 print to_string example2 [1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6] print to_string example3 apples and oranges, apples and oranges, apples and oranges, As we can see, the language outputted the correct result as long as any of the input data types (int, string) supported the ‘+’ and ‘*’ operator. 2
  • 5. Static Programming Languages Static system languages were introduced as an alternative to assembly. In assembly languages, virtually every aspect of the machine is reflected in the program. Each statement represents a single machine instruction and programmers must deal with low-level details such as register allocation and procedure calling sequences. As a result, it is difficult to write and maintain large programs in assembly language [4]. Static languages are also known as strongly typed languages. These are called strong because they guarantee a certain runtime behavior before running the actual program. The compiler ensures that operands only function in a pre-destined way with the actual operations and the data objects never changes over the object’s lifespan. They also provide type safety. At compile or run time, the rejection of operations or function calls which attempt to disregard data types. In a more rigorous setting, type safety is proved about a formal language by proving progress and preservation [5]. Statically typed systems are necessarily also conservative. They can categorically prove the absence of some bad program behaviors, but they cannot prove their presence [9]. Dynamic Programming Languages Dynamic programming language is a term used broadly in computer science to describe a class of high-level programming languages that execute at runtime many common behaviors that other languages might perform during compilation, if at all. These behaviors could include extension of the program, by adding new code, by extending objects and definitions, or by modifying the type system, all during program execution [6]. Dynamically typed languages support dynamic allocation of storage objects whenever they are needed to contain an input value or the result of a computation. Identifiers are typeless in the sense that types are not permanently attached to them. Rather, a type tag is attached to each storage object when it is created. The storage object is then bound dynamically to an identifier. Thus the type that is indirectly associated with an identifier may change dynamically [1]. Dynamic language opponents argue that these languages cannot scale in terms of capacity handling, because they are “built on top of their own runtimes, which are arguably vastly inferior to the engineering effort that goes into the garbage collection facilities found in the JVM Hotspot or CLR implementations.” [7] Core Differences The following table illustrates major differences between static and dynamic languages in a nutshell that are in production today: Static Languages Dynamic Languages Earlier detection of programming mistakes at Detection is delayed until runtime compile-time Better documentation through type signatures Documentation possible through comments Compiler and runtime code optimizations Runtime code optimizations only Better IDE support for a at design time IDE support limited to few well-known developer experience, through features like languages, since it is considerably hard for IDE Refactor, Rename, etc. to assume types at design time. [13] Not too good for prototyping. Static typing is Well suited for prototyping due to its ad-hoc too rigid. nature, implicit and duck typing. Have to be compiled, deployed and forked Can usually be run from an interactive 3
  • 6. using the underlying platform. command prompt, increasing productivity. [13] Longer learning curve. Usually shorter learning curve. [13] Languages The following table houses few popular static and dynamic languages that are in lime light today: Statically Typed Languages Dynamically Typed Languages ML, Haskell, Java, C#, C++, etc Lisp, Scheme, Php, Ruby, Postscript, JavaScript, etc Static to Dynamic For illustration purposes, the following section would show the steps involved in transforming a traditional statically typed language, Java to a modern dynamic language, Ruby. The following method is taking an object of the class country and printing the output by calling a method on it, called capitalCity. private static void printCapitalOf(Country country) { System.out.println(country.capitalCity()); } public static void main(String[] args) { Country aus = new Australia(); Country jpn = new Japan(); printCapitalOf(aus); printCapitalOf(jpn); } The above could turn into a dynamically typed language, by leaving out the types, as follows: private static void printCapitalOf(Country country) { System.out.println(country.capitalCity()); } public static void main(String[] args) { Country aus = new Australia(); Country jpn = new Japan(); printCapitalOf(aus); printCapitalOf(jpn); } The same logic as above implemented in a dynamically typed language Ruby. As we can see, duck typing is being used to assume the type of the object country: 4
  • 7. def printCapitalOf(country) { print(country.capitalCity()) } def aus = new Australia(); def jpn = new Japan(); printCapitalOf(aus); printCapitalOf(jpn); Type Inference and Binding Type inference plays a big role in language performance and security. Dynamic typing implies that execution of the program is slowed down by implicit run-type checks, and also implies that every value must be tagged to identify its type in order to make these type checks possible. These time and space overheads are avoided in a statically typed language, because all type checks are performed at compile-time. Another feature of static typing is compile time security. Type errors are guaranteed to be detected by the compiler, rather than being left to the vagaries of testing [2]. Static binding happens when the body of a function is evaluated in the environment of the function definition, whereas dynamic binding occurs when the function body is evaluated in the environment of the function call. With static binding we can do this at compile-time; with dynamic binding we must delay this until run-time [2]. Sub-typing Static type systems can enforce higher-level modularity properties to protect the integrity of user defined abstractions, therefore enforcing disciplined programming. Violations of information hiding, such as directly accessing the fields of a data value whose representation is supposed to be abstract, are caught at compile time, instead of runtime in opposed to dynamic typed languages. In large-scale software composition, statically typed languages form the backbone of module languages used to package and tie together the components of large systems. Structuring larger systems in terms of modules with clear interfaces leads to a more abstract style of design, where interfaces are designed and discussed independently from their eventual implementations. More abstract thinking about interfaces generally leads to better design [9]. Generics Generic programming is a style of computer programming in which algorithms are written in terms of to-be-specified-later types that are then instantiated when needed for specific types provided as parameters. Generic programming refers to features of certain statically typed programming languages that allow some code to effectively circumvent the static typing requirements. Generic programming is commonly used to implement containers such as lists and hash tables and functions such as a particular sorting algorithm for objects specified in terms more general than a concrete type [14]. //The following is an interface which allows the methods to work on a type T unknown till runtime. interface IEnumerator<T> 5
  • 8. { bool MoveNext(); T Current { get; } } Generic classes and methods in statically typed languages combine reusability, type safety and efficiency in a way that dynamically typed languages cannot. By allowing types and programs to be parameterized by types, it becomes possible to create highly reusable libraries, while maintaining the benefits of compile-time type checking [11]. In combination with type-inference, usually writing types explicitly is unnecessary. In the example below, the compiler infers that variable xs has type IEnumerator<string>, and hence that variable x has type string: var xs = { yield return quot;Helloquot;; yield return quot;Worldquot;; }; foreach(x in xs) { Console.WriteLine(x); } In languages without generics a new sort function would require for any element type, and any kind of collection. Using generics a single function that sorts arbitrary collections of arbitrary element types void Sort<T>(...) and IComparer<T> would be enough. void Sort<T>(IComparer<T> comparer) { ... } Reflection Reflection is the ability to find out information about objects, the application details (assemblies), its metadata at run-time [15]. It is a special trait of statically typed languages. It is very powerful since it is a way of collecting and manipulating information present in application shared libraries and its metadata. Metadata contain all the Type information used by the application. The ability to obtain information at runtime also makes it even more advantageous [15]. It is a consensus that that the ability to dynamically eval strings as programs is what sets dynamic languages apart from static languages. But, in reality any language that can dynamically load class loaders in some form or another, either via DLLs, shared libraries or dynamic class loading, has the ability to do eval, even though eval is considered a poor man’s substitute for higher-order functions. Instead of passing around a function and call it, they pass around a string and eval it [12]. 6
  • 9. Maintenance 12.1 Packages/Namespaces Namespaces are well-defined boundaries that are used to organize code in a unique fashion. Every statically programming language supports various forms of namespaces, be they as fine- grained as the context of a procedure or a block, or as coarse-grained as packages or modules. Namespaces provide a consistent way of grouping related source code together in a pre defined fashion. This makes code cleaner, streamlined and easier to maintain. In most, if not all statically typed languages namespaces are first-class citizens. Namespaces can be used to model objects, classes, meta-objects, software components, modules, and a variety of compositional abstractions, such as wrappers and mix-in layers. Furthermore, namespaces lend themselves well to formal specification using standard semantic modeling techniques, which can form the basis for reasoning about language constructs [22]. Dynamic languages have second class namespaces. In languages like JavaScript, most global functions that are part of the language are in the global namespace. These class names have to be organized in ways that there are no conflicts between two classes of same names in two files. This type of distinction is usually done by company_namespace_class { … } Good namespaces could aid quite a bit in development and maintenance activities. In languages where namespaces are not available, the above technique has to be used; otherwise there is a good possibility of method or class name confusion. Namespaces also help when reading, understanding, restructuring or reengineering software. 12.2 Contracts In human affairs, contracts are written between two parties when one of them performs some task for the other. Each party expects some benefits from the contract, and accepts some obligations in return. Contracts in object oriented languages, facilitates the concept of inheritance, which makes software more maintainable by avoiding redundancy and sharing structures and behaviors. Statically typed languages provide a very solid means for contracts between elements and provide a standard way to document them [3]. A method with three arguments, in Java for example would only and only accept the objects it is expecting in a well- defined sequence. However, static typing could provide a false sense of safety, since it can only prove the absence of certain errors statically at compile time. Even if a program does not contain any static type-errors, it does not imply that you will not encounter any unwanted runtime errors. Dynamic languages being susceptive to runtime surprises forces developers to put in place very strict unit testing frameworks therefore eliminating any chances for run-time contract nightmares. In a dynamic language like PHP, contracts could be loose; depending on how a method is written, it could accept a combination of parameters based on their default values in the method. The same method could have multiple contracts, therefore unit tests should be written for each type of method usage. 7
  • 10. 12.3 New Requirements Testing Dynamic languages could be more productive and easier to use than static languages. However, making code easier to write does not necessarily yield long term gains. In bigger projects, the lack of language formality can be detrimental to the maintenance bottom line. That includes adding new features to the system. Unit testing helps but they are a form of sampling and as such, they tend to suffer from selection bias. Static languages, while limited in what they can accomplish right off the bat, have a 100% success rate for what is type checked and covered. Unit tests on the other hand have a failure rate due to limited input/output/state coverage and should not be considered as a replacement for basic error checking but as a supplement to it. New features are far easier to add in dynamic languages than static, however both paradigms need strict and well to do unit tests to verify and validate the new features/requirements. The type of issues that should be cared for while testing dynamic languages are: • Order of tests in case of interpreters since they interpret code line by line • Tests cannot be run in parallel due to global state variables and their sharing • New tests can break old tests by changing global state variables Even though in static languages like Java, method definitions could be replaced at runtime using a Class Loaders and Aspect Oriented Programming frameworks; this is not how Java is used in the real world and therefore there are not many unknown cases that have to be brought into perspective when unit testing while adding new features. Usually unit tests that cover 90% or more validate the design. 12.4 Refactoring Refactoring is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior. Its heart is a series of small behavior preserving transformations. Each transformation (called a ‘refactoring’) does little, but a sequence of transformations can produce a significant restructuring. Since each refactoring is small, it’s less likely to go wrong. The system is also kept fully working after each small refactoring, reducing the chances that a system can get seriously broken during the restructuring [10]. Refactoring is usually aided by very sophisticated editors. Few of them are eclipse and IntelliJ. Static typing helps these editors navigate between modules. A well-factored, well-tested application spreads each feature over several layers and unites them all by type. These editors can easily bounce between related tests, views, controllers, and models, simply by tracking the types they use. Dynamic languages however, don’t have a notion of types at development time. Hence, any IDE would have a hard time navigating through code. Here are few ways that dynamic languages could be modeled for refactoring. Using PHP interpreter and running the code [18]. In order to find all occurrences of a function, for example few work-around have been proposed like renaming the original function name and create a function with the old name that adds the caller to a list and then modifying the callers to call the renamed functions. At the end delete the function with the old name. Refactoring of dynamic languages depend on a 100% coverage test suite so each and every possible path in the program’s flow could be covered. 8
  • 11. 12.5 Reengineering Reengineering software is defined as “reorganizing and modifying existing software system(s) to make them more maintainable by re-structuring or re-writing part or all of a legacy system without changing its functionality.” [17] It is applicable where few or all of the components or modules of a larger system require frequent maintenance. Reengineering plays a big role in adaptive, perfective and preventive change. In order to implement a new version of a software system, it is crucial to obtain its architecture and design if not already present. This information is required for the identification of all the entities that have some relation with the evolving part of the software. In addition, we need it for providing new source code that will fit in the existing system. Recovering the design of an application has to be done by using both static and dynamic information. Static information describes the structure of the software as it is written in the source code, while dynamic information describes what is really happening at runtime. Statically typed languages provide a very comprehensive set of static information, while dynamically typed languages do not reveal much at development time. Therefore, it could be possible that structural information would show that two classes are just a bit related, as there could only be one method call from one class to the other. However, it dynamic information could show that the same call occurs continuously when running the application, making the two classes very related. 12.6 Reuse Reusability is the likelihood a segment of source code that can be used again to add new functionalities with slight or no modification. Reusable modules and classes reduce implementation time, increase the likelihood that prior testing and use has eliminated bugs and localizes code modifications when a change in implementation is required. Martin Fowler says: “Any fool can write code that a computer can understand. Good programmers write code that humans can understand.” However, for software to be reusable, it must be usable in a variety of contexts. An important attribute of reusability at the code level is genericity. Generic software can operate, unmodified, on a variety of object types. Dynamically typed languages provide genericity naturally: //Python function that determines the smallest of whatever it receives as a parameter def smallest(stuff): assert len(stuff) > 0 theMin = stuff[0] for x in stuff[1:]: if x < theMin: theMin = x return theMin This function can be called with any type of sequence: smallest([1,2,3]) 1 smallest(quot;cbaquot;) a 9
  • 12. The only constraints on the parameter stuff are that it is an iterable entity and that its contained objects support the less than operator [16]. Hence, smallest is a generic function and is very easily reusable in variety of applications. Statically typed languages cannot have such flexibility out of the box [16], but that is changing. Modern languages such as Java and C# now have generic programming capability while retaining the safety and efficiency that comes with static type checking. 12.7 Documentation Statically typed languages could prove to be easier when reading programs. Because documentation is not just about comments. It is about everything that helps people understand software. Static type systems build ideas that help explain a system and what it does. They capture information about the inputs and outputs of various functions and modules. The type declarations in procedure headers and module interfaces constitute a form of documentation, giving useful hints about behavior. Moreover, unlike descriptions embedded in comments (in dynamically typed languages), this form of documentation cannot become outdated, since it is checked during every run of the compiler. This role of types is particularly important in module signatures [9]. This is exactly the set of information needed in documentation. Clearly, if all of this information is written in comments, there is a pretty good chance it will eventually become out of date. If this information is written in identifier names, it will be nearly impossible to fit it all in. Type information is a very nice place to keep this information. After all it is better to have self-documenting code than code that needs a lot of comments. Most languages with static type systems have type inference, which is directly analogous to self- documenting code. Information about the correct way to use a piece of code is extracted from the code itself, but then verified and presented in a convenient format. It is this type of documentation that doesn’t need to be maintained or even written, but is available on demand even without reading the source code. Language Selection There is no universally superior language, but language selection has long term implications including those of business capability, cost and technology lock-in. So how should a team choose a language for its next “big” project? According to Dhananjay Nene [19], these are the dimensions of selection of a programming language: 13.1 Capability What the languages can and cannot do? 13.2 Productivity How efficiently can one write programs using the language? 13.3 Costs What are the costs of using the language? 13.4 Expectations Can the language deliver on expectations? What is the cost of delivering on expectations? 13.5 Development 10
  • 13. How long does it take to write and debug code? If skills are not present, what is the cost and time required to build them? 13.6 Support What is the support structure available from community? 13.7 Deployment What are the hardware and deployment costs? 13.8 Performance How fast can the programs run for given hardware? 13.9 Scalability How cost effectively can the software be scaled to handle higher loads? 13.10 Reliability How fault tolerant can the resultant software be? 13.11 Hardware Ease of cloud/virtualized hosting; hosting requirements for small vs. medium vs. big apps. 13.12 Ramp- Up Time How easily can you get online? As things stand, today’s programmer has a wide range of languages to choose from but none of them is perfect for every job. However, a programmer who has a knowledge of static (usually for back-end) and dynamic languages (usually for front-end) probably does not need anything beyond those tools. The following is the breakdown of languages currently being part of the O’Reilly’s code zoo, [24] which is one view point of various languages being in use today. As we can see, dynamic languages like Python, PHP, Ruby, and Perl seem to have taken down almost 50% of the pie chart with C, C# and C++ taking down a large majority of the rest. It is also interesting to note that Java, a major language is missing from this pie chart. 11
  • 14. Conclusion Maintenance is an ongoing activity in the world of software. Therefore, a lot of effort should go into choosing the right languages and tools for a new software application. The languages and tools usually stay with the application for its entire lifetime. The creators of the application usually leave the project after development due to what I call software maintenance syndrome. Maintenance programmers could then be overwhelmed by the complexity of the source code. After a number of modifications, design documents could be outdated or non-existent. They just have to do it hoping the bugs disappear before the deadline. Despite of the fact that maintenance requires experience and skills, novice programmers are often assigned to this time-consuming task, making the situation worse. In many ways, we are still in the dark ages of programming language design. Consider, for example, the great innovations in programming languages over the past fifty years. To a large extent, most of these innovations were achieved in the 1950s and 1960s. It is harder and harder to identify significant contributions over the past 20 years. It is also hard to identify truly radical language designs in recent years [23]. The software industry is faced with new challenges posed 12
  • 15. by enormous advances in hardware and internet technology. Silicon chips cannot go up in performance and clock cycle anymore; we therefore need language features like inherit concurrency and multi threading. The truth is there is no silver bullet; if I want to drive on the race track, my regular car wouldn’t fit the profile, but a good performance car with special suspension, brakes and tires would, in which case I should be ready to pay the price for constant barrage of new tires and brake pads. 13
  • 16. References [1] Alice E. Fischer, Frances S. Grodzinsky. “The Anatomy of Programming Languages”. Prentice Hall. January 1993. [2] Watt, David. “Programming Language Concepts and Paradigms”. Prentice Hall. May 1990. [3] Building bug-free O-O software: An introduction to Design by Contract(TM). http://archive.eiffel.com/doc/manuals/technology/contract/page.html [4] Ousterhout , John.“Scripting: Higher Level Programming for the 21st Century”. Sun Microsystems Laboratories. [5] http://en.wikipedia.org/wiki/Strongly- typed_programming_language#Meanings_in_computer_literature [6] http://en.wikipedia.org/wiki/Dynamic_programming_language [7] http://sadekdrobi.com/2008/02/09/scalability-dynamic-and-static-programming-languages/ [8] Erik Meijer, Peter Drayton. “Static Typing Where Possible, Dynamic Typing When Needed: The End of the Cold War Between Programming Languages”. Microsoft Corporation. [9] Pierce, Benjamin. “Types and Programming Languages”. The MIT Press.2002 [10] Fowler, Martin. http://www.refactoring.com [11] D. A. Schmidt. quot;The Structure of Typed Programming Languagesquot;. MIT Press. 1994. [12] D. Ungar and R. B. Smith. “Self: The Power of Simplicity”. In Proceedings OOPSLA’87. 1987. [13] Visual Numerics, Inc. “Components for Analytic Prototyping and Production Deployment”. February 2009 [14] http://en.wikipedia.org/wiki/Generic_programming [15] Code Source. http://www.codersource.net/published/view/291/reflection_in.aspx [16] Allison, Chuck. “Designing Reusable Software”. StickyMinds. [17] Sommerville,Ian. “Software Engineering”. Addison Wesley; 6 edition. August 21, 2000. [18] Don Roberts, John Brant, Ralph Johnson. “A Refactoring Tool for Smalltalk”. [19] Nene, Dhananjay. “Programming Language Selection”. A PuneTech event. March 28, 2009. [20] Smith, Chris. http://www.pphsg.org/cdsmith/types.html. [21] http://en.wikipedia.org/wiki/Duck_typing [22] Oscar Nierstrasz, Alexandre Bergel, Marcus Denker, St´ephane Ducasse, Markus G¨alli, and Roel Wuyts. “On the Revival of Dynamic Languages”. Software Composition Group, University of Bern. [23] Black, Greg. “Programming Language Selection”. [24] http://lesscode.org/2005/08/04/code-zoo-language-breakdown/ 14