经常的近义词是什么| 什么动物怕水| mandy是什么意思| 土克什么| 见干见湿是什么意思| 圈癣是什么引起的| 1月17号什么星座| 休眠是什么意思| fla是什么牌子| 井什么有什么| 水母吃什么| 偏光和非偏光有什么区别| 锁阳是什么| 办护照需要什么材料| 尿酸高会出现什么症状| 痔疮为什么会出血| 种小麦用什么肥料好| 恪尽职守是什么意思| 指什么为什么| 身体乳是什么| 人体第一道防线是什么| 搞破鞋什么意思| 梦见掰玉米是什么意思| 尼泊尔人是什么人种| 手麻木吃什么药| 你是什么| 什么生肖站着睡觉| 为什么拉不出屎| 胸闷气短吃什么药| 78是什么意思| 氢化油是什么东西| ab型血生的孩子是什么血型| 补血吃什么食物最好| 什么人容易得心肌炎| 乳腺癌ki67是什么意思| 经期洗澡有什么影响| 射手座是什么象| 是故是什么意思| 复读是什么意思| 脾虚要吃什么东西调理| 及笄是什么意思| 黄精什么人不能吃| 革兰阴性杆菌是什么| 腮腺炎吃什么药最管用| 传染病八项包括什么| 孔雀女是什么意思| 留级是什么意思| 冠心病用什么药| 时迁的绰号是什么| 口腔溃疡是什么| 三保是什么| 牙疼吃什么药最好最有效| 什么的摇篮| 什么水果泡酒最好喝| 大姨妈喝什么汤好| 血沉高是什么原因| ana医学上是什么意思| 伊丽莎白雅顿什么档次| 故事情节是什么意思| 清真是什么意思啊| 爱心是什么意思| 一什么红枣| 万足读什么| 老花镜是什么镜| 治安大队是干什么的| 大腿肌肉疼是什么原因| angelababy是什么意思| 放疗跟化疗有什么区别| 老卵上海话什么意思| 抚琴是什么意思| 真命题是什么意思| 术后病人吃什么营养恢复快| 小孩说话不清楚挂什么科| 2002年是什么命| 绿松石有什么功效| 牛奶丝是什么面料| 非球面镜片是什么意思| 弱碱性水是什么水| 华语是什么语言| 七月开什么花| 什么水果解酒| 缺钙吃什么补得最快| 男人眉毛长代表什么| usd什么意思| 乡镇党委书记是什么级别| 头发没有光泽是什么原因| 月经不正常吃什么药| 75年属什么生肖| 簸箕是什么东西| 狼吞虎咽是什么意思| 梦见打架是什么意思| 抽象是什么意思| 小麦粉可以做什么吃的| 什么羽毛球拍最好| 阑尾切除后有什么影响和后遗症| 立加羽念什么| 脚底发麻是什么病的前兆| 心脾两虚吃什么食物补最快| 股票里xd是什么意思| 烫伤了抹什么| 清蒸鱼一般用什么鱼| 大连有什么特产| 一阵一阵的胃疼是什么原因| 舌根发硬是什么原因| 汗斑是什么样的图片| 桑葚什么时候成熟| 落地成盒什么意思| 脾胃伏火是什么意思| 喝苹果醋有什么好处和坏处| 异性朋友是什么意思| 50分贝相当于什么声音| 大熊猫为什么有黑眼圈| 977是什么意思| 没有胎心胎芽是什么原因造成的| 秦皇岛有什么特产| 枸杞泡水喝有什么作用| 双顶径是什么| 高血压能吃什么水果| 有鳞状细胞是什么意思| 什么是修行人| cg是什么意思| 腿酸是什么原因引起的| 水杯用什么材质的好| 全身检查要挂什么科| 麦冬什么时候种植| 大脑供血不足头晕吃什么药最好| 屁股出汗多是什么原因| 骨骼闭合了还有什么办法可以长高| who医学上是什么意思| 为什么叫香港脚| 舌苔白吃什么药效果好| 塑胶厂是做什么的| 木耳属于什么类| 田鸡是什么| 黄瓜苦是什么原因| 农历七月初七是什么节日| 孕妇吃海带有什么好处| 什么爱| sob是什么意思| idh是什么意思| 下面外面瘙痒用什么药| 天蝎座喜欢什么样的女生| 一什么方向| 膳食是什么意思| 乳癖是什么病| 孕晚期白细胞高是什么原因| 疖肿吃什么药| 胰腺是什么器官| 明年属什么| 喝冰美式有什么好处| 免疫系统由什么组成| 芡实是什么| 23岁属什么| 擦枪走火什么意思| 9月15号是什么日子| 什么动物吃草| 欧芹在中国叫什么| 两点水的字和什么有关| 狗狗中毒了用什么办法可以解毒| 上焦火旺什么症状| 出柜什么意思| 步履维艰是什么意思| 无花果什么时候结果| 骨折后吃什么好的快| 螺吃什么| 午睡后头疼是什么原因| 股票举牌什么意思| 什么人不适合吃榴莲| 防弹衣为什么能防弹| 小猫吃什么| 脾大是怎么回事有什么危害| 子宫囊肿严重吗有什么危害| 贼不走空什么意思| 肠粉为什么叫肠粉| 竟然是什么意思| 手指甲上有竖纹是什么原因| 什么东西含铅| 天亮是什么时辰| 物是人非什么意思| 网球肘用什么方法能彻底治好呢| 开宠物医院需要什么条件| 睡莲为什么不开花| 黑色记号笔用什么能擦掉| 9价疫苗适合什么年龄人打| 头发大把大把的掉是什么原因| 邪气入体是什么症状| 为什么缺钾| 黄酒是什么| 下体有异味是什么原因| 高考推迟月经吃什么药| 起酥油是什么做的| 吃什么月经会推迟| bl是什么意思| 中标是什么意思| 乌豆是什么| 生物医学工程专业学什么| 做水煮鱼用什么鱼最好| 星星为什么会眨眼睛| 肠镜前一天吃什么| 舌头有红点是什么原因| 什么是零和博弈| 耸肩是什么原因造成的| 优生优育检查什么项目| 出生日期查五行缺什么| 视线模糊是什么原因| 天天喝白酒对身体有什么危害| 肝胃不和是什么意思| tvoc是什么意思| 甲状腺低密度结节是什么意思| 六合什么意思| lee什么意思| 长期是什么意思| 木木耳朵旁是什么字| 小孩心肌炎有什么症状| 老人喝什么牛奶好| 熠五行属什么| 五行缺水戴什么| 甘油三酯高吃什么食物| 吃什么水果对胃好| 身上湿气重吃什么药| 用什么药材泡酒最好| 风热感冒吃什么药效果好| 吃土豆有什么好处和坏处| 眼睛干痒用什么眼药水比较好| 房间放什么可以驱蜈蚣| 什么是特殊膳食| 老子姓什么| 拉脱水是什么症状| 凉席什么材质好| 吃什么防止脱发掉发| 什么水果对嗓子好| 舌苔发黄是什么原因| 左肺下叶钙化灶是什么意思| 咳嗽喉咙痒吃什么药好得快| 月经老是推迟是什么原因| 五月初是什么星座| 腐女是什么意思| 名分是什么意思| 牙龈和牙齿分离是什么原因| 大便陶土色是什么颜色| 什么是纳囊| 上海最高的楼叫什么| 经期适合吃什么食物| 灰指甲吃什么药| 猫咪能吃什么水果| 什么是结扎| 为什么会有| 一什么尾巴| 并蒂是什么意思| 荣五行属什么| 第一次坐飞机注意什么| 社保卡是什么样的图片| 琛字五行属什么| 用什么| 黑茶属于什么茶| 什么是血清| 尿素高不能吃什么| 白带多是什么原因| 官员出狱后靠什么生活| 100聚酯纤维是什么面料| 新疆都有什么民族| 例假少吃什么药| 什么名字好听男生| 手肿是什么原因引起的| 百度
BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage Articles Transcrypt: Anatomy of a Python to JavaScript Compiler

