The Swift Programming Language Kick Start

programming
swift

#1

Dear Manjaro users,

I have been investing some time in learning a new language that suited my particular needs and came across Swift. Since it fits for the purpose of automating some tasks in my type of research and it is now gaining progressive traction, including with useful bindings to known and batted Linux libraries, it might be perhaps useful to other users to know about it.

Discussing with other Linux users a month ago, it was told to me that the reason Swift did not get traction in this community was mainly because it is backed by a large corporation (Apple), thus would never really take any place among us, like C and Rust did, as these are very much linked to the open source communities. Regardless of these points, which may be reasonable, I think that Swift still has some interesting aspects that are worth investigating.

First, it has a first class scripting ability. Its unbeknownst between Linux users that Swift can be used to automation of tasks in the system (provided, of course, it is installed). Second, Swift offers mature enough bindings to known GNU libraries like Glibc. Third, some binding to Gtk is available. Fourth, creation of modules from extant C code is a breeze. It is commonly said that Vala binds perfectly with other C tools, but Swift modules are at least as easy to write as VAPIs. Moreover, some people will be happy to discover that Swift is statically typed and allow writing beautiful expressive code (either in oop or functional design) with first-class lambda/closures support.

This text aims at helping the curious get going with the language in Manjaro. No batteries are included, I am not myself an experienced developer, but I am a statistician that needs to concatenate and automate some command line tools. The strength of Swift is that it allows me to learn one syntax and apply it in my small Gtk tools and all my scripts. There is no learning curve of a new language only to automation and another to robust compiled programs.

Installation

As expected, installation is a no-brainer in Manjaro due to the multiple options upstream offers. In the AUR, my suggestion is:

yaourt -Sy swift swift-lldb

Note that the above command may take hours to compile, as it pulls the source code of the language and build it in your system. It is much faster to install swift-bin if you don’t want too much commitment.

One workflow

There are multiple ways of setting a programming worklfow, probably someone will yell Vim or Emacs, but below is a Sublime Text 3 workflow, just because.

In ST3 install the following packages for basic support:

  • swift for the syntax highlighting,
  • zeal for documentation (you have to install zeal in the system with sudo pacman -Sy zeal open the app and install the swift’s and glibc’s documentation).
  • Sublime REPL for a basic REPL, which is now a bit buggy. This step is optional because it is not mature enough,
  • SublimeLinter
  • SublimeLinter-contrib-tailor and install tailor in the system with pacman -Sy tailor
  • SwiftFoundationCompletions for basic completions.

Setting the REPL (optional)

Launch the Command Palette and browse the packages. Find the SublimeREPL directory and create a /Swift directory.

Inside this directory, create the file Default.sublime-commands with the following content (1):

[
    {
        "caption": "SublimeREPL: Swift",
        "command": "run_existing_window_command", "args":
        {
            "id": "repl_swift",
            "file": "config/Swift/Main.sublime-menu"
        }
    }
]

Finally, create a second file Main.sublime-menu with the contents:

[
    {
        "id": "tools",
        "children":
        [{
            "caption": "SublimeREPL",
            "mnemonic": "r",
            "id": "SublimeREPL",
            "children":
            [
                {"command": "repl_open",
                 "caption": "Swift",
                 "id": "repl_swift",
                 "args": {
                    "type": "subprocess",
                    "external_id": "swift",
                    "encoding": "utf8",
                    "cmd": {
                            "osx": ["/Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift"],
                            "linux":["swift"]},
                    "cwd": "$file_path",
                    "additional_scopes": ["swift"],
                    "syntax": "Packages/Swift/Syntaxes/Swift.tmLanguage"
                    }
                }
            ]
        }]
    }
]

Scripting

Once it is all set, you can test the scripting capabilities of the language. Test with the code below. This is a function that executes echo in the bash environment.

#! /usr/bin/swift

import Foundation

func execCommand(command: String, args: [String]) -> String {
    if !command.hasPrefix("/") {
        let commandFull = execCommand(command: "/usr/bin/which", args: [command]).trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
        return execCommand(command: commandFull, args: args)
    } else {
        let proc = Process()
        proc.launchPath = command
        proc.arguments = args
        let pipe = Pipe()
        proc.standardOutput = pipe
        proc.launch()
        let data = pipe.fileHandleForReading.readDataToEndOfFile()
        return String(data: data, encoding: String.Encoding.utf8)!
    }
}

