Why Kotlin, why should you choose Kotlin?

Why should you choose Kotlin?

Programming language design is an evolutionary path from meeting machine needs to meeting programmer needs.

We have outlined the historical development of programming languages ​​so you can understand where Kotlin fits and why you should learn it. This atom introduces some topics, if you are a novice, it may seem too complicated now. You can skip this atom at any time after you read more books.

The language designer invented a programming language and implemented it as an interpreter or compiler , which are also programs. The implementer is usually the language designer at least initially.

Early languages ​​focused on hardware limitations. As computer functions increase, newer languages ​​will shift to more complex programming that focuses on reliability. These languages ​​can also start selecting functions based on the psychology of programming.

Each programming language is a collection of experiments. Historically, programming language design has always been a series of guesses and assumptions about enabling programmers to increase their productivity. Some of these experiments failed, some were successful, and some were very successful.

We learn from experiments in each new language. The problems solved by some languages ​​turned out to be accidental rather than fundamental, or the environment changed (faster processors, cheaper memory, new understanding of programming and languages), and the problem became less important , And even become irrelevant. If these ideas are outdated and the language is not developed, it will disappear from use.

The first programmers worked directly with numbers representing the machine instructions of the processor. This method produced many errors and created assembly language to replace numbers with mnemonic opcodes ( words that programmers can remember and read more easily and many other useful tools). However, there is still a one-to-one correspondence between assembly language instructions and machine instructions, and programmers must write every line of assembly code. In addition, each computer processor uses its own unique assembly language.

It is very expensive to develop programs in assembly language. High-level languages ​​help solve this problem by providing a level of abstraction away from low-level assembly languages. Here, we provide the history of selected languages ​​to choose their influence on the languages ​​that follow. All these languages ​​eventually inspired Kotlin's design, and sometimes even became a role model for not doing things.

FORTRAN:FORMULA TRANSATION(1957年)

Designed for use by scientists and engineers, Fortran's goal is to make coding of other programs easier. Fine-tuned and tested Fortran libraries are still in use today, but they are usually "wrapped" so that they can be called from other languages.

LISP: LISt processor (1958)

LISP is not specific to applications, but embodies basic programming concepts. It is the language of computer scientists and the first functional programming language (you will learn functional programming in this book). The trade-off between its functionality and flexibility is efficiency: LISP is usually too expensive to run on early machines, and it is only in the last few decades that machines have become fast enough to make the use of LISP popular again. For example, the GNU Emacs editor is written entirely in LISP and can be extended with LISP.

ALGOL: Algorithmic Language (1958)

It can be said that this was the most influential language in the 1950s, because the grammar it introduced still exists in many subsequent languages. For example, C and its derivatives are "ALGOL-like" languages.

COBOL: COmmon Business Oriented Language (1959)

Designed for business, financial and management data processing. It has an English-like grammar and is designed to be self-explanatory and highly readable. Although this intent usually fails-COBOL is famous for errors introduced during misplacement-the US Department of Defense forced the widespread adoption of mainframe computers, and the system is still running today (and requires maintenance).

BASIC: General Symbol Explanation Code for Beginners (1964)

This is one of the early attempts to make programming accessible. Although very successful, its functions and grammar are limited, so it is only partially useful for people who need to learn more complex languages. It is primarily an interpreted language, which means that to run it, you need the original code of the program. Nevertheless, many useful programs are written in BASIC, especially as a scripting language for Microsoft "Office" products. People even regard BASIC as the first "open" programming language because people have made many changes to it.

Simula 67, the original object-oriented language (1967)

A simulation usually involves many "objects" blending together. Different objects have different characteristics and behaviors. The languages ​​that existed at the time were awkward when used for simulation, so Simula (another "ALGOL-like" language) was developed to provide direct support for creating simulation objects. It turns out that these ideas are also useful for general programming, which is the origin of object-oriented (OO) languages.

Pascal (1970)

