Celedev Blog Archive

Old posts that were originally published on celedev.com

Celedev CodeFlow has now been renamed Bounces.

Some posts in this section may be outdated or not relevant anymore.
Please refer to the Home page and the Documentation section for current information about Bounces.

When Swift meets Lua


The recently-published RedMonk Programming Language Rankings for Q1 2015 provides interesting figures about the relative popularity of programming languages. Stephen O'Grady writes about it:

The idea is not to offer a statistically valid representation of current usage, but rather to correlate language discussion (Stack Overflow) and usage (GitHub) in an effort to extract insights into potential future adoption trends.

Probably one of the most significant trend in this ranking is the fantastic growth of Swift, the brand new language that Apple introduced at WWDC 2014. In just over seven months, Swift has jumped from nothing to rank 22, and is now at parity with Lua (at rank 23).

RedMonk Top Programming Language Rankings

It goes without saying that this ranking parity between between Swift and Lua is temporary, and we can expect Swift to continue raising in the future rankings.

Nevertheless, having Swift and Lua at parity is an nice coincidence, because Lua is the language we use for live-coding iOS applications in CodeFlow, and more interestingly because both Lua and Swift are two great programming languages that show almost opposite design choices in many areas, and turn out to be very complementary and effective in the job of developing iOS apps.

To illustrate this, let's compare Lua and Swift on a few key aspects.

Simplicity vs. complexity

One thing I like about Lua is the simplicity of the language: the entire Lua 5.2 grammar fits in about 50 lines (or 2 pages in a book). This makes the language really easy to learn, and very logical and pleasant in the daily use. Sure, Lua does not have many fancy language constructs, but everything you need is there, and Lua code tends to stay reasonably concise. And on the performance side, this deliberate minimalism helps to keep the Lua compiler and runtime small and fast, which is a valuable quality for an embedded language.

For Swift, the design team has chosen the exact opposite option: build into the language a large set of syntactic constructs, in which you can almost always find one that fits your needs in a given situation. This makes Swift a very powerful language, and most iOS developers I know are really excited about Swift. But it comes at the price of a high complexity: the Swift grammar takes 20 pages in the book The Swift Programming Language and learning Swift is not a matter of one day or two.

A complex language needs a complex and clever compiler, and Swift is no exception to the rule: Apple has certainly put a massive effort on the Swift compiler, capitalizing on the work they did for llvm and clang, and Swift code execution performances rely heavily on compiler optimizations, as shown by many benchmarks on the web comparing Swift and Obj-C performances in debug and release modes. The language sophistication and its needs for code optimization result in a more CPU-demanding compilation and in a probably higher memory usage by the compiler. But for a compiler designed to be used inside Xcode or from the command line, and not supposed to be embedded in a target application, this choice is fully consistent and (reasonable) CPU/memory consumption is not an issue in this case.

Dynamic vs. compile-time decisions

Lua is a dynamic language, meaning that most decisions that affect the code and data structure of the program are made dynamically at runtime, instead of being pre-calculated during the compilation. For example, Lua's main data structure, the Lua table, is a dictionary that doesn't impose any restriction on the types of acceptable keys or values; it is therefore possible at any time to add a property or a method to an object defined as a Lua table. Another example: when compiling a Lua code chunk, Lua doesn't need any context information about this code chunk's source code dependencies; the result of the compilation is just a regular function that can be stored in any variable or called immediately, as decided by the program loading the code chunk.

This dynamicity brings to Lua the same advantages and issues as in other dynamic languages: a huge freedom and flexibility in your code, which is especially great for live coding, but almost no static check to help you detect obvious errors in your code before executing it.

Swift, on the other hand, is all about compile-time checking and ensuring the safety of your code as much as it can. Which is really good for the safety of your code, and probably not so good for your creativity, since it obliges you to make your code base fully consistent before you start executing it.

Therefore the Swift compiler needs lots of context information when compiling a source file, like the definitions of all external entities used by the compiled source code: modules, other classes... All this information helps the compiler to generate better optimized code than in a dynamic approach. But when the code is running, you can not set a property to an object or change a method in a class (or at least not with the language).

Of course, Swift has some dynamic features, like optionals (variables that can be nil), the AnyObject type (needed for Obj-C interoperability), or failable initializers. But compile-time checks are really at the heart of the language. And especially aspects related to type-checking...

Variables vs. values typing

For the developer, probably the most visible difference between Lua and Swift is the way they handle typing.

