A CodeFlow blog
about live coding and more…
A great new feature of CodeFlow 0.9.15 is the automatic creation of Project Bindings Libraries. But what role do Bindings Libs play in CodeFlow? And what make them so important?
Since the very beginning, the main goal of CodeFlow is to bring real interactivity to iOS Apps development. Real interactivity implies a development environment that provides the highest possible level of responsiveness between the writing of the application's source code and the execution of this code on the target device, while giving to the developer access to every capability of the iOS platform and the comfort of using iOS familiar APIs.
The use of Lua as the programming language for dynamic code in CodeFlow comes therefore with the possibility to have access in Lua to the whole iOS SDK. Except for a few low-level frameworks, almost every API, type, classe, protocol and method defined in the SDK can be used in Lua, in a very straightforward and natural way. This is one of CodeFlow's big strengths: be fully transparent regarding the set of APIs usable from the code, avoiding thus the constraints of a proprietary API, and the pitfall of a narrow target application domain.
On the technical side, enabling the Lua code to use SDK native APIs requires some sort of interface components, which are called Bindings Libraries. In CodeFlow a Binding Library is a package containing two kinds of contents: Lua API modules (i.e. Lua source files containing a Lua translation of SDK APIs), and code libraries that will be linked - when needed - with the target application in Xcode. The code in these libraries handles the necessary conversions between a Lua dynamic environment and iOS native system APIs.
This could look a bit complex, but actually the the use of Bindings Libraries is fully transparent for the user. Once you have selected the SDK version that you want to use, CodeFlow takes care of everything: making code writing easier by proposing auto-completion for symbols in the SDK, configuring the Xcode project of the target application, so that it embeds the framework and bindings libraries needed by the Lua code... These things are automatically done, so you don't need to bother with bindings management.
Therefore Bindings Libraries are an essential component of a dynamic application development system like CodeFlow, because they act as a transparent communication path between the dynamic code and the rest of the system.
Accessing Application-Specific APIs
And for accessing application-specific APIs from Lua, how does that work?
In previous CodeFlow versions, prior to 0.9.15, it was definitely possible to reference (and to extend) specific compiled classes of the target application from the Lua code, to call their methods, or to use their properties and IBOutlets. In most cases that worked just well, but using such APIs was done somewhat in the blind, without completion support from the Lua editor in CodeFlow, and method calls were done in best-effort mode, relying on the (sometimes insufficient) information available in the Objective-C runtime. Besides, application-specific C types or functions were simply not accessible from Lua.
In a nutshell, before CodeFlow 0.9.15, integration between dynamic code and compiled code in an iOS application was a bit limited…
This is why I am happy to present the great new feature of CodeFlow 0.9.15: dynamic creation of Project Bindings Libraries, providing extended access from Lua to specific types and APIs of the target application.
Project Bindings Libraries, this means that all APIs defined in your application's header files can now be used from your Lua code in CodeFlow, with the same level of transparency and quality that was previously only available for APIs of the system SDK. Naturally, Project Bindings Libraries can also include the APIs of third-party libraries and CocoaPods used in your application project! 😃
Specifically, Project Bindings Libraries give access to the vast majority of symbols defined in .h files belonging to your Xcode project; this includes entities declared as #define, enum, struct, C function, const global variable (e.g. string constants declared as
extern NSString* const), and, of course, Objective-C classes and protocols, with their methods and properties.
Each CodeFlow project has its own Project Bindings Library. This Bindings Library is automatically created and updated, so as to stay in-sync with the target application's Xcode project. You can configure the content of a Project Bindings Library through a dedicated interface in CodeFlow (read below).
Using Project Bindings
In CodeFlow 0.9.15, if a given CodeFlow project has an associated Xcode project, then a Project Bindings Library is automatically created, to provide Lua interfaces for the C and Objective-C APIs defined in this Xcode project. By default the Project Bindings Library includes APIs defined in all .h files of the Xcode project, but the list of visible header files can be modified in the corresponding Bindings Editor.
As an example, let's consider a WatchKit test application named WatchApp1, that show the following structure under Xcode:
If we select the Project Bindings Library in the associated CodeFlow project, we can see the Bindings Editor for it. The Bindings Editor presents a file tree that mirrors the Xcode project structure and that contains every .h file in this project.
Each .h file (and each group) can be individually selected or unselected, and only APIs declared in selected header files will be included in the Project Bindings Library. In this example, we are only interested in APIs in the "WatchKit Extension" group; so we have unchecked the "WatchApp1" group in the list.
In addition to the selection checkbox, the Bindings Editor displays for every header file in the project:
- a QuickLook button that shows a preview of the .h header file;
- a Bindings-generation-result indicator for this file: green in case of success, yellow if warnings were emitted during the generation, red if the generation did fail, or gray if the generation did not take place; a click on this indicator displays detailed information about the status;
- a direct access button to the generated Lua module API.
Project Bindings Libraries are automatically updated if one of the selected .h files is modified, or if the contents of the associated Xcode Project is changed (e.g. if you add a new .h file in the project). Conversely when you change the list of selected header files in the Bindings Editor, you have to explicitly tell CodeFlow to update the Bindings Library, by either clicking on the Refresh button in the Bindings Editor or by selecting the Update Lua Bindings… command in the Program menu.
And, well… that's about all you need to know for using this new Project Bindings feature in CodeFlow.
The actual usage of the Project Bindings Library in your code is transparently managed by CodeFlow, just as with SDK Bindings Libraries. Project APIs are added to code-completion proposals; Project Bindings code libraries are automatically added to the associated Xcode project if needed; and, during the target app execution, project-specific data are created with the expected types, project methods and function are called with the specified parameter types…
All this is made possible by Bindings Libraries. In CodeFlow they are an essential component of the live-coding system, almost invisible but so important. And with CodeFlow 0.9.15 and Project Bindings Libraries, live coding on iOS takes a major feature boost. And really, for the developer, It just works!
One feature that was missing to CodeFlow until now was true auto-completion of Lua code, i.e. code completion proposals appearing automatically as you type your code, without having to hit the
esc key first. Automatic code-completion is probably one of the most important editor features for bringing more comfort and effectiveness to the code-writing experience, and it has been on my to-do list for some time.
And this is precisely the main new feature of the just-released CodeFlow v0.9.12. In this version, code completion proposals appear while typing code, and they can usually be validated with a minimum number of key presses: typically, when the appropriate completion is selected, you can just continue entering the code after the completed word, like in this short example.
And, if you don't like it, automatic code completion can be disabled in the application preferences.
On the debug side, the Lua command editor also features automatic code completion, but there is more: code completion the Lua command editor is now aware of the current callstack-context . What this means is that, when stopped on a breakpoint, you can very easily write commands containing local variables or other symbols available at the line where the selected callstack level is stopped, without worrying about not misspelling variables or method names, as those will be proposed by auto-completion.
And the code editor behavior in case of syntax error in a Lua file has been improved too: code completion now takes into account field and method names defined after the error location; syntax-aware selection, code coloring and variables highlights, all work in the whole source file in case of syntax error. All this is really useful, because transitory syntax errors are quite inevitable when writing code, or dynamically modifying existing code in live coding mode!
As usual, CodeFlow v0.9.12 can be downloaded from celedev's support page or by using the software-update check feature in CodeFlow.
mdevcon is a great mobile developers conference that takes place every spring in Amsterdam. It focuses not only on iOS, but also on Android and other mobile platforms. The location in Tuschinski Theater in the center of Amsterdam is fantastic, there are plenty of very good talks during the two days of the conference, and with the organization in multiple tracks, you can always find at least one you are interested in.
And, even more important, attendees and speakers are very friendly and passionate about development. I was there last year and I had great conversations with many people during the breaks and evenings.
This are probably the reasons why mdevcon has been put by Ray Wenderlich in the Top 10 iOS Conferences in 2015.
And I'm very pleased to announce today that celedev is a sponsor of mdevcon 2015. If you can come to Amsterdam on March 5-6 2015, mdevcon is definitely worth attending, and I will be happy to meet you there!
It has been almost two weeks since I released CodeFlow 0.9.10 and it is more than time for me to write a few words about the changes in this version.
CodeFlow v0.9.10, that can be downloaded here, is mostly focused on improving the debug experience when developing code in Lua.
The Lua Command Editor can now interpret commands in the context of the currently-selected call-stack frame. This means that the Command Editor can execute virtually any sequence of Lua code, that would be valid at the current line of the selected call-stack function. Executed code has read / write access to all variables visible at the current source location: this includes local variables, up-values, var-args and free names (i.e. Lua env-aware globals).
CodeFlow also features an improved Variables Inspector that displays more information about the current state of your program: it allows the visualization of masked local variables, and the display of custom Lua environments. In addition, the Variables Inspector now includes a simple type-aware variable editing capability, and other small improvements that make it easier to use and very reliable.
I will illustrate these debug features with a simple screenshot of a test program:
Here the execution is stopped at line 23 in a function named
square, where a lot of variable masking takes place.
To start with, the function defines a local environment on line 12, that masks the inherited
_ENV up-value (that was set at line 4); you can see in the Variable Inspector that the masked _ENV up-value is dimmed but still accessible, and you can easily identify the active _ENV, which is a local variable.
In addition, many variables in the
square function are named
x. This is really confusing and certainly not a good programming practice, but this is still syntacticly-valid Lua code. Fortunately, the CodeFlow Variable Inspector will help you to clarify things.
x in the list is not dimmed, so it is the active variable
x; its value has been modified by the last step in the code, as indicated by the yellow highlight on the Craig value. Other variables called
x are dimmed, so they are masked; you can locate any them precisely in the source code by selecting it in the variable inspector, like here the
xwith value Bob: we can see that it is set on line 21 and never read.
Now, we can have a look at the Lua Command Editor, in the Lua Console pane. The Lua Console title indicates the context in which the command will be executed, here in function square, line 23. The code of the command is colored appropriately for this context, so it is easier to detect typing errors: you can see that
x is colored as a local variable, which is precisely what we expect.
What happens if we execute the command?
We can see that the values of variables
x have been modified (highlighted in yellow), and the console output contains the string printed by the command, with the right value for
In addition to these debug-related improvements, CodeFlow v0.9.10 fixes a number of bugs in various parts of the system and improves the reliability of the connection between CodeFlow and target iOS device running the application.
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).
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
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.
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.
CodeFlow 1.0.2 is a minor release that focuses on improving the Live Application Developer's Experience.
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.
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…
Still a work in progress, but it took me only a few hours to reach this point, while keeping it compatible with macOS 10.11+ 😎
CodeFlow = live-code native iOS apps in Lua celedev.com
The approval process took less than 24 hours. 😎
#LuaLang #livecoding #iOS
Thanks @alf147 for reporting the issue! 😀
Check for update in CodeFlow, or download version 1.2.2 from celedev.com/en/download/.
To get it from GitHub: github.com/celedev/LuaPan…
Check for update in the appplication,
or download it from celedev.com/en/download/,
or simply read about the changes here: celedev.com/en/download/co…
Version 1.2 of CodeFlow is out, with lots of improved features, for a unique interactive native app development experience. 😀
- download celedev.com/en/download/
- changelog celedev.com/en/download/co…
🛠 Download updated OS SDK bindings from celedev.com/en/download/
Check for update or celedev.com/en/download/
Slides of my talk at Lua Workshop 2016 are here: slideshare.net/jljumpertz/pro…
A SceneKit 3D game in #LuaLang with dynamic update of all 3D assets and code
⚡️ Live SceneKit assets, Sierra support, and more…