Pascal improves compilation speed by restricting the language, so it can be implemented as a single pass compiler . This language forces programmers to structure their code in a specific way, and imposes some clumsy and incomprehensible constraints on program organization. As processors become faster, memory becomes cheaper, and compiler technology becomes better, the impact of these constraints becomes too expensive.

The implementation of Pascal comes from Borland's Turbo Pascal, which initially worked on CP/M machines, then moved to the early MS-DOS (the predecessor of Windows), and later evolved into the Delphi language of Windows. By storing everything in memory, Turbo Pascal compiles at lightning speed on very low-power machines, which greatly improves the programming experience. Its creator Anders Hejlsberg later continued to design C# and TypeScript.

Pascal inventor Niklaus Wirth created the later languages: Modula, Modula-2 and Oberon. As the name suggests, Modula is committed to dividing the program into modules for better organization and faster compilation. Most modern languages ​​support separate compilation and some form of module system.

C(1972)

Although the number of high-level languages ​​continues to increase, programmers are still writing assembly language. This is usually called system programming because it is done at the operating system level, but it also includes embedded programming of dedicated physical devices. Not only is this arduous and expensive (Bruce started his career, writing assembly language for embedded systems), but it is not portable-assembly language can only run on the processor it was written for. C is designed as a "high-level assembly language", which is still close enough to the hardware you rarely need to write assembly language. More importantly, a C program can run on any processor with a C compiler. C decouples the program from the processor, thus solving a huge and expensive problem. As a result, the productivity of previous assembly language programmers in the C language may be greatly improved. C is so effective that recent languages ​​(especially Go and Rust) are still trying to use it for system programming.

Small talk (1972)

Designed to be purely object-oriented from the beginning, Smalltalk, as an experimental platform and a platform for demonstrating rapid application development, has greatly promoted the development of object-oriented and language theory. However, it was created when the language was still proprietary, and the entry price of the Smalltalk system could be as high as thousands of dollars. It is explained, so you need a Smalltalk environment to run the program. The open source Smalltalk implementation did not appear until the development of the programming world. Smalltalk programmers benefit a lot from future OO languages ​​(such as C++ and Java).

C++: Better C with Objects (1983)

Bjarne Stroustrup created C++ because he wanted a better C language and wanted to support the object-oriented construction he experienced while using Simula-67. Bruce has served as a member of the C++ Standards Committee for the first eight years and has written three books on C++, including "C++ Thinking" .

Backward compatibility with C is the basic principle of C++ design, so C code can almost be compiled in C++ without changes. This provides an easy migration path-programmers can continue to program in C, reap the benefits of C++, and slowly try out C++ features while still remaining productive. Most criticisms of C++ can be traced to the constraints of backward compatibility with C.

One of C's problems is memory management . The programmer must first acquire memory, then use that memory to run operations, and then release the memory. Forgetting to release memory is called a memory leak , which can cause the available memory to run out and cause the process to crash. The initial version of C++ made some innovations in this regard and worked with the constructor to ensure proper initialization. A later version of the language has made significant improvements in memory management.

Python: Friendly and flexible (1990)

Python designer Guido Van Rossum created the language based on the inspiration of "programming for everyone". His cultivation of the Python community makes it the friendliest and most supportive community in the programming field. Python is one of the earliest open source languages ​​and can be implemented on almost every platform including embedded systems and machine learning. Its dynamics and ease of use make it ideal for automating small repetitive tasks, but its functions also support the creation of large and complex programs.

Python is a true "grassroot" language; it has never had a company to promote it, and the attitude of its fans has never been to promote the language, but to help anyone who wants to learn it. The language continues to improve steadily, and its popularity has soared in recent years.

Python may be the first mainstream language that combines functionality and OO programming. It predates Java 's automatic memory management using garbage collection (you usually don't have to allocate or release memory yourself), and it can run programs on multiple platforms.

Haskell: Pure Functional Programming (1990)

Inspired by the proprietary language Miranda (1985), Haskell was created as an open standard for purely functional programming research, although it has also been used in products. Haskell's grammar and ideas have influenced many subsequent languages, including Kotlin.

Java: Virtual Machine and Garbage Collection (1995)