Swift relies on variables typing. Swift has a strong, but rather classic, object-oriented typing system, and an important part of Swift compile-time check rules are related to guarantying the consistency of variables usage with the corresponding variable declaration types.

On the other side, in Lua, variables are not typed, only values are. Which mean that every value belongs to one of the 8 base types defined by Lua, and that a value always carries its own type with it. A Lua variable is simply a neutral container that can accept a value of any type. This is very flexible, but it puts on the developer's shoulders the task of checking the actual type of a variable, where necessary in the code.

Similarities

Actually Lua and Swift are not opposite in every aspect. On some points, they are even quite close. Here are some examples:

  • None of them is derived from C, so they do not suffer from C major flaws: Lua syntax was originally inspired by Niklaus Wirth's Modula languages, and for Swift, its designers made the courageous and excellent decision to drop C compatibility, and to create a brand-new safer state-of-the-art programming language.

  • Both include a certain level of extensibility in their syntax: in Lua you can do rather important customization (e.g. defining your own object model in Lua) through the clever use of metatables and metamethods; in Swift, language features like operator overloading, custom operators and generics give you the ability to extend the language syntax.

  • In both, functions can have multiple return values: in Lua, a return statement simply accepts a sequence of expressions, e.g. return a, b, c, which is fully consistent with Lua multiple assignment syntax; in Swift, a function can specify multiple return values by specify a tupple as result type, and then use return (a, b, c).

  • Both do not require semicolons at the end of instructions, but accept them to force statement separation if needed.

Beyond the language

The object here is not to claim that Lua is better than Swift, or Swift better than Lua. That would obviously be pointless, as both are great programming languages. What this short comparison shows, however, is that Lua and Swift have strength in different areas, related to their respective philosophies, design choices and implementation tradeoffs.

And actually, the programming language is only a part of a bigger development picture. Another important part of this picture is the IDE. The main role of an IDE is not to provide a text editor showing fancy colors in your source code; it is to make your whole development activity easier and more effective.

To achieve this goal, good IDEs include features that compensate for the main limitations of the programming language used. Examples of this can be found in our preferred IDEs: Xcode has the Playground for Swift, that allows you to interactively develop and experiment simple Swift programs; and CodeFlow adds extensive runtime checks to Lua when invoking native methods, that brings type errors detection and preserve the stability of the target app during live development.

Playing with Swift or Lua

If you want to go further and make up your own mind about both languages, here are some valuable resources:

  • For Swift, you can go to Apple Swift Resources page, where you will find lots of documentation and the download link for Xcode, in case you don't already have it. Then create a new playground in Xcode and enter some swift code in it.

  • For Lua, various language documentation can be found on lua.org, and my personal IDE recommendation for writing Lua code is to use CodeFlow, even if you don't target iOS apps. CodeFlow can be downloaded here, and it can be freely used as a pure Lua playground. To do this, create a new Lua project in CodeFlow (Menu File->New) and, in the project window, select the Local Lua Context target to run and debug the code locally inside CodeFlow.

    Local Lua Context in CodeFlow

Comments

  • Craig 2015-01-30 17:28:30

    I highly doubt the GitHub "ranking" of Lua is accurate. All those projects on GitHub where Lua is embedded (but not the majority source language) aren't being counted. Likewise for many C modules and bindings that are specifically made for Lua but still counted by GitHub as being C projects.

Post a Comment


Recent posts

Blog Post
Aug 1, 2016

CodeFlow 1.0.2

CodeFlow 1.0.2 is a minor release that focuses on improving the Live Application Developer's Experience.

Aug 1, 2016
Blog Post
Jun 16, 2016

CodeFlow 1.0.1 and WWDC 2016

The just-released CodeFlow 1.0.1 brings support for the new iOS 10, tvOS 10 and macOS 10.12 announced at WWDC 2016 this week.

Jun 16, 2016
Blog Post
Jun 9, 2016

CodeFlow turns 1.0

It has been some time since the last beta of CodeFlow, version 0.9.20 was released in January this year. And all this time, we have worked very hard to improve CodeFlow, and to turn it into an effective Application Development System that we love to…

Jun 9, 2016
Blog Post
Apr 22, 2016

Live storyboards in CodeFlow

Live storyboards are a important feature of the upcoming CodeFlow 1.0. Mixing the power of Xcode storyboards with the flexibility of CodeFlow live coding, they are amazing for fast, fun and creative live app development.

Apr 22, 2016