大师用车|汽车美容属暴利行业 贴膜价格悬殊利

Key Takeaways

  • Languages that run in the browser should precompile to JavaScript isomorphically for compactness, execution speed and development speed
  • For efficient cooperation on a large web application, module boundaries should coincide with team boundaries
  • Modules may have dynamic typing on the inside, but should have static typing on the outside
  • Having the same technology on the client and on the server promotes scalability
  • The future of Python in the browser is tied to the future of Python in general, not so much to a particular implementation

Featuring a diversity of programming languages, backend technology offers the right tool for any kind of job. At the frontend, however, it's one size fits all: JavaScript. Someone with only a hammer will have to treat anything like a nail. One attempt to break open this restricted world is represented by the growing set of source to source compilers that target JavaScript. Such compilers are available for languages as diverse as Scala, C++, Ruby, and Python. The Transcrypt Python to JavaScript compiler is a relatively new open source project, aiming at executing Python 3.6 at JavaScript speed, with comparable file sizes.

For a tool like this to offer an attractive alternative to everyday web development in JavaScript, at least the following three demands have to be met:

  1. From a user point of view, web sites and web applications created with it should be indistinguishable with regard to look and feel, page load time, page startup time and sustained speed
  2. From a developer point of view, it should allow seamless access to any JavaScript library, efficient debugging and the opportunity to capitalize on existing skills
  3. From a business point of view, it should offer continuity, availability of a large pool of professionally trained developers, a good ratio of created functionality to invested hours and a resulting application open to changing needs