The task of James Gosling and his team is to write code for TV set-top boxes. They decided not to like C++ and not to create a box, but to create the Java language. Sun Microsystems provided a huge market impetus for free languages ​​(still a new idea at the time), trying to control the emerging Internet landscape.

The perceived time window of the Internet dominating time has put a lot of pressure on the Java language design, which has led to many defects (" Thinking in Java " book clarifies these defects, so readers are prepared to deal with these defects). Although Java has achieved great success, an important design goal of Kotlin is to fix Java's flaws so that programmers can improve their work efficiency. Currently, the main developer of Java, Oracle's Brian Goetz, has made surprisingly amazing improvements in Java despite inheriting many restrictions.

The success of Java comes from two innovative features: virtual machine and garbage collection . These languages ​​can be provided in other languages, such as LISP, Smalltalk and Python with garbage collection function, while UCSD Pascal runs on a virtual machine, but they have never been considered practical for mainstream languages. Java has changed this, and doing so greatly improves the efficiency of programmers.

The virtual machine is an intermediate layer between the language and the hardware, so the language does not have to generate machine code for a specific processor. It only needs to generate an intermediate language that runs on a virtual machine. Virtual machines require processing power. Before Java, virtual machines were considered impractical. In the Java Virtual Machine (JVM), the slogan that caused Java is "write once, run everywhere". In addition, other languages ​​can be easily developed for JVM. For example, Groovy (a scripting language similar to Java) and Clojure (a LISP version).

Garbage collection solves the problem of forgetting to release memory. Sometimes it is difficult to know when a certain storage is no longer in use. Due to a memory leak, the project has been severely delayed or even cancelled. Although garbage collection appeared in some previous languages, until Java proved it feasible, garbage collection was considered to generate unacceptable overhead.

JavaScript: Use Java only in the name (1995)

The original web browser just copied and displayed the page from the web server. The proliferation of web browsers has become a new programming platform that requires language support. Java wants to be this language, but it is too awkward for this job. JavaScript started with LiveScript and was built into NetScape Navigator, one of the earliest web browsers. Renaming it to JavaScript is NetScape's marketing strategy, because the language has only similarities with Java.

With the rise of the Web, JavaScript has become extremely important. However, the behavior of JavaScript is so unpredictable that Douglas Crockford (Douglas Crockford ) wrote a book with the mocking title JavaScript (Good Parts) in which he demonstrated all the problems of the language in order to program The staff can avoid them. Subsequent improvements by the ECMAScript committee changed JavaScript so completely that the original JavaScript programmers could not recognize it. Now, it is considered a stable and mature language.

Scale: Scalable (2003)

Martin Odersky created Scala to run on the Java virtual machine: carrying the work done on the JVM, interacting with Java programs, and might think that it might replace Java. As a researcher, Odersky and his team use Scala as a platform for experimenting language features, especially features not included in Java.

These experiments are instructive, and many of the findings usually enter Kotlin in improved form. For example, the function of redefining operators (such as used +in special circumstances) is called operator overloading . It is included in C++, but not in Java. Scala adds operator overloading, but it also allows you to invent new operators by combining any sequence of characters. This usually produces messy code. Kotlin includes a limited form of operator overloading, but you can only overload operators that already exist.

Scala is also a hybrid of object functions, such as Python, but the emphasis is on pure functions and strict objects. This helps to motivate Kotlin to become the choice of object functional hybrid.

Like Scala, Kotlin runs on the JVM, but interacting with Scala is much easier than Java. In addition, Kotlin targets JavaScript (Android operating system) and generates native code for other platforms.

Atomic Kotlin evolved from the ideas and materials in Atomic Scala.

Why choose Kotlin? (Launched in 2011, version 1.0: 2016)

Just as C++ was originally intended to be a "better C", Kotlin was also initially committed to being a "better Java". Since then, it has greatly exceeded its goal.

Kotlin's design philosophy distinguishes it from almost all its predecessors because it clearly avoids inventing new language features to solve perceived problems. Instead, in these functions were tested and field proven particularly valuable after its most successful, the most useful function is selected from other programming languages.

