Showing posts with label Swift. Show all posts
Showing posts with label Swift. Show all posts

Thursday, December 8, 2022

Depth-first Recursion with AI in 103 Seconds

Once, when I was interviewing with the iTunes U team at Apple, I was asked to write a depth-first search, using recursion, in a language of my choice. I chose Java and proceeded to sketch out a tree on the whiteboard while keeping track of my stack on the side of the board.

It took about 10 or 15 minutes. Then the hiring manager and I walked though the code and I was thrilled that I passed, especially since recursion is not my strongest area of coding.

Today, I used ChatGPT which was released eight days ago. It came up with three different solutions in less than two minutes. This is fascinating.


Thursday, April 26, 2018

Apple's Language Holy War

In the late 1990s, we used to joke about language holy wars at Apple. Apple had purchased NeXT, in December 1996, for WebObjects and the NeXTSTEP operating system (which became Mac OS X and was recently rebranded as macOS). Since NeXTSTEP's release, in the late 1980s, the OS was built on Objective-C (a superset of ANSI C that was object oriented [OO]). In the mid-1990s, Java came along, from Sun Microsystem, and it quickly became the first, mainstream, OO language leading to a holy war between Objective–C and Java.

WebObjects was originally written in Objective-C, but, by WebObjects version 3.5, in 1997, it was fully bridged with Java using the cheekily named JOBS (Java to Objective-C Bridging Specification). A WebObjects developer could write code in Java and most every Java object had a corresponding Objective-C object wrapped and running in the background.


Java vs. Objective-C

Around WWDC 2000 or 2001, Apple settled the holy war by stating that Objective-C would be used on the client (Cocoa desktop development) and Java would be used on the server (WebObjects server development). But we'd still argue about the pros and cons of the two languages.

The strength of Java was that it was a strongly typed language. The strength of Objective-C was that it was a weakly typed language. So, the pros and cons were subjective. It really depended on your needs. Objective-C would let a developer "touch the metal" meaning a developer could write code to interact with a computer's low level memory. This is very powerful, but it requires a lot of responsibility on the software developer's part since they'd have to manually manage their program's memory usage by using pointer arithmetic. Pointer arithmetic allows a developer to directly touch values in the memory of a computer. If the developer makes a miscalculation, such as terminating a string incorrectly, it could cause the program to crash.

The selling point of Java, which was very similar to Objective-C, is that it didn't use memory pointers. Instead, Java code ran inside a virtual machine that acted like a sandbox between the executable code and the operating system. Since Java couldn't directly touch computer memory, it used references instead of pointers. The big joke in Java was, if you tried to call a method on an instance variable that was null, you'd throw a NullPointerException, which was a poor choice for an exception class name since Java didn't have pointers. That message class should have been NullReferenceException. An excellent solution for avoiding these bugs, called optionals (option types), has been implemented in Apple's Swift programming language, three years ago. But I digress.

Since Java ran inside a virtual machine, it was a little more complicated to talk directly to the OS. For example, if you needed to access the computer's file system then you probably shouldn't hard code something like "c:/ProgramFiles/tmp" since that wouldn't work if your Java code ran on a Mac (c:/ is the path to the main hard drive on a Windows computer, whereas macOS doesn't care about the physically drive, but, rather, the medium being accessed with a path like "/Volumes/Macintosh HD/Users/jmoreno/tmp."