To be successful, all aspects of these three requirements have to be met. Different compilers strike a different balance between them, but no viable compiler for every day production use can neglect any of them. For Transcrypt, each of the above three points has led to certain design decisions.

Demand 1:

Look and feel of web sites and web applications are directly connected to the underlying JavaScript libraries used, so to have exactly the same look and feel, a site or application should use exactly the same libraries.

Although fast connections may hide the differences, achieving the same page load time, even on mobile devices running on public networks, mandates having roughly the same code size. This rules out downloading a compiler, virtual machine or large runtime at each new page load.

Achieving the same startup time as pages utilizing native JavaScript is only possible if the code is statically precompiled to JavaScript on the server. The larger the amount of code needed for a certain page, the more obvious the difference becomes.

To have the same sustained speed, the generated JavaScript must be efficient. Since JavaScript virtual machines are highly optimized for common coding patterns, the generated JavaScript should be similar to handwritten JavaScript, rather than emulating a stack machine or any other low level abstraction.

Demand 2:

To allow seamless access to any JavaScript library, Python and JavaScript have to use unified data formats, a unified calling model, and a unified object model. The latter requires the JavaScript prototype based single inheritance mechanism to somehow gel with Python’s class based multiple inheritance. Note that the recent addition of the keyword 'class' to JavaScript has no impact on the need to bridge this fundamental difference.

To enable efficient debugging, things like setting breakpoints and single stepping through code have to be done on the source level. In other words: source maps are necessary. Whenever a problem is encountered it must be possible to inspect and comprehend the generated JavaScript to pinpoint exactly what's going on. To this end, the generated JavaScript should be isomorphic to the Python source code.

The ability to capitalize on existing skills means that the source code has to be pure Python, not some syntactic variation. A robust way to achieve this is to use Python's native parser. The same holds for semantics, a requirement that poses practical problems and requires introduction of compiler directives to maintain runtime efficiency.

Demand 3:

Continuity is needed to protect investments in client side Python code, requiring continued availability of client side Python compilers with both good conformance and good performance. Striking the right balance between these two is the most critical part of designing a compiler.

Continued availability of trained Python developers is sufficiently warranted by the fact that Python has been the number 1 language taught in introductory computer science courses for three consecutive years now.  On the backend it is used for every conceivable branch of computing.  All these developers, used to designing large, long lived systems rather than insulated, short lived pieces of frontend script code, become available to browser programming if it is done in Python.

With regard to productivity, many developers that have made the switch from a different programming language to Python agree that it has significantly increased their output while retaining runtime performance. The latter is due to the fact that libraries used by Python applications for time critical operations like numerical processing and 3D graphics usually compile to native machine code.

