
What we learned from rewriting our robotic control software in Swift - ingve
http://www.sunsetlakesoftware.com/2015/11/03/what-we-learned-rewriting-our-robotic-control-software-swift
======
svec
This quote is the big takeaway for me:

 _" We use Macs to drive these robots, with control software that was written
in Objective-C. We made the decision to rewrite this software in Swift late
last year, but only after a careful survey of the bugs that had impacted our
customers over the years. That survey revealed that most of these shipped bugs
would have been prevented or detected early in Swift-based code."_

Apparently they were able to categorize their shipped bugs and prevent those
types of bugs from happening again with Swift. That's a very professional
process.

~~~
ska

       That's a very professional process.
    

Sad, but true. Not about the Swift part (I have no opinion there) but about
the analysis and review of shipped bugs.

It should really be "that's an industry standard practice", but a huge amount
of software development seems to be done in ways that don't have any
systematic way to attempt to learn from mistakes.

~~~
sanderjd
This is probably a heretical opinion, but here goes anyway: while it's
definitely great to take the time to do a full analysis of common classes of
bugs, I don't think it is _necessary_ to do so in order to have a good sense
for what common issues a language like Swift solves. I don't need to evaluate
my log of bugs to know that I have been bitten _tons_ of times by having a
null object or pointer at runtime when a compiler could have made sure I was
checking. Languages like Swift and Rust (and Haskell and Ocaml and others)
have protections for this and other no-brainer bug classes that I really don't
think you need a big bug log analysis to see the advantage of.

~~~
AnimalMuppet
Sure, you can see what Swift _solves_ , based on the experience of not writing
in Swift. That doesn't tell you what new kinds of bugs Swift _enables_ ,
though. It's going to take years of using it to find out. You can somewhat
speed that up by doing a full analysis of the bugs you get using the new
language.

~~~
moonchrome
>Sure, you can see what Swift solves, based on the experience of not writing
in Swift.

That's actually not true. You can see the trivial stuff it solves from the
promo materials - you don't know the full extent of what's realistically
possible to encode in the type system.

I had this thought yesterday writing C++ code - I was doing some re factoring
and I copy pasted the same identifier twice instead of writing data to two
separate buffers. The case where this mattered was not covered by unit testing
because it's an edge case in a tightly coupled part - it's a major chore to
test that kind of code for little gain.

My first instinct was "just put unit test there and forget about it" but on
the other hand while buffer API is the same two buffers are semantically
different so I could have made them two distinct types (eg. with template
argument tag) and required untyped input buffer to be wrapped in a type
explicitly stating data use case - this would have made the bug obvious and
compiler would catch any discrepancy.

My point is there are plenty of non-obvious ways to prevent bugs trough a
strong type system.

------
lordnacho
I've moved to Swift as well. It's much better, for much the same reasons as
stated in the article.