let commandOutput = execCommand(command:"/usr/bin/echo", args:["Hello, I am here!"])
print("Command output: \(commandOutput)")

Cool, isn’t it?

Hopefully this simple example is enough to kick start.

Compiling

Swift was released to Linux with a new building system, which was different from the one in offered in native Darwin. It depends on a particular directory structure. So take the previous code and copy in a Sources subdirectory with the name main.swift. Remember to comment the first line, the shebang. In the base directory create a Package.swift file with the content below. Note that this building file has to be valid Swift code. In order to build it, issue the command swift build in the base directory.

import PackageDescription

let package = Package(
    name: "ExecuteSomething"
)

If all worked out ok, the compiler will declare where it saved the binary. In my case it was: Linking ./.build/debug/ExecuteSomething. Sure enough, executing the binary resulted in the message:

Command output: Hello, I am here!

Little Gtk example

Perhaps you are more interested in Qt, it would be excellent to bind it to Swift, however I did not find instructions on how to do that. Instead, this example will allow you to have a look into importing C modules into Swift.

Clone the following repository:

git clone https://github.com/TomasLinhart/SwiftGtk

Build it with swift build and it will complain of CGtk bindings missing headers, then navigate into /SwiftGtk/.build/checkouts/CGtk-Linux-1241398140629683141/ and edit the file headers.h to include the below:

#include <sys/types.h>

This should be the last step, building now will work properly as we pointed to the correct headers. Execute the file and you may have a nice Gtk window with a simple button. Make sure to read the module.modulemap files in /SwiftGtk/.build/checkouts/CGtk-Linux-1241398140629683141 to understand how C libraries are imported.

Conclusion

This is a kick starter for Manjaro users interested in learning a new language, hopefully this will ease the process of building a workflow. Note that you can get help by using Zeal, as suggested. The Zeal package in Sublime Text allows you to search for help off-line on the go. Other important sources are:


#2

NEVER use sudo with yaourt.


#3

Why would you recommend Swift over Python?

You say one of the advantages is one language to do it all. But that’s also what Python has been doing for everyone, and moving to Swift would seem to run against that very advantage. Similarly, why Swift for statisticians, if that is precisely one of the strongest and one of the most widely used set of libraries for Python, from universities to businesses? And I would risk, that Python is one of the most widely used languages for statisticians anywhere.

I suppose if I have not been exposed to Python yet, I may find something interesting to look at in Switf. But as a Python user, so far Swift barely scratches the requirements to make it a language worth investigating. There are many things I don;t like in Python, mind you. And I’m very critical about the direction it is taking. So this isn’t me being a mindless fanboy. Trust me, I’d happily move away from Python if I was shown something worth it. I’m trying to look at it from a practical point of view. And that is basically that Swift doesn’t seem to carry enough weight yet to challenge the features and usability of Python.


#4

Updated


#5

There is no reason to use one over the other. It just fits my needs and I figured I could help out someone interested in the language. Python is excellent, if you are used to it, stick to it.

Oh, about stats, python is obviously far superior now. I don’t use python, but R and have created some command line R tools that I connect using Swift.

Note that Swift creates performant executables.


#6

Ok, fair enough. I may have misinterpreted your intentions. Seemed to me you were advocating for the language as an alternative to other solutions on Linux. That warrants a debate on the advantages and disadvantages. But it this is instead about “it works for me” without much explanation of why it does, then I guess there is indeed nothing to debate here.


#7

i recommend to move this great post into the tutorials section


#8

After compilation, what are the program dependencies if I want to distribute it (on aur) ?


#9

None, I guess. It’s a pretty simple job.


#10

You’ll require the swift runtime library if compiling your program normally, which defaults to a dynamically linked runtime. However you don’t normally distribute it with your Swift programs; i.e. you expect the user to have the Swift runtime installed or package maintainers to list it as a dependency that gets automatically installed. So, for instance, your Github Swift project release tarballs do not include the runtime.

You can however compile the runtime statically with -static-stdlib, or -Xswiftc -static-stdlib if using the build command. This works because a swift executable is 1st class ELF binary. But I’d advise against this on a linux system, since your users are expected to have the runtime installed sooner or later, because it takes only one Swift executable that links dynamically to the runtime to be installed on the user machine, for your statically linked library to become redundant.