Home About Eric Topics SourceGear

2021-07-26 12:00:00

Alpaca Preview: Native Swift with ASP.NET Core

I have pushed up nuget packages for a preview version (0.1.10) of SourceGear.Alpaca.Swift.SDK. Yes, I said "Alpaca" rather than "Llama". So I should probably explain...

What is Alpaca? (starting from Llama)

My Llama project has grown to have two major pieces:

Llama takes its name from the first of these two pieces, because it has been the core concept, and because that piece is LLVM-centric, and because the word "Llama" starts with two L's, and because naming things is hard, so I saw no reason to be more creative.

But I recently realized that the second piece could be used without the first. I should probably have figured this out sooner.

My "LLVM bitcode to CIL" approach results in a strange kind of code which has no common name.

For the moment, let's just call it "purple code". Over time, I have noticed that, with respect to interop with the CLR, the rules for purple code are awfully similar to the rules for native code.

And the thing I only recently realized is that those rules are not merely "similar" -- they are exactly the same.

Which means those bindings could be independent of the core of Llama. Yes, they need to be hooked up in different ways, but aside from that, they can be used unchanged with either purple code or native code.

So maybe those bindings deserve a life of their own, an opportunity to explore their place in the world without LLVM-to-CIL stuff.

So the name I am giving to that second piece is "Alpaca".

What is Alpaca?

Alpaca refers to my exploration of "great interop between .NET and other language ecosystems".

What do I mean by "great interop"? For one thing, I'm talking about calling .NET libraries from the other languages. .NET has always had excellent native interop features like P/Invoke, but those features are mostly focused on calling languages like C from C#. I'm talking about the opposite direction.

What if I want to call .NET libraries from native code? What if I want to write my ASP.NET Core web service in Swift instead of C#? Alpaca is about libraries and tooling to make that kind of use case simpler.

Llama SDK vs Alpaca SDK

Earlier I spoke of my project having two major pieces, which I am now calling Llama and Alpaca. The "third piece", which is smaller but more visible, is an MSBuild project SDK that integrates things into the regular dotnet tooling.

In my previous Llama blog entry I showed a simple ASP.NET Core sample written in Swift:

The Llama Swift project SDK makes things work for Swift like they do for C# or F#. There is a Program.swift file and a whatever.swiftproj file. You can do dotnet build, or dotnet run, and so on.

The Alpaca Swift project SDK provides the same user experience, but accomplished in a very different way. Whereas the Llama SDK is compiling the Swift code to CIL, the Alpaca SDK is compiling to a native shared library. Both SDKs then provide their respective scaffolding to hook up the bindings and run the program.

One of my former coworkers often said that "sometimes a software project is like a car which has been disassembled and its parts are scattered on the front lawn". Conceptually, given an ASP.NET Core program in Swift, I could switch between Llama and Alpaca by changing only the .swiftproj file and not the Swift code itself. Right now, some parts of my car are sitting out in the grass, so I can't actually do this. But it should work.

Why did I choose the name "Alpaca"? Because Wikipedia says an alpaca "is similar to, and often confused with, the llama", and I figured this blog entry was going to be darn confusing.

Sample

Inspired by Ben Adams (and building on his attempt with Llama), the sample for this preview is a Swift--Alpaca implementation of the TechEmpower benchmarks (plaintext and json):

https://github.com/ericsink/FrameworkBenchmarks/tree/alpaca/frameworks/Swift/alpaca

Brief summary of the early results: Swift--Alpaca--AspNetCore is Not Terribly Fast. It's maybe a little faster than Swift--Vapor, but neither is in the ballpark of C#--AspNetCore. I don't know yet how much of the blame goes to my bindings as opposed to Swift itself. I'm still digging...

Moving forward

I still describe all this stuff using terms like "side project" and "exploratory project". So I don't do formal planning, and I don't make commitments.

I have no plans to abandon the Llama side of things, but for now, Alpaca is where I have traction, so that's where my current focus is.

And I should also admit that Alpaca differs from Llama in two ways that I find myself thinking about:

Technical requirements for this preview

The last few preview releases of Llama have been Windows-only. This one only supports Linux. I'm using Ubuntu 20.04 with WSL 2 on Windows 10.

The Alpaca Swift SDK needs Swift 5.4. And .NET Core 6 preview 6.

If you want to try the TE benchmarks, you need Docker, but the dockerfile will setup the other prerequisites for you. So you should be able to clone my fork (of Ben's fork) and do this:

./tfb --mode verify --test alpaca
./tfb --mode benchmark --test alpaca

Enjoy!