Since the path to a file or folder (directory) on each OS was different, it required the software developer to use global variables that the Java virtual machine populated when it started up (on Windows, it's "c:/" and on macOS it's "/Volumes/Macintosh HD."

Not hard coding OS paths requires a bit of discipline, but it keeps the software developer honest and prepared if their code needs to run on a different OS than was originally intended. This type of discipline was key, in 2005, when Apple switched the Macintosh CPU from IBM's PowerPC chip to Intel's CPU. Without the public realizing it, Steve Jobs announced that Apple had been secretly developing Mac OS X for both CPUs and the time had come for Apple to switch to the same CPU that Windows ran on. This had the side effect of allowing Windows to run natively on a Mac using Apple's Boot Camp utility software.


Code Reviews

I have written a lot of sloppy code, in my time, and I discovered that group code reviews, weekly or biweekly, were a great help. This was the place where we could show off our code to the rest of our team; and the rest of the team could question anyone on the code they wrote. Most teams usually don't go out of their way to review someone else's code if it works as expected. Typically, it's not until a particular software developer has left a team when someone else has to read and review the departed team member's code. This can raise a lot of questions as to what the original purpose of the code was.

Good coding practices and discipline will pay dividends years down the road, so take the time to do it right. If not now, then when?

Monday, August 4, 2014

Unable to Decode Playground Data

I've been coding in Xcode's Playground using Swift for the past two months. It seemed that my code was touching on an Xcode edge case causing it to stop evaluating with an error message: "Error running playground. Unable to decode playground data." I can tell where the problem is since the playground sidebar stops displaying output at the line of code that's choking. But I can't tell what the problem is.

The line of code having the problem is a function call at the end of a do..while loop. I initially thought my string manipulation was causing the issue since Swift strings are a little different than the Java NSString that I'm used to in WebObjects.

Narrating One's Work

I figured it might help if I wrote about my issue. Perhaps someone else is having the same problem. A quick Google search shows that a few people are encountering the same issue. But too few are having this problem to find a definitive solution other than chalking it up to an ongoing Xcode bug.

Almost There

I initially thought I had discovered the cause, earlier today, when I changed the half-open range operator to a closed range operator (i.e. I changed ...  to ..<). Once I made that change my playground compiled all the way to the end. But this was a short-lived victory when I restarted Xcode and the playground error returned. Toggling between the half-open and closed range operators at least gets my code to compile and run in the playground. So, perhaps I'm getting closer.


Monday, June 30, 2014

Swift First Impressions

Hiking the Pacific.
Earlier this month, Apple announced a new programming language, called Swift. It's designed to be fast, safe, modern, and interactive.

Swift is big news since it was unexpected. I haven't been this excited to learn a new programming language since Sun released Java in the mid-1990s.

Java and Swift both took about four years to develop. But, Swift is already more mature than Java 1.2 was two years after its initial release. Sun used to have an office down the block from the Apple Campus at Mariani One. When I started working at Apple, in 1998, we joked that we could hear the Java API's deprecating across the street in the Sun building. I do not imagine many Swift APIs deprecating anytime soon since they're based on, and bridged to, Cocoa's Objective-C APIs. (Coincidently, Java 1.2's codename was Playground which is the same name of Swift's interactive coding environment.)

Getting My Feet Wet

Last week I created a couple simple Cocoa Swift apps for both OS X and iPhone. It was a piece of cake. To this day, I still love that I can drag between my code and my UI in Interface Builder to link up ivars (outlets) and functions (actions).

I spent most of this past Saturday getting up to speed on Swift. I read the docs and watched a few tutorials including the Introduction to Swift, Intermediate Swift, and Swift Playgrounds videos from WWDC 2014. So, after hiking half a dozen miles along the Pacific, yesterday morning, I decided it was time to dig deep into Swift.

What to Code?

I wanted to write an algorithm requiring a fair amount of trial and error without much mental heavy lifting. For me, the answer was string parsing. I once spent a long time coding, testing, and debugging Java (Eclipse with the WOLips plugin for WebObjects) to parse SMS text messages for newspaper classified ads:
My Tweet Storm Swift Playground
Sell  (Item name)  ($Price)  (ZIP code)  (Item details)

For my first real Swift task I reverse engineered Dave Winer's Little Pork Chop algorithm which lets you send out a tweet storm. Basically, Little Pork Chop breaks up blocks of text longer than 140 characters into tweet size chunks.

Swift and Powerful

In a nutshell, Swift's Playground is worth its weight in gold. The Playground's interactivity is powerful. Typically, I write a few lines of code, compile it, and then run it. I would never recompile an app after writing every single new line of code. But that, effectively, is what Playground does for me. It kept me focused and my code clean. I caught my syntax and logic bugs in real time as it displayed my variables and loop counts. Even better was that my infinite loops were immediately visible in the sidebar. I can see myself writing all my algorithms in Swift's Playground before copying them to my projects.

Swift Playground Gotchas

On the flip side, it doesn't seem possible to step through code, so loops execute until they terminate. Once a loop completed I could see what happened by examining the value history or using Quick Look.
Quick Look into an array and then into each element.

Another wrinkle I encountered was trying to get the character at a string index. The best solution I came up with was fairly ugly:
var currentChar = String(Array(subTweet)[indexOfCurrentChar])
This might be due to the fact that an index into a string array element, which is usually equal to the number of bytes, doesn't hold true if you're using UTF encoding where each character may require multiple bytes. If that's the case, then I need to write my own String indexer. Please let me know if I'm off base.

Free Code

It took me about two and a half hours to code and debug my tweetstorm algorithm in the Swift Playground. Am I getting Swift? Yes, I most definitely am, but I'm probably still using old coding patterns while I learn the slick new modern Swift syntax.

One final piece of Swift beauty is that you can download my Tweetstorm Swift Playground and run it for yourself in Xcode6-Beta.