The last point – openness to changed needs – means that modularity and flexibility have to be supported at every level. The presence, right from the start, of class-based OO with multiple inheritance and a sophisticated module and package mechanism has contributed to this.  In addition, the possibility to use named and default parameters allows developers to change call signatures in a late stage without breaking existing code.

Conformance versus performance:  language convergence to the rescue

Many Python constructs closely match JavaScript constructs, especially when translating to newer versions of JavaScript. There's a clear convergence between both languages. Specifically, more and more elements of Python make their way into JavaScript: for ... of ..., classes (in a limited form), modules, destructuring assignment and argument spreading. Since constructs like  for ... of ... are highly optimized on modern JavaScript virtual machines, it's advantageous to translate such Python constructs to closely matching JavaScript constructs. Such isomorphic translation will result in code that can benefit from optimizations in the target language. It will also result in JavaScript code that is easy to read and debug.

Although with Transcrypt, through the presence of source maps, most debugging will take place stepping through Python rather than JavaScript code, a tool should not conceal but rather reveal the underlying technology, granting developer full access to 'what's actually going on'. This is even more desirable since native JavaScript code can be inserted at any point in the Python source, using a compiler directive.

The isomorphism between Python and the JavaScript code generated by Transcrypt is illustrated by the following fragment using multiple inheritance.

    class C (A, B):
        def __init__ (self, x, y):
            A.__init__ (self, x)
            B.__init__ (self, y)
            
        def show (self, label):
            A.show (self, label)
            B.show (self, label)

   translates to:

    var C = __class__ ('C', [A, B], {
        get __init__ () {return __get__ (this, function (self, x, y) {
            A.__init__ (self, x);
            B.__init__ (self, y);
        });},
        get show () {return __get__ (this, function (self, label) {
            A.show (self, label);
            B.show (self, label);
        });}
    });

Striving for isomorphic translation has limitations, rooted in subtle, but sometimes hard to overcome differences between the two languages. Whereas Python allows lists to be concatenated with the + operator, isomorphic use of this operator in JavaScript result in both lists being converted to strings and then glued together. Of course a + b could be translated to __add__ (a, b), but since the type of a and b is determined at runtime, this would result in a function call and dynamic type inspection code being generated for something as simple as 1 + 1, resulting in bad performance for computations in inner loops. Another example is Python's interpretation of 'truthyness'.  The boolean value of an empty list is True (or rather: true) in JavaScript and False in Python. Dealing with this globally in an application would require every if-statement to feature a conversion, since in the Python construct if a: it cannot be predicted whether a holds a boolean or somthing else like a list So if a:  would have to be translated to if( __istrue__ (a)), again resulting in slow performance if used in inner loops.

In Transcrypt, compiler directives embedded in the code (pragmas) are used control compilation of such constructs locally. This enables writing matrix computations using standard mathematics notation like M4 = (M1 + M2) * M3, at the same time not generating any overhead for something like perimeter = 2 * pi * radius. Syntactically, pragma's are just calls to the __pragma__ function, executed compile time rather than run time. Importing a stub module containing def  __pragma__ (directive, parameters): pass allows this code to run on CPython as well, without modification. Alternatively, pragmas can be placed in comments.

Unifying the type system while avoiding name clashes

Another fundamental design choice for Transcrypt was to unify the Python and the JavaScript type system, rather than have them live next to each other, converting between them on the fly. Data conversion costs time and increases target code size as well as memory use. It burdens the garbage collector and makes interaction between Python code and JavaScript libraries cumbersome.

So the decision was made to embrace the JavaScript world, rather than to create a parallel universe. A simple example of this is the following code using the Plotly.js library:

  __pragma__ ('jskeys')    # For convenience, allow JS style unquoted string literals as dictionary keys
    
    import random
    import math
    import itertools
    
    xValues = [2 * math.pi * step / 200 for step in range (201)]
    yValuesList = [
        [math.sin (xValue) + 0.5 * math.sin (xValue * 3 + 0.25 * math.sin (xValue * 5)) for xValue in xValues],
        [1 if xValue <= math.pi else -1 for xValue in xValues]
    ]
    kind = 'linear'
    Plotly.plot (
        kind,
        [
            {
                x: xValues,
                y: yValues
            }
            for yValues in yValuesList
        ],
        {
            title: kind,
            xaxis: {title: 'U (t) [V]'},
            yaxis: {title: 't [s]'}
        }
    )        