Therefore, if you come from another language, you may recognize certain features of that language in Kotlin. This is intentional: Kotlin maximizes productivity by leveraging tested concepts.

This atom does not assume that you are a programmer, which makes it difficult to explain most of the benefits of Kotlin over alternatives. However, there are two topics that are very influential and can be explained at this early stage: Java interoperability and the issue of indicating "worthlessness".

Effortless Java interoperability

To be "better C", C++ must be backward compatible with C's syntax, but Kotlin does not have to be backward compatible with Java's syntax-it only needs to be used with the JVM. This gives Kotlin designers the freedom to create a more concise, more powerful syntax without the visual noise and complexity that confuses Java.

In order to make Kotlin a "better Java", the experience of trying it must be pleasant and smooth, so Kotlin can be easily integrated with existing Java projects. You can write a small piece of Kotlin functionality and insert it into existing Java code. The Java code doesn't even know the Kotlin code is there, it looks like more Java code.

Companies usually research a new language by building independent programs in the language. Ideally, this procedure is beneficial but not necessary, so if the project fails, it can be terminated with minimal loss. Not every company wants to spend the resources needed for such experiments. Since Kotlin is seamlessly integrated into the existing Java system (and benefited from the testing of that system), it is very cheap or even free to try Kotlin to determine if it is suitable.

In addition, JetBrains, the company that created Kotlin, provides IntelliJ IDEA in a "community" (free) version, which includes support for Java and Kotlin and the ability to easily integrate the two. It even has a tool that uses Java code and (mostly) rewrites it to Kotlin.

Appendix B covers Java interoperability.

Represents emptiness

A particularly useful feature of Kotlin is that it can solve programming problems.

What do you do when someone hands you a dictionary and asks you to find a word that does not exist? You can guarantee results by defining definitions for unknown words. A more useful method is to say: "The word is not defined." This indicates a serious problem in programming: For uninitialized storage or operation results, how to indicate "no value"?

The null reference was made by Tony Hall, who later referred to it as inventing ALGOL in 1965 "My Billion Dollar Mistake." One problem is that it is too simple-sometimes being told that the room is empty is not enough of. For example, you may need to know why it is empty. This leads to the second problem: implementation. In order to improve efficiency, it is usually just a special value that can hold a small amount of memory. What could be better than the memory already allocated for this information?

The original C language did not automatically initialize the storage, which caused many problems. C++ improves this situation by setting the newly allocated storage to all zeros. Therefore, if the value is not initialized, it is just the number zero. This seems pretty good, but it allows uninitialized values ​​to slip away quietly (new C and C++ compilers often warn you about these issues). Worse, if a piece of storage is a pointer ( used to indicate (point to) another piece of storage), the null pointer will point to a zero position in memory, which is almost certainly not what you want.

Java prevents access to uninitialized values ​​by reporting errors while the program is running (ie, runtime ). Although this will find uninitialized values, it does not solve the problem because the only way you can run the program to verify that the program will not crash. There are a lot of such errors in Java code, and programmers waste a lot of time looking for them.

Kotlin solves this problem by preventing operations that may cause null errors before the program runs . This is the most famous feature when Java programmers adopt Kotlin. This feature can minimize or eliminate Java null errors.

Rich welfare

Whether you are a Java programmer or not, the two functions we can explain here (no more programming knowledge required) make a huge difference. If Kotlin is your first language, and you eventually need a project that requires more programmers, it will be much easier to recruit one of the many existing Java programmers to Kotlin.

Kotlin has many other benefits, and unless you know something about programming, we won’t be able to explain it. This is the purpose of the rest of the book.

Languages ​​are usually chosen out of passion rather than reason... I am trying to make Kotlin a language that people love for some reason. — Andrey Breslav, chief language designer at Kotlin.

Why Kotlin?

Programming language design is an evolutionary path from serving the needs of the machine to serving the needs of the programmer.

We give an overview of the historical development of programming languages so you can understand where Kotlin fits and why you might want to learn it. This atom introduces some topics which, if you are a novice, might seem too complicated right now. Feel free to skip this atom and come back to it after you’ve read more of the book.

A programming language is invented by a language designer and implemented as either an interpreter or a compiler, which are also programs. The implementer is usually the language designer, at least initially.

Early languages focused on hardware limitations. As computers become more powerful, newer languages shift toward more sophisticated programming with an emphasis on reliability. These languages can also begin choosing features based on the psychology of programming.

Every programming language is a collection of experiments. Historically, programming language design has been a succession of guesses and assumptions about what will make programmers more productive. Some of those experiments fail, some are mildly successful and some are very successful.

We learn from the experiments in each new language. Some languages address issues that turn out to be incidental rather than essential, or the environment changes (faster processors, cheaper memory, new understanding of programming and languages) and that issue becomes less important or even inconsequential. If those ideas become obsolete and the language doesn’t evolve, it fades from use.

The original programmers worked directly with numbers representing processor machine instructions. This approach produced numerous errors, and assembly language was created to replace the numbers with mnemonic opcodes—words that programmers could more easily remember and read, along with a number of other helpful tools. However, there was still a one-to-one correspondence between assembly-language instructions and machine instructions, and programmers had to write each line of assembly code. In addition, each computer processor used its own distinct assembly language.

Developing programs in assembly language is exceedingly expensive. Higher-level languages help solve that problem by providing a level of abstraction away from low-level assembly languages. Here we give a history of selected languages, chosen for their influence on those that followed them. All these languages ultimately inspired the design of Kotlin, sometimes by being an example of what not to do.

FORTRAN: FORmula TRANslation (1957)

Designed for use by scientists and engineers, Fortran’s goal was to make it easier to encode equations. Finely-tuned and tested Fortran libraries are still in use today, but they are typically “wrapped” to make them callable from other languages.

LISP: LISt Processor (1958)

Rather than being application-specific, LISP embodied essential programming concepts; it was the computer scientist’s language and the first functional programming language (You’ll learn about functional programming in this book). The tradeoff for its power and flexibility was efficiency: LISP was typically too expensive to run on early machines, and only in recent decades have machines become fast enough to produce a resurgence in the use of LISP. For example, the GNU Emacs editor is written entirely in LISP, and can be extended using LISP.

ALGOL: ALGOrithmic Language (1958)

Arguably the most influential of the 1950’s languages because it introduced syntax that persisted in many subsequent languages. For example, C and its derivatives are “ALGOL-like” languages.

COBOL: COmmon Business-Oriented Language (1959)

Designed for business, finance, and administrative data processing. It has an English-like syntax, and was intended to be self-documenting and highly readable. Although this intent generally failed—COBOL is famous for bugs introduced by a misplaced period—the US Department of Defense forced widespread adoption on mainframe computers, and systems are still running (and requiring maintenance) today.

BASIC: Beginners’ All-purpose Symbolic Instruction Code (1964)

This was one of the early attempts to make programming accessible. While very successful, its features and syntax were limited, so it was only partly helpful for people who needed to learn more sophisticated languages. It is predominantly an interpreted language, which means that to run it you need the original code for the program. Despite that, many useful programs were written in BASIC, in particular as a scripting language for Microsoft’s “Office” products. BASIC might even be thought of as the first “open” programming language, as people made numerous variations of it.

Simula 67, the Original Object-Oriented Language (1967)

A simulation typically involves many “objects” interacting with each other. Different objects have different characteristics and behaviors. Languages that existed at the time were awkward to use for simulations, so Simula (another “ALGOL-like” language) was developed to provide direct support for creating simulation objects. It turns out that these ideas are also useful for general-purpose programming, and this was the genesis of Object-Oriented (OO) languages.

Pascal (1970)

Pascal increased compilation speed by restricting the language so it could be implemented as a single-pass compiler. The language forced the programmer to structure their code in a particular way and imposed somewhat awkward and less-readable constraints on program organization. As processors became faster, memory cheaper, and compiler technology better, the impact of these constraints became too costly.

An implementation of Pascal, Turbo Pascal from Borland, initially worked on CP/M machines and then made the move to early MS-DOS (precursor to Windows), later evolving into the Delphi language for Windows. By putting everything in memory, Turbo Pascal compiled at lightning speeds on very underpowered machines, dramatically improving the programming experience. Its creator, Anders Hejlsberg, later went on to design both C# and TypeScript.

Niklaus Wirth, the inventor of Pascal, created subsequent languages: Modula, Modula-2 and Oberon. As the name implies, Modula focused on dividing programs into modules, for better organization and faster compilation. Most modern languages support separate compilation and some form of module system.

C (1972)

Despite the increasing number of higher-level languages, programmers were still writing assembly language. This is often called systems programming, because it is done at the level of the operating system, but it also includes embedded programming for dedicated physical devices. This is not only arduous and expensive (Bruce began his career writing assembly language for embedded systems), but it isn’t portable—assembly language can only run on the processor it is written for. C was designed to be a “high-level assembly language” that is still close enough to the hardware that you rarely need to write assembly. More importantly, a C program runs on any processor with a C compiler. C decoupled the program from the processor, which solved a huge and expensive problem. As a result, former assembly-language programmers could be vastly more productive in C. C has been so effective that recent languages (notably Go and Rust) are still attempting to usurp it for systems programming.

Smalltalk (1972)

Designed from the beginning to be purely object-oriented, Smalltalk significantly moved OO and language theory forward by being a platform for experimentation and demonstrating rapid application development. However, it was created when languages were still proprietary, and the entry price for a Smalltalk system could be in the thousands. It was interpreted, so you needed a Smalltalk environment to run programs. Open-source Smalltalk implementations did not appear until after the programming world had moved on. Smalltalk programmers have contributed great insights benefitting later OO languages like C++ and Java.

C++: A Better C with Objects (1983)

Bjarne Stroustrup created C++ because he wanted a better C and he wanted support for the object-oriented constructs he had experienced while using Simula-67. Bruce was a member of the C++ Standards Committee for its first eight years, and wrote three books on C++ including Thinking in C++.

Backwards-compatibility with C was a foundational principle of C++ design, so C code can be compiled in C++ with virtually no changes. This provided an easy migration path—programmers could continue to program in C, receive the benefits of C++, and slowly experiment with C++ features while still being productive. Most criticisms of C++ can be traced to the constraint of backwards compatibility with C.

One of the problems with C was the issue of memory management. The programmer must first acquire memory, then run an operation using that memory, then release the memory. Forgetting to release memory is called a memory leak and can result in using up the available memory and crashing the process. The initial version of C++ made some innovations in this area, along with constructors to ensure proper initialization. Later versions of the language have made significant improvements in memory management.

Python: Friendly and Flexible (1990)

Python’s designer, Guido Van Rossum, created the language based on his inspiration of “programming for everyone.” His nurturing of the Python community has given it the reputation of being the friendliest and most supportive community in the programming world. Python was one of the first open-source languages, resulting in implementations on virtually every platform including embedded systems and machine learning. Its dynamism and ease-of-use makes it ideal for automating small, repetitive tasks but its features also support the creation of large, complex programs.

Python is a true “grass-roots” language; it never had a company promoting it and the attitude of its fans was never to push the language, but simply to help anyone learn it who wants to. The language continues to steadily improve, and in recent years its popularity has skyrocketed.

Python may have been the first mainstream language to combine functional and OO programming. It predated Java with automatic memory management using garbage collection (you typically never have to allocate or release memory yourself) and the ability to run programs on multiple platforms.

Haskell: Pure Functional Programming (1990)

Inspired by Miranda (1985), a proprietary language, Haskell was created as an open standard for pure functional programming research, although it has also been used for products. Syntax and ideas from Haskell have influenced a number of subsequent languages including Kotlin.

Java: Virtual Machines and Garbage Collection (1995)

James Gosling and his team were given the task of writing code for a TV set-top box. They decided they didn’t like C++ and instead of creating the box, created the Java language. The company, Sun Microsystems, put an enormous marketing push behind the free language (still a new idea at the time) to attempt domination of the emerging Internet landscape.

This perceived time window for Internet domination put a lot of pressure on Java language design, resulting in a significant number of flaws (The book Thinking in Java illuminates these flaws so readers are prepared to cope with them). Although Java was remarkably successful, an important Kotlin design goal is to fix Java’s flaws so programmers can be more productive. Brian Goetz at Oracle, the current lead developer of Java, has made remarkable and surprising improvements in Java despite the constraints he inherited.

Java’s success came from two innovative features: a virtual machine andgarbage collection. These were available in other languages—for example, LISP, Smalltalk and Python have garbage collection and UCSD Pascal ran on a virtual machine—but they were never considered practical for mainstream languages. Java changed that, and in doing so made programmers significantly more productive.

A virtual machine is an intermediate layer between the language and the hardware, so the language doesn’t have to generate machine code for a particular processor; it only needs to generate an intermediate language that runs on the virtual machine. Virtual machines require processing power and, before Java, were believed to be impractical. The Java Virtual Machine (JVM) gave rise to Java’s slogan “write once, run everywhere.” In addition, other languages can be more easily developed by targeting the JVM; examples include Groovy, a Java-like scripting language, and Clojure, a version of LISP.

Garbage collection solves the problem of forgetting to release memory. There are also times when it can be quite difficult to know when a piece of storage is no longer used. Projects have been significantly delayed or even cancelled because of memory leaks. Although garbage collection appears in some prior languages, it was believed to produce an unacceptable amount of overhead until Java showed that it could be practical.

JavaScript: Java in Name Only (1995)

The original Web browser simply copied and displayed pages from a Web server. Web browsers proliferated, becoming a new programming platform that needed language support. Java wanted to be this language but was too awkward for the job. JavaScript began as LiveScript and was built into NetScape Navigator, one of the first Web browsers. Renaming it to JavaScript was a marketing ploy by NetScape, as the language has only a vague similarity to Java.

As the Web took off, JavaScript became tremendously important. However, the behavior of JavaScript was so unpredictable that Douglas Crockford wrote a book with the tongue-in-cheek title JavaScript, the Good Parts, where he demonstrated all the problems with the language so programmers could avoid them. Subsequent improvements by the ECMAScript committee changed JavaScript so thoroughly that it would be unrecognizeable by an original JavaScript programmer. It is now considered a stable and mature language.

Scala: SCALAble (2003)

Martin Odersky created Scala to run on the Java virtual machine: To piggyback on the work done on the JVM, to interact with Java programs, and possibly with the idea that it might displace Java. As a researcher, Odersky and his team used Scala as a platform to experiment with language features, notably those not included in Java.

These experiments have been illuminating and a number of them found their way into Kotlin, usually in a modified form. For example, the ability to redefine operators like + for use in special cases is called operator overloading. This was included in C++ but not Java. Scala added operator overloading but also allows you to invent new operators by combining any sequence of characters. This often produces confusing code. A limited form of operator overloading is included in Kotlin, but you can only overload operators that already exist.

Scala is also an object-functional hybrid, like Python but with a focus on pure functions and strict objects. This helped inspire Kotlin’s choice to also be an object-functional hybrid.

Like Scala, Kotlin runs on the JVM but it interacts with Java far more easily than Scala does. In addition, Kotlin targets JavaScript, the Android OS, and it generates native code for other platforms.

Atomic Kotlin evolved from the ideas and material in Atomic Scala.

Why Kotlin? (Introduced 2011, Version 1.0: 2016)

Just as C++ was initially intended to be “a better C,” Kotlin was initially oriented towards being “a better Java.” It has since evolved significantly beyond that goal.

Kotlin’s design philosophy sets it apart from virtually all its predecessors, because it explicitly avoids inventing new language features to solve perceived problems. Instead, it chooses the most successful and helpful features from other programming languages—after those features have been field-tested and proven to be especially valuable.