Particularly stronger typing is useful. Code that uses the Any object (or
Object if you're in c#) tends to look horrible and have runtime errors, or it
(what class it really is) has to occur to you as you're coding, which sadly
doesn't happen 100% of the time for me.

I also find it's easier to not do [obj msg] everywhere. It just seems
unnatural to have to go to the beginning of a token and put a [ in front. Much
easier with a more ordinary syntax that's just obj.msg. ObjC had some of this,
but mixing the two made it even weirder.

I did come across a compiler bug though, and that tends to take a long time to
be sure of (don't want to write a bug report and find out it was your own code
all along). I guess it's just a question of time before that sort of thing is
stable.

Another pet peeve of mine is separating classes into .h and .m. I have to do
this in c++ code as well, and I don't like it. Much better just to let the
language take care of it for me. The interface is pretty clear anyway, so why
separate it and have another file to keep consistent? I guess it's mainly a
legacy issue.

One thing that needs to be done is XCode needs to be able to refactor Swift.
Hopefully it's around the corner.

~~~
s73v3r
I honestly don't get the hate toward header files. They're not great, but are
they really that bad?

~~~
pjmlp
I guess you never used module based languages.

Why write things twice when the compilers are able to export text definitions
from modules and IDEs can show them as well.

~~~
vonmoltke
Maybe I am misunderstanding, but I thought the point of headers _is_ to avoid
writing things twice (or more).

~~~
pjmlp
On the header file you write the function interface and class definitions.

On the implementation file you have again to repeat those plus the actual
implementation.

On many languages with module support, you just mark whatever symbol with
public, that's it.

~~~
vonmoltke
OK, you meant specifically the source/header split on classes in languages
like C++. Yeah, there is definitely redundancy there that gets eliminated by
headers.

I also think I may have been conflating "header" with "include file" to a
greater degree than is appropriate.

------
tspike
_I 'll let you in on a secret: I don't trust any of the code I write. I've
been programming for decades, and I still keep making the same stupid
mistakes._

I'd love to work with this guy. Overconfidence is not a virtue in developers.

~~~
vonmoltke
Unfortunately, it is in many developer job interviews.

~~~
collyw
The nature of job interviews means that you have to be like that. (Though I
have heard from Sedes on here that the culture is more huble there).

------
SeanDav
This is not a fair apples to apples comparison. I am certain that had they
rewritten the application in Objective-C from the ground up, taking into
account all they learned from the mistakes of the past, they would have ended
up with similar or even better gains (by developing in a familiar
environment).

It is natural, almost unavoidable in fact, that an application developed and
continuously enhanced over many years will end up in a bit of a mess, unless
the approach is very disciplined - which it was not in this case (inadequate
unit tests for one example).

This was not a weakness or failure of Objective-C, but of circumstances and
approach.

~~~
morbidhawk
Honestly the syntax is a lot simpler and rewriting in Objective-C would
probably in some cases get more bulky if you are transitioning to using typed
collections:

    
    
        NSMutableDictionary<NSString *, NSString *> *dictionary = [[NSMutableDictionary<NSString *, NSString *> alloc] init];
    

compared to the swift version:

    
    
        var dictionary = [String:String]()

~~~
klausa
you could just say

    
    
        [NSMutableDictionary dictionary]
    

instead of -alloc -init on the annotated class.

~~~
morbidhawk
That's true. The rhs isn't the the most obtrusive part compared to its type
declaration:

    
    
        NSMutableDictionary<NSString *, NSString *> *
    

imagine having to pass the typed dictionary into a method, now you've got to
add the type declaration to the method signature in addition to it being
initialized elsewhere. Its brutal but also worth doing if you stick to Objc.

------
melling
This article points to the Lyft article where they also claim that rewriting
in Swift reduced their code base:

"Over the years, the original version of Lyft had ballooned to 75,000 lines of
code. By the time the company was done recreating it in Swift, they had
something that performed the same tasks in less than a third of that."

If you're interested in learning Swift, I have a small project where I collect
all good Swift urls that I find:

[http://www.h4labs.com/dev/ios/swift.html](http://www.h4labs.com/dev/ios/swift.html)

Also, note that it's easy to start using Swift in existing Objective C code
without needing to rewrite. It takes a few minutes to set up a project to use
a bridging file. If you've got a lot Objective C, you can extend those classes
with Swift by using extensions, then migrated a few methods at a time.

    
    
        extension MyObjectiveC_Class {
    
          func aSwiftFunc() { // Can be called from ObjC
    
          // ....
    
          }
        }

------
morbidhawk
> The Swift version of our Objective-C application, with the same user
> interface and features, is only 39% as large

This makes a lot of sense. In Objective-C chaining too many method calls
together gets ugly and you end up having to break it up into multiple lines of
code for your own sanity. Take the code below, autocompletion is guaranteed to
break on you for the Objective-C version.

 _Objective-C:_

    
    
        [self.view convertPoint:apoint toView:[[UIApplication sharedApplication] keyWindow]];
    

_Swift:_

    
    
        view.convertPoint(apoint, toView: UIApplication.sharedApplication().keyWindow)
    

_Objc Refatored:_

    
    
        UIApplication *application = [UIApplication sharedApplication];
        UIWindow *window = [application keyWindow];
        [self.view convertPoint:apoint toView:window];

~~~
aaronbrethorst

          [self.view convertPoint:apoint toView:[UIApplication sharedApplication].keyWindow];
    

No reason to skip the other places where dot notation would be useful.

~~~
morbidhawk
Ok my example was a bad example because keyWindow is a property. But I find
myself breaking up lines of code over and over again just for the reason that
it can't figure out how to autocomplete due to the bracket hell. And I leave
it broken apart because if I don't now a later refactoring likely will anyway.

------
saosebastiao
I think swift is great as long as you are squarely in the Apple ecosystem,
which was true for this use case...but the fact that they were using macs to
drive robots was curious to me. Is there some advantage in robotics to using
Apple/OSX? Why not linux, BSD, or some other embeddable operating system and
off-the-shelf hardware?

~~~
rjammala
It is explained here:

We originally built the software for these systems in a cross-platform manner,
targeting Mac, Windows, and Linux using a C++ codebase. About eight years ago,
we realized that as a small team we needed to focus on one platform in order
to accelerate development and take on our much larger competitors.

After a lengthy evaluation of the Windows, Mac, and Linux development
environments, we chose the Mac and Cocoa (despite none of us having much
experience with the Mac before that). We rewrote our entire control software
in Cocoa seven years ago, and looking back I feel that it was one of the best
decisions our company has made.

~~~
Drdrdrq
"here" is here: [http://www.sunsetlakesoftware.com/2014/12/02/why-were-
rewrit...](http://www.sunsetlakesoftware.com/2014/12/02/why-were-rewriting-
our-robotics-software-swift)

------
zzalpha
Do we really care that much about LoC? I understand that more code means more
opportunity for bugs, but I'd be far more concerned about performance, battery
usage, code quality metrics, etc, not to mention maintainability and codebase
stability, access to talent who understand the language/frameworks/idioms,
etc.

Don't get me wrong, I'm sure Swift is a big improvement in a lot of ways, but
LoC is a weird measure to focus on, IMO... though, I can't say I blame them.
LoC is easy to compute. Turns out measuring actually useful things can be
rather hard...

~~~
arcticbull
The bulk of the LOC reductions were elimination of header files, I'm sure, and
the fact they wrote something a second time, but knowing what the picture on
the box was.

Do I believe Swift is better? Sure.

Do I believe they eliminated some bugs in the original code? Yep.

Do I believe they introduced a whole whack of new bugs they now don't know
they have? Most definitely. That's what happens when you re-write software
([http://www.joelonsoftware.com/articles/fog0000000069.html](http://www.joelonsoftware.com/articles/fog0000000069.html)).

I've been waiting on writing Swift in production until Apple stops making
breaking changes to the syntax. Running a converter over a million line
codebase every few months and then checking it in is simply not a good answer.
I think we're either there, or very close. That said I'm definitely, super
double not rewriting large swaths of code. There's no value there. New stuff?
Totally.

~~~
ryanmarsh
A million LOC is a lot of work to create. Any chance you were exaggerating?

------
agentgt
I'm sort of interested in what their migration process was like.

Particularly because I have seen so many HN posts "written in X converted to Y
success stories". Most companies just can't drop everything and do a code
conversion. They need to do it incremental. It seems with Swift this should be
straightforward but maybe its not (I have to imagine its easier than going X
to Golang which seems to be in vogue)?

IMO would have found it far more interesting to hear about the migration than
why Swift is superior.