Apart from the pragma allowing to leave out the quotes from dictionary keys, which is optional and only used for convenience, the code looks a lot like comparable JavaScript code. Note the (optional) use of list comprehensions, a facility JavaScript still lacks. The fact that Python dictionary literals are mapped to JavaScript object literals is of no concern to the developer; they can use the Plotly JavaScript documentation while writing Python code. No conversion is done behind the scenes. A Transcrypt dict IS a JavaScript object, in all cases.

 In unifying the type systems, name clashes occur. Python and JavaScript strings both have a split (), but their semantics have important differences. There are many cases of such clashes and, since both Python and JavaScript are evolving, future clashes are to be expected.

To deal with these, Transcrypt supports the notion of aliases. Whenever in Python <string>.split is used, this is translated to <string>.py_split, a JavaScript function having Python split semantics. In native JavaScript code split will refer to the native JavaScript split function as it should. However, the JavaScript native split method can also be called from Python, where it is called js_split. While methods like these predefined aliases are available in Transcrypt, the developer can define new aliases and undefine existing ones. In this way any name clashes resulting from the unified type system can be resolved without run time penalty, since aliases do their work compile time.

Aliases also allow generation of any JavaScript identifier from a Python identifier. An example is the $ character, that is allowed as part of a name in JavaScript but forbidden in Python. Transcrypt strictly conforms Python syntax and is parsed by the native CPython parser, making its syntax identical. A piece of code using JQuery may look as follows:

__pragma__ ('alias', 'S', '$')
    
    def start ():
        def changeColors ():
            for div in S__divs:
                S (div) .css ({
                    'color': 'rgb({},{},{})'.format (* [int (256 * Math.random ()) for i in range (3)]),
                })
    
        S__divs = S ('div')
        changeColors ()
        window.setInterval (changeColors, 500)

   

Since Transcrypt uses compilation rather than interpretation, imports have to be decided upon compile time, to allow joined minification and shipment of all modules involved. To this end C-style conditional compilation is supported, as can be seen in the following code fragment:

__pragma__ ('ifdef', '__py3.6__') 
    import dashed_numbers_test          # Import only  for Python 3.6, that supports them
__pragma__ ('endif')