Thus, if you are coming from another language, you might recognize some features of that language in Kotlin. This is intentional: Kotlin maximizes productivity by leveraging tested concepts.

This atom does not assume you are a programmer, which makes it hard to explain most of the benefits of Kotlin over the alternatives. There are, however, two topics which are very impactful and can also be explained at this early juncture: Java interoperability and the issue of indicating “no value.”

Effortless Java Interoperability

To be “a better C,” C++ must be backwards compatible with the syntax of C, but Kotlin does not have to be backwards compatible with the syntax of Java—it only needs to work with the JVM. This frees the Kotlin designers to create a much cleaner and more powerful syntax, without the visual noise and complication that clutters Java.

For Kotlin to be “a better Java,” the experience of trying it must be pleasant and frictionless, so Kotlin enables effortless integration with existing Java projects. You can write a small piece of Kotlin functionality and slip it in amidst your existing Java code. The Java code doesn’t even know the Kotlin code is there—it just looks like more Java code.

Companies often investigate a new language by building a standalone program with that language. Ideally, this program is beneficial but nonessential, so if the project fails it can be terminated with minimal damage. Not every company wants to spend the kind of resources necessary for this type of experimentation. Because Kotlin seamlessly integrates into an existing Java system (and benefits from that system’s tests), it becomes very cheap or even free to try Kotlin to see whether it’s a good fit.

In addition, JetBrains, the company that creates Kotlin, provides IntelliJ IDEA in a “Community” (free) version, which includes support for both Java and Kotlin along with the ability to easily integrate the two. It even has a tool that takes Java code and (mostly) rewrites it to Kotlin.

Appendix B covers Java interoperability.

Representing Emptiness

An especially beneficial Kotlin feature is its solution to a challenging programming problem.

What do you do when someone hands you a dictionary and asks you to look up a word that doesn’t exist? You could guarantee results by making up definitions for unknown words. A more useful approach is just to say, “There’s no definition for that word.” This demonstrates a significant problem in programming: How do you indicate “no value” for a piece of storage that is uninitialized, or for the result of an operation?

The null reference was invented in 1965 for ALGOL by Tony Hoare, who later called it “my billion-dollar mistake.” One problem was that it was too simple—sometimes being told a room is empty isn’t enough; you might need to know, for example, why it is empty. This leads to the second problem: the implementation. For efficiency’s sake, it was typically just a special value that could fit in a small amount of memory, and what better than the memory that had already been allocated for that information?

The original C language did not automatically initialize storage, which caused numerous problems. C++ improved the situation by setting newly-allocated storage to all zeroes. Thus, if a numerical value isn’t initialized, it is simply a numerical zero. This didn’t seem so bad but it allowed uninitialized values to quietly slip through the cracks (newer C and C++ compilers often warn you about these). Worse, if a piece of storage was a pointer—used to indicate (“point to”) another piece of storage—a null pointer would point at location zero in memory, which is almost certainly not what you want.

Java prevents accesses to uninitialized values by reporting the error when the program is running (that is, at runtime). Although this discovers uninitialized values, it doesn’t solve the problem because the only way you can verify that your program won’t crash is by running it. There are swarms of these kinds of bugs in Java code, and programmers waste huge amounts of time finding them.

Kotlin solves this problem by preventing operations that might cause null errors before the program can run. This is the single-most celebrated feature by Java programmers adopting Kotlin. This one feature can minimize or eliminate Java’s null errors.

An Abundance of Benefits

The two features we were able to explain here (without requiring more programming knowledge) make a huge difference whether or not you’re a Java programmer. If Kotlin is your first language and you end up on a project that needs more programmers, it is much easier to recruit one of the many existing Java programmers into Kotlin.

Kotlin has many other benefits, which we cannot explain until you know more about programming. That’s what the rest of the book is for.

Languages are often selected by passion, not reason…I’m trying to make Kotlin a language that is loved for a reason.—Andrey Breslav, Kotlin Lead Language Designer.

From "Atomic Kotlin".

Guess you like

Origin blog.csdn.net/universsky2015/article/details/108480649