Note: The Python language is 30 years old, and it’s growing fast, thanks in large part to its easy-to-learn and easy-to-use design, but there’s no denying that Python has stolen a lot from other languages. The core of the writer is a senior developer, his broad vision and accurate understanding, make me a more comprehensive understanding of the design of Python, at the same time, he “using a sense of pride instead of fear” that sends out is “focus on the progress of the self, don’t envy other people’s success” principle, is also very helpful to me. The original, written in 2015, has been sitting in my favorites for a long, long time. Now it has been translated successfully, which is a meaningful thing to boost my pride. Finally, I wish you all a beneficial opening and a fruitful reading.
By Nick Coghlan
The cat under the pea flower
English: www.curiousefficiency.org/posts/2015/…
Note: This translation is for the purpose of communication and learning, based on CC BY-NC-SA 4.0 license agreement. The content has been changed slightly for ease of reading.
directory
- Broaden our horizons
- Procedural programming: C, Rust, Cython
- Object-oriented data model: Java, C#, Eiffel
- Object-oriented C derivatives: C++, D
- Array-oriented data processing: MATLAB/Octave, Julia
- Statistical analysis: R
- Computational pipeline modeling: Haskell, Scala, Clojure, F#
- Event-driven programming: JavaScript, Go, Erlang, Elixir
- Gradient type: TypeScript
- Dynamic metaprogramming: Hy, Ruby
- Pragmatic problem solving: Lua, PHP, Perl
- Programming thinking: Scratch, Logo
As a co-designer of one of the most popular programming languages in the world, I often see frustrating behavior (in the Python community and beyond) where influencers try to motivate people to contribute to the community by raising fears of “losing” to other open source communities. (I occasionally make this mistake myself, which makes it easier to see if others are falling into the same trap.)
Although the experience of the community to learn other programming language is a good thing, but the method based on fear to motivate action is a serious problem, because it can stimulate the community members will be other people in the community as a competition for open source contributors to focus on the enemy, rather than as a potential Allies in the greater challenge, propel the development of the art software development). It also tells those who prefer other languages that they are unwelcome in a community that sees them and their companions as “hostile competitors”.
In fact, we want to have a wide variety of cross-platform open source programming languages to choose from, because programming languages are the primary tool for thinking — enabling us to express our ideas in explicit ways that computers can understand. It would be great if someone found a brain-friendly language that could solve the problem at hand, no matter what language they chose.
So I have three specific requests to the Python community, and one more general recommendation. First of all, my request is this:
- If we are to harness the instincts of community to spur action, we should avoid exploiting fear and use pride instead. When we use fear as a motivator, like saying “if we don’t do X, we’ll lose developers’ interest in Python,” it’s deliberately creating pessimism among free open source contributors. However, relying on community pride is like saying “it’s not clear how to solve the X problem in Python. If we look at Y, we can see that they have a very good approach to problem X that we can incorporate into Python to provide a similarly comfortable user experience.” A positive attitude that makes us proud of our own efforts, rather than devalue the efforts of others, helps foster a culture of continuous learning within the Python community and promotes improved collaborative relationships and co-development with other communities.
- Refrain from taking a dismissive attitude toward other open source programming language communities, especially when those communities empower people to solve their own problems rather than waiting for commercial software vendors to solve them. Most of the world’s important problems are unprofitable to solve (because the people who suffer from them are not rich and have no influence over institutional funding decisions), so we should encourage people trying to solve these problems, no matter what we think of their technology choices.
- ** If someone we know is just learning to program, and they pick a language we don’t like, we should support their choice. ** They know better than we do what works for them, and what works for us may not work for them. If they are frustrated with their initial choice, or even unmotivated to learn programming, suggest another language. This advice also applies to those who are trying to improve their poor online security: We not safe in the face of a natural language, the approach is to improve the operating system of the function of the sandbox, gradually learning have better local security properties of language, and improve the default behavior of the existing language, why not list from the point of view of application security, their choice of language is a bad choice, to confuse the beginners. (If someone deploys unapproved software written by a beginner to handle security-sensitive tasks, that’s not the developer’s problem, but the deployers’, who didn’t do proper due diligence on the software’s provenance and security attributes.)
My general advice is for those who encounter the limitations of Python’s core programs and therefore wish to explore the “thinking tools” available in Python. This advice is:
Broaden our horizons
One of the things we do as we develop Python core programs is to look at features in other languages that address the problems we are facing and see if there are ways to both absorb them and make Python code easier to read and write. This means that learning about other programming languages that focus on a particular style of software development can help us improve our understanding of that style of programming when we use Python.
To help, I’ve listed some areas worth exploring below, along with language that might deepen understanding of them. I linked to wikipedia pages as much as possible, rather than directly to the language’s home page, because Wikipedia often provides interesting historical background that’s worth knowing when you’re learning a new programming language for educational purposes, rather than directly for practical use.
While I know most of these languages (and have used several while developing production systems), this list of recommendations also includes languages I know indirectly (usually through reading tutorials and design documents, or talking to people I trust to gain insight into a language’s strengths and weaknesses).
There are many other languages that should have been included but didn’t make the list, so the ones listed below are just the ones I’m interested in (for example, I’m mainly interested in the Linux, Android, and Windows ecosystems, So I dropped Objective-C and Swift from the Apple ecosystem, and I’m not familiar with Processing as an art-focused programming language and can’t imagine what learning them can teach Python developers.)
In addition to considering what a language might teach you, if you want a more comprehensive list, check out IEEE Spectrum’s annual list on the popularity and growth of programming languages.
Procedural programming: C, Rust, Cython
Python’s default execution model is procedural: start at the top of the main module and execute statement by statement. Python’s support for all of the data and programming modeling approaches described below rests on this procedural execution model.
C remains the undisputed ruler of low-level procedural programming. It is the official Python interpreter and the core implementation language of the Linux operating system kernel. As a software developer, learning C is one of the best ways to learn more about the underlying hardware — C is often referred to as “portable assembly language” and the first cross-compiled application for any new CPU architecture will be a C compiler.
Rust is a relatively new programming language, created by Mozilla. Rust’s goal was to take all of the lessons the industry had learned without C and design a new language that interoperated with the C library, providing the precise control over hardware usage needed for underlying system programming, but using different compilation methods for data modeling and memory management. Structurally eliminate many of the common defects that plague C programs (such as buffer overflows, duplicate pointer release errors, null pointer access, and thread synchronization issues). I’m an embedded systems engineer by training and early professional experience, and Rust is the first new language I’ve seen that looks like it has the potential to shrink the niche currently dominated by C and custom assembly code.
Cython is also a lower-level procedural language, but unlike general-purpose languages such as C and Rust, Cython is dedicated to writing extension modules to CPython. To achieve this goal, Cython is designed as a superset of Python, allowing programmers to choose when to support pure Python syntax for flexibility and when to support Cython’s syntax extensions in order to produce code comparable to native C code in terms of speed and memory efficiency.
By learning these languages, you can gain insights into the practical aspects of memory management, algorithmic efficiency, binary interface (ABI) compatibility, software portability, and converting source code into a running system.
Object-oriented data model: Java, C#, Eiffel
One of the main things that programming does is to model the real world, and the most popular approach is to provide native syntax to support object-oriented programming: structured groupings of data, using class methods to manipulate those data structures.
Python itself is designed so that you can use object-oriented features without first writing your own classes. Not every language takes this approach — all of the languages listed in this section consider learning object-oriented design a requirement to use the language.
During a major marketing push by Sun Microsystems in the mid to late 1990s, Java became the default language in many college introductory computer science classes. Although Java has been replaced by Python in many teaching activities today, it remains one of the most popular languages for developing commercial programs. There are also languages based on the general-purpose JVM (Java Virtual Machine) runtime, such as the Jython implementation of Python. The Dalvik and ART environments of Android system are secondary development based on Java open API.
Similar to Java in many ways, C# became an alternative after Sun and Microsoft failed to resolve their business differences regarding Microsoft’s Java implementation, known as J++. Like Java, this is a popular language for developing business applications, and there are other languages that share the.NET CLR (Common Language Runtime), Including the IronPython implementation of Python (the core components of the original IronPython 1.0 were extracted into a language-independent.NET dynamic language runtime). For a long time,.NET was a Windows-specific technology and Mono served as a cross-platform open source implementation, but Microsoft switched to an open source ecosystem strategy in early 2015.
Unlike most of the languages on this list, I don’t recommend using Eiffel for everyday work. However, I recommend it because it has taught me a lot about good object-oriented design, such as the idea that “verifiable correctness” is the design goal of an application. (Learning Eiffel also helped me understand why “verifiable correctness” is not a design goal for most software development, because verifiable correctness doesn’t really handle ambiguity well, and doesn’t work at all well with constraints that you don’t understand but need to leave yourself plenty of wiggle room. In order to find out more details through iterative development.
Learning these languages will give you insight into inheritance models, design by contract, class invariants, preconditions, postconditions, covariances, contravariance, class method parsing order, generic programming, and other concepts that apply to Python’s type system. There are also many standard library modules and third-party frameworks that use this “visible object-oriented” design style, such as the UnitTest and Logging modules and the class-based views in the Django framework.
Object-oriented C derivatives: C++, D
The CPython runtime environment can be thought of as a “C with objects” programming environment — at its core, CPython uses C’s approach to object-oriented programming by defining C constructs to hold relevant data and passing an instance of the constructs to functions as the first argument, The data is then manipulated (this is the all-powerful PyObject * pointer in the CPython C API). This design pattern corresponds at the Python level to the explicit self argument for instance methods and the explicit CLS argument for class methods.
The goal of C++ is to maintain full compatibility with C language source code while adding more advanced features such as support for native object-oriented programming and template-based metaprogramming. It is notoriously tedious and difficult to program (although a 2011 update to the language standards fixed a lot of bad problems), but it is also the programming of choice in many areas, including a graphical engine for 3D modeling and a development framework for cross-platform applications (e.g. Qt).
D is also interesting because its relationship to C++ is similar to that of Rust to C: Its goal is to retain most of the desirable features of C++ while also avoiding many of its problems (such as a lack of memory security). Unlike Rust, D is not a new programming language designed from scratch — on the contrary, IT is a derivative of C++, and while it is not a strict C superset like C++, it follows the design principle that any code that falls into a common subset of C and D must behave consistently in both languages.
By studying these languages, you can gain a deeper understanding of the complexities of combining the features of a high-level language with the underlying C runtime model. Learning C++ and working with libraries and toolkits written in C++ in Python may also be helpful.
Array-oriented data processing: MATLAB/Octave, Julia
Array-oriented programming is designed to support numerical programming models: those based on matrix algebra and related numerical methods.
Although Python’s standard library does not directly support this, Python has been designed with array-oriented programming in mind, and has added a number of syntactic and semantic features specifically for third-party NumPy libraries and similar array-oriented tools.
In many ways, Python’s Science and Technology stack is used as an alternative to commercial MATLAB, which is widely used for modeling, simulation, and data analysis in science and engineering. GNU Octave is an open source solution that aims to be compatible with the syntax of MATLAB code, allowing people to compare these two array-oriented programming approaches.
Julia is another relatively new language that focuses on array-oriented programming and type-based function overloading.
Learning these languages gives you an insight into Python’s science stack and the opportunity to explore parallel execution at the hardware level through technologies like OpenCL and Nvidia’s CUDA, Learn about distributed data processing with Apache Spark and Python-specific Blaze.
Statistical analysis: R
As access to large data sets increases, so does the need for analytical tools that can work flexibly with them. The R programming language is one such tool, with a special focus on statistical data analysis and visualization.
Learning R will give you insight into the statistical analysis capabilities of Python’s scientific stack, especially its pandas library and seaborn statistical visualization library.
Computational pipeline modeling: Haskell, Scala, Clojure, F#
Object-oriented data modeling and array-oriented data processing focus on static data, whether in the form of named attributes as collections or structured data as arrays.
In contrast, functional programming languages emphasize modeling dynamic data in the form of computational flows. Learning even the basics of functional programming can greatly improve the structure of data conversion operations, even in other procedural, object-oriented, or array-oriented programs.
Haskell is a functional programming language that has had a major influence on the design of Python, most notably with the introduction of list derivations in Python 2.0.
Scala is a (questionable) JVM functional programming language, along with Java, Python, and R, which are the four main programming languages for the Apache Spark data analysis platform. Despite Scala’s design bias toward functional programming, its syntax, data model, and execution model are designed to minimize the barriers to use by Java programmers (hence “questionable” — in fact, Scala is best classed as an object-oriented programming language with strong functional programming support).
Clojure is another JVM-based functional programming language, a dialect of Lisp. It’s on this list because it was the inspiration for Python’s Toolz functional programming toolkit.
F# is not a language I’m particularly familiar with myself, but it’s still worth watching as a functional programming language recommended by the.net CLR (common language runtime).
Learning these languages gives you insight into Python’s own computational pipeline modeling tools, including the container derivations, generators, generator expressions, funcTools, and Itertools standard libraries, as well as third-party Python function toolkits, such as Toolz.
Event-driven programming: JavaScript, Go, Erlang, Elixir
Computing pipes are an excellent way to handle data transformation and analysis problems, but many problems require programs to run as persistent services, waiting for events to occur, and then processing those events. In such services, it is often necessary to process multiple events concurrently in order to accommodate multiple users (or operations) at the same time.
JavaScript was originally developed as an event processing language for Web browsers, allowing Web developers to respond locally to client actions (such as mouse clicks and keystrokes) and events (such as when a Web page has been rendered). It is supported by all modern browsers, and along with the HTML5 Domain Object Model (DOM), it has become a de facto standard for defining the look and behavior of user interfaces.
Go is a proprietary language designed by Google for creating highly scalable Web services, and has proven to be a great language for developing command-line applications. The most interesting aspect of Go from a programming language design point of view is the use of the concept of Communicating Sequential Processes in its core concurrency model.
Erlang is a proprietary language designed by Ericsson for the creation of highly reliable telephone switches and similar devices. It is used to develop the popular RabbitMQ message broker middleware. Erlang uses the Actor model as the core concurrency primitive, passing messages between executing threads rather than having them share data directly. Although I had never programmed with Erlang, my first full-time job involved an actor-based C++ concurrency framework developed by a former Ericsson engineer, as well as one of my own, TSK (Task) and MBX (Mailbox) primitives in the Lightweight DSP/BIOS runtime (now TI-RTOS) based on Texas Instrument.
Elixir appears on this list because it is designed to run on top of the Erlang VM, providing the same concurrency semantics as Erlang, while also providing a set of langua-level features that create a more comprehensive environment. More likely to attract developers from other languages such as Python, Java or Ruby.
Learning these languages gives you insight into Python’s support for concurrency and parallelism, These include native coroutines, generator-based coroutines, concurrent.futures and Asyncio standard library modules, third-party web service development frameworks such as Twisted and Tornado, the channel concept introduced in Django, and GUI Event processing loops in the framework. Python advanced
Gradient type: TypeScript
One of the more controversial features in Python 3.5 is the introduction of the typing module, which brings a standard dictionary to the Python ecosystem that supports gradient typing.
Python Cat Note: Gradual typing is a theory developed by Jeremy Siek and Walid Taha in 2006 that allows both dynamic and static typing to occur in a program. Some people in China have translated it into “progressive type”, “asymptotic type”, “progressive stereotype”, “hybrid type” and so on, but I think it is not good enough. The gradient type is perhaps my first, borrowed from Photoshop’s gradient color, which expresses the transition (or blending) from dynamic to static types. The term “gradient” implies a state of breaking down boundaries (size, distance, light and shade) to achieve a state of neutralization.
To those whose primary exposure to static typing comes from languages like C, C++, and Java, this may seem a surprisingly bad feature (and thus controversial).
Microsoft TypeScript provides gradient typing for Javascript programs, so it explains this concept better. TypeScript code is compiled into JavaScript code (which then does not include runtime type checking), and TypeScript annotations from popular JavaScript libraries are maintained in dedicated DefinitelyTyped bins.
As Chris Neugebauer pointed out at PyCon in Australia, this is a lot like Python’s relationship with typeshed type hint libraries and type inference and analysis tools like Mypy.
In essence, type hints in TypeScript and Python are ways of writing specific kinds of tests, either in separate files (like normal tests) or embedded in the body of code (like type declarations in statically typed languages). In both cases, you run a separate command to check that the rest of the code is consistent with the added type assertion. (With TypeScript, this happens implicitly when written to JavaScript; For Python type hints, this is a completely optional static analysis task).
Dynamic metaprogramming: Hy, Ruby
One feature that learners of languages like C, C++, C#, and Java often find uncomfortable when working with Python is “code is data” : things like functions and classes are runtime objects that can be manipulated just like any other object.
Hy is a Lisp dialect that can run on both CPython VM and PyPy VM. Lisp and its dialects push the concept of “code as data” to the extreme, because Lisp code consists of nested lists that describe the operations to be performed (the language’s name itself stands for LISt Processor). The power of lisp-style languages is that they make it very easy to write your own domain-specific code. The biggest drawback of the Lisp-style language is that it makes it very easy to write your own domain-specific code, but this can lead to everyone writing code that is hard to read.
The Ruby language is similar to Python in many respects, but the Ruby community is relatively open to dynamic metaprogramming features that are “supported but discouraged” in Python. This includes adding new methods to existing class definitions and using closures to implement core constructs of the language, such as iteration. (Python cat note: See this article for a comparison of implementations of iterative constructs in the two languages.)
Learning these languages will give you insight into Python’s own dynamic metaprogramming features, including function and class decorators, monkey patches, the UnitTest. mock standard library, and third-party object proxy modules like WRapt. (I have no idea which language to learn to gain insight into Python’s metaclass system, and if anyone has any suggestions on this, please let me know in the comments. Python metaclasses drive many features, such as the core type system, abstract base classes, runtime evaluation of enumerated types, and tent-type expressions.
Pragmatic problem solving: Lua, PHP, Perl
Mainstream programming languages don’t exist in isolation — they exist as part of a larger ecosystem composed of publishers (businesses and community organizations), end users, framework developers, tool developers, educators, and so on.
Lua is a popular programming language embedded in large programs as a scripting engine. An iconic example is its use in world of Warcraft to write client plug-ins, and it is embedded in the RPM component used in many Linux distributions. Compared to CPython, the Lua runtime is typically one-tenth the size of CPython and is more easily isolated from the rest of the program and the server’s operating system due to its weaker introspection. A notable contribution of the Lua community to the Python ecosystem is the LuaJIT FFI (Foreign Function Interface Foreign Function Interface), which was adopted by CPython and PyPy as the basis for the JIT-enabled CFFI Interface library.
PHP is another popular programming language that rose to prominence as the “P” in the Linux-Apache-mysql-PHP LAMP stack because of its focus on generating HTML pages, and in the early days of Virtual Private Servers (Virtual Private Servers, VPS) is widely used by VPS providers. Despite the sheer despair of conceptual flaws in its design, it is now the basis for several extremely popular open source Web services, including the Drupal content management system, the WordPress blog engine, and Wikipedia’s MediaWiki engine. PHP also supports important services, such as the Ushahidi platform, which is an open source social news publishing community.
Like PHP, Perl grew out of Linux. But unlike PHP, which is exclusively a Web development platform, Perl is a system administrator’s tool that, in the text-based Linux operating system, uses regular expressions to turn the output of commands into strings and manipulate them. Perl comes in handy when sh, AWk, and SED aren’t up to the task.
Learning these languages is unlikely to yield any aesthetic or elegant concepts of programming language design. The best way to learn them is to understand how programming languages are distributed and adopted in reality, and how much of this depends on chance, historical accidents, and publishers lowering the barriers to use by default by integrating into systems, rather than on the inherent capabilities of the language itself. Python advanced
In particular, it can provide insight into the importance of: CKAN, OpenStack NFV, Blender, SciPy, OpenMDAO, PyGMO, PyCUDA, Raspberry PI Foundation, and Python are adopted by a large number of commercial organizations to protect their ongoing investments in the Python ecosystem.
Programming thinking: Scratch, Logo
I often talk to proponents of functional and object-oriented programming who claim that such languages are as easy to learn as procedural languages.
If we’re talking about teaching through embedded programming, such as robotics, where objects modeled in software have real-world counterparts, such as sensors, motors, and relays that students can touch, then I think OOP people have a point.
But for everyone else, I now have a standard challenge: Pick up a cookbook, translate one of the recipes into what you think is an easy programming language to learn, and get a student who understands the language in the cookbook to follow the translated recipe. They didn’t have to actually do it — just a thought experiment was enough to realize how much prior knowledge they assumed when they claimed to be “easy to learn.” (I’d love to see academic researchers do this kind of research in the real world — I’d really like to see the results)
Another way to tackle this problem is to learn languages that are actually used to teach children to think programmatically.
One of the most popular is Scratch, which uses a drag-and-drop programming interface that lets students manipulate a separate graphics environment with electronic graphics that can move and respond to events in the environment. Graphic environments like Scratch are the picture books we use to teach children to read and write.
The idea of using a special educational language to manipulate graphical environments is not new; one of the earliest examples was the Logo environment invented in the 1960s. In Logo (and similar environments, such as the Turtle module in Python), you are primarily dealing with a Turtle, and you can draw lines to guide it to move and modify the environment. In this way, command sequences, repetitions, and states (e.g., “start pen,” “drop pen”) can be used based on people’s natural intuition (” Imagine you’re the turtle, what would happen if you turned 90 degrees right? )
Reviewing and relearning these languages helps experienced programmers to let go of stereotypes: they use concepts that remind us that we now take for granted, but that beginners need to learn first. When we do this, we are better able to relate to students and other beginners because we are more likely to unshackle logic and no longer ignore necessary learning steps.
Translator’s note: The above is the full translation. I have also translated many excellent articles. Here are some recent ones:
1. Compare Python and Ruby programming ideas through the for loop
2. Official Python Workshop: Is it really possible to completely remove the GIL?
3. Chat with the Father of Python: Faster Python!
4. Digging into the Python interpreter source code, I finally understand the principle of string residence!
5. Why doesn’t Python have function overloading? How to implement function overloading with decorators?
6. Python optimization: Constant folding
If you find this article helpful, please like + follow support, thank you!