The same mechanism is used in the Transcrypt runtime to switch between JavaScript 5 and JavaScript 6 code:

  

    __pragma__ ('ifdef', '__esv6__')
                for (let aClass of classinfo) {
    __pragma__ ('else')
                for (var index = 0; index < classinfo.length; index++) {
                    var aClass = classinfo [index];
    __pragma__ ('endif')

In this way optimizations in newer JavaScript versions are taken into account, retaining backward compatibility. In some cases, the possibility for optimization is preferred over isomorphism:

    # Translate i += 1 to i++ and i -= 1 to i--
    if type (node.value) == ast.Num and node.value.n == 1:
        if type (node.op) == ast.Add:
            self.emit ('++')
            return
        elif type (node.op) == ast.Sub:
            self.emit ('--')
            return

Some optimizations are optional, such as the possibility to activate call caching, resulting in repeated calls to inherited methods being done directly, rather than through the prototype chain.

Static versus dynamic typing: Scripting languages growing mature

There has been a resurgence in appreciation of the benefits of static typing, with TypeScript being the best known example. In Python, as opposed to JavaScript, static typing syntax is an integral part of the language and supported by the native parser. Type checking itself, however, is left to third party tools, most notably mypy, a project from Jukka Lehtosalo with regular contributions of Python initiator Guido van Rossum. To enable efficient use of mypy in Transcrypt, the Transcrypt team contributed a lightweight API to the project, that makes it possible to activate mypy from another Python application without going through the operating system. Although mypy is still under development, it already catches an impressive amount of typing errors at compile time. Static type checking is optional and can be activated locally by inserting standard type annotations. A trivial example of the use of such annotations is the mypy in-process API itself:

def run(params: List[str]) -> Tuple[str, str, int]:
    sys.argv = [''] + params

    old_stdout = sys.stdout
    new_stdout = StringIO()
    sys.stdout = new_stdout

    old_stderr = sys.stderr
    new_stderr = StringIO()
    sys.stderr = new_stderr

    try:
        main(None)
        exit_status = 0
    except SystemExit as system_exit:
        exit_status = system_exit.code

    sys.stdout = old_stdout
    sys.stderr = old_stderr

    return new_stdout.getvalue(), new_stderr.getvalue(), exit_status

As illustrated by the example, static typing can be applied where appropriate, in this case in the signature of the run function, since that is the part of the API module that can be seen from the outside by other developers. If anyone misinterprets the parameter types or the return type of the API, mypy will generate a clear error message, referring to the file and line number where the mismatch occurs.

The concept of dynamic typing remains central to languages like Python and JavaScript, because it allows for flexible data structures and helps to reduce the amount of source code needed to perform a certain task. Source code size is important, because to understand and maintain source code, the first thing that has to happen is to read through it. In that sense, 100 kB of Python source code offers a direct advantage over 300 kB of C++ source that has the same functionality, but without the hard to read type definitions using templates, explicit type inspection and conversion code, overloaded constructors and other overloaded methods, abstract base classes to deal with polymorphic data structures and type dependent branching.

For small scripts well below 100kB source code and written by one person, dynamic typing seems to only have advantages. Very little planning and design are needed; everything just falls into place while programming. But when applications grow larger and are no longer built by individuals but by teams, the balance changes. For such applications, featuring more than roughly 200kB source code, the lack of compile time type checking has the following consequences:

  1. Many errors are only caught at runtime, often late in the process, making remedies more expensive, since they influence more code already written.
  2. Module interfaces tend to be open to several interpretations, due to the lack of type information they carry. This means that more development time is consumed by consultation between team members to establish the correct use of a module API.
  3. Especially when working with a large team, dynamically typed interfaces can lead to unwanted coupling of design decisions taken in distinct modules. Thin, well specified interfaces become a necessity.

An interface featuring even one parameter that may refer to a complex, dynamically typed object structure, cannot be considered sufficiently stable to warrant separation of concerns. While this type of 'who did what, why and when' programming accounts for tremendous flexibility, it also accounts for design decisions being postponed to the very last, impacting large amounts of already written code, requiring extensive modifications.

The 'coupling and cohesion' paradigm applies. It's OK for modules to have strong coupling of design decisions on the inside. But between modules there should preferably be loose coupling, a design decision to change the inner workings of one module should not influence the others. In general, this leads to the following rules of the thumb for the choice between dynamic and static typing.

  1. Inside a particular module design decisions are allowed to be coupled. Designing it as a cohesive entity will result in less source code to read through and ease experimentation with different implementations. Dynamic typing is an effective means to this end, imposing minimum design time overhead at maximum flexibility.
  2. On the boundaries between modules, developers will have draw up stable 'contracts' on what information to exchange exactly. In this way they can work in parallel without constant deliberation and aim for a fixed, rather than a moving target. Static typing fits the bill here, allowing formal, machine validated agreement upon which information crosses the API.

So while the current surge in static typing may seem like a regression, it isn't. Dynamic typing has earned its place and it won't go away. The opposite is also true: even a traditionally statically typed language like C# has absorbed dynamic typing concepts. But with the complexity of applications written in languages like JavaScript and Python growing, effective modularization, cooperation and unit validation strategies gain importance. Scripting languages are coming of age.

Why choose Python over JavaScript on the client?

Due to the immense popularity of programming for the web, JavaScript has drawn lots of attention and investment. There are clear advantages in having the same language on the client and on the server. An important advantage is that it becomes possible to move code from server to client in a late stage, when an application is upscaled. 

Another advantage is unity of concept, allowing developers to work both on the front end and the back and without constantly switching between technologies. The desirability of decreasing the conceptual distance between the client and server part of an application has resulted in the popularity of a platform like Node.js.  But at the same time, it carries the risk of expanding the 'one size fits all' reality of current web client programming to the server. JavaScript is considered a good enough language by many. Recent versions finally start to support features like class based OO (be it in the form of a thin varnish over its prototyping guts), modules and  namespaces. With the advent of TypeScript, the use of strict typing is possible, though incorporating it in the language standard is probably some years away.

But  even with these features, JavaScript isn't going to be the one language to end all languages. A camel may resemble a horse designed by a committee, but it never becomes one. What the browser language market needs, in fact what any free market needs, is diversity.  It means that the right tool can be picked for the job at hand. Hammers for nails, and screwdrivers for screws. Python was designed with clean, concise readability in mind right from the start. The value of that shouldn't be underestimated.

JavaScript will probably be the choice of the masses in programming the client for a long time to come. But for those who consider the alternative, what matters to continuity is the momentum behind a language, as opposed to an implementation of that language.  So the most important choice is not which implementation to use, but which language to choose. In that light Python is an effective and safe choice. Python has a huge mindshare and there's a growing number of browser implementations for it, approaching the golden standard of CPython closer and closer while retaining performance.

While new implementations may supersede existing ones, this process is guided by a centrally guarded consensus over what the Python language should entail. Switching to another implementation will always be easier than switching to the next JavaScript library hype or preprocessor with proprietary syntax to deal with its shortcomings. Looking at the situation in the well-established server world, it is to be expected that multiple client side Python implementations will continue to exist side by side in healthy competition. The winner here is the language itself: Python in the browser is there to stay.

About the Author

Jacques de Hooge MSc is a C++/Python developer  living in Rotterdam, the Netherlands. After graduating from the Delft University of Technology, department of Information Theory, he started his own company, GEATEC engineering, specializing in Realtime Controls, Scientific Computation, Oil and Gas Prospecting and Medical Imaging. He is a part-time teacher at the Rotterdam University of Applied Sciences, where he teaches C++, Python, Image Processing, Artificial Intelligence, Robotics, Realtime Embedded Systems and Linear Algebra. Currently he's developing cardiological research software for the Erasmus University in Rotterdam. Also he is the initiator and the lead designer of the Transcrypt open source project.

Rate this Article

Adoption
Style

BT
小孩肠系膜淋巴结炎吃什么药 牙齿变黑是什么原因 感叹号像什么 什么泡水喝降甘油三酯 把碗打碎了有什么征兆
初字五行属什么 魔性是什么意思 花木兰代表什么生肖 准确值是什么意思 釜底抽薪是什么意思
血色素低吃什么补得快 为什么月经一次比一次提前 鱼的五行属什么 相敬如宾是什么意思 五月二十五是什么星座
委曲求全是什么生肖 高送转是什么意思 梅花什么时候开 嗓子老有痰是什么原因 财代表什么生肖
吃什么都吐是什么原因hcv8jop0ns4r.cn 孩子老是流鼻血是什么原因hcv9jop3ns0r.cn 什么样的眼睛travellingsim.com 预调酒是什么意思hcv9jop8ns0r.cn 甲状腺属于什么科室hcv8jop1ns5r.cn
什么花是白色的hcv9jop6ns3r.cn 舌头辣辣的是什么原因hcv9jop3ns0r.cn 10月20是什么星座hcv9jop5ns2r.cn 甲状腺结节吃什么中药hcv8jop9ns9r.cn 关心则乱是什么意思hcv8jop9ns5r.cn
做梦梦见死去的亲人是什么意思hcv9jop0ns1r.cn 疝气看病挂什么科hcv9jop1ns5r.cn 飞黄腾达是什么生肖hcv8jop4ns3r.cn 邕是什么意思hcv7jop7ns3r.cn 捐精有什么要求hcv8jop6ns6r.cn
一什么场面hcv9jop4ns6r.cn 喝什么茶好hcv8jop9ns9r.cn 两个人在一起的意义是什么beikeqingting.com 为什么腰疼hcv7jop5ns2r.cn 蹄花是什么hcv8jop1ns1r.cn
百度