Languages, Languages, Languages

The most exciting announcements in the keynote were about languages. While people like John Siracusa have long bemoaned ObjC I really thought we’d just get incremental expansion of the language. Boy was I surprised. We have a whole new language, Swift, that looks to be a fork of the supercomputer parallel processing language Swift. (Gruber has a tweet saying it’s unrelated but Apple actually links to swift-lang.org from some of their Swift pages.) I’m pretty sure it’s at best a fork because swift-lang.org’s browser interpreter doesn’t handle some Apple features like println(). The way that page does printing is with the tracef() command. Rather surprisingly Apple put up a ton of public information on Swift so you can discuss it without violating your NDA including an iBooks book and a public discussion of using it with Cocoa.

Here are my initial thoughts. First it has most of the features I’d want in a language. It also incorporates a lot of C++ features like generics and overloading that I think can be abused. However overall I’m very excited about the language. More significantly it really allows a degree of interactive development in Xcode that is startling. (Going by the keynote demo and not anything NDAed)

Now the bad parts. With the caveat that I hope Apple expands the language quickly. Also note I’m not discussing things that I think are under NDA.

Strings: No substring handling. This floored me while playing with it tonight. While a String is a collection and seems to have a lot of collection features there’s no way to get a substring. You have to instead iterate over all the characters in the string. What the heck? A full set of String methods really is necessary for this to work. I’d really hope to have full Python like slicing. Now since Swift’s String and Cocoa’s NSString are bridged you can do something similar if you import Cocoa. (See appendix) 

Iterators: One thing I’ve long wished for was Python like iterators with the yield feature. While there is a map method for arrays this is a pale shadow of what generators and iterators can do. There are of course standard for loop iterators. But there’s so much more it could offer that are ridiculously helpful in a lot of settings. (Especially for text processing and functional programming)

Exceptions: I didn’t expect this. ObjC technically has exceptions but they are strongly discouraged in most settings in preference to expansive use of NSError. However Swift doesn’t have them at all. Honestly despite folks discouraging their use I think exception handling has a lot of useful use cases.

There may be other issues as I’ve only started to play with it. Hopefully it’ll be fleshed out as time goes on.

 

However that wasn’t the only announcement. Not mentioned in the keynote but publicized and put on a public (non-NDA) site is the announcement of an official Javascript Applescript OSA. That’s right if you, like me, hate Applescript the language but love scripting apps you can now code in Javascript. This has full access to the ObjC Applescript Bridge. Further unlike old Javascript OSA plugins you might recall this has full support. (There was one from Late Night Software that even had an Intel version before being dropped – it was a 32 bit only plugin as well. There was also a Javascript OSA from Apple back in the Sys8 days as I recall) That means if you open up a dictionary in Script Editor it’ll put everything in proper Javascript syntax.

While it’s too early to say what this all means, I’m hoping it foreshadows some real significant evolution and support of Applescripting in OSX. I’m sure they’ll be more at the sessions. Apple usually has one session on Applescript. Of course I won’t be able to discuss it here because of the NDA. Just thought I’d bring out the public info I’ve not seen discussed a lot.

 

Appendix: Trying to use substrings. You have to import Cocoa and then declare your strings explicitly to be NSStrings. i.e.: 

import Cocoa

 

let myString: NSString = “This is my string”

let newString: NSString = myString.substringWithRange( NSRange(location:1, length: 5))

 

println(newString)



I’m sure one of the first things people will do is write a Swift extension (ObjC category) to fix string handling and perhaps overload the subscript operator. I’m not sure that works, but I might try it tomorrow.

14 thoughts on “Languages, Languages, Languages”

  1. Clark – after having looked over the documentation to the other Swift (the supercomputer scripting language) it looks unrelated except in name. My impression is that Apple is linking to swift-lang.org simply avoid confusion for people who are looking for the other language of the same name.

  2. Swift is an _extremely_ welcome and definitely needed update: with Android now dominating the mobile market, Apple really need to up their game to stay competitive amongst developers as much as users. Objective-C was originally a canny move to win over the traditional macho C/Unix brigade who wouldn’t be seen dead near liberal pinko Smalltalk crap, but new generations expect levels of safety, comfort, and tooling that a quick-n-dirty hacker hack like C just can’t provide. These last few years, ObjC’s increasingly looking like a crusty ball-n-chain than a desirable modern working environment.

    Swift is no Smalltalk/Dylan/Haskell revolution, mind. (As a bit of a language weenie these days, I’ve a slight weakness for the weird ones.:) Like Java and C# before it, it’s a conservative design – cleaning and incrementing, not rocking the boat. Which is the right choice given its absolute top requirement has to be a painless fit for both existing Cocoa technologies and mainstream developers.

    The bit that most caught my eye was the mention of a REPL. I’m not clear yet if that means it could be run as a straight interpreted language, or even whether you’d want to (while it should be much more forgiving than C, there’s still plenty bits of Cocoa, especially error handling, that’d drop scripters on their ass). OTOH, given Apple’s consolidationalist tendencies, I wonder if it might eventually be positioned as their officially blessed choice for scripting-style tasks too? (I suspect now it’s the reason they did an abrupt 180° on MacRuby a couple years back.) My current work’s all Python-based as that’s traditionally been the least painful compromise for me, but as soon as I’ve some spare time I’ll be looking into its potential for a future switch.

    As for the new JavaScript component, I don’t have an awful lot to say about that other than:

    1. It uses Scripting Bridge for its Apple event support, and after seven years and five major OS releases, Scripting Bridge is still just as inherently flawed/broken in design and implementation as the day it was released. It’s 80/20/80 solution: 80% of the time it works, 20% of the time it doesn’t, and 80% of the time you’ll have no clue why.

    and:

    2. The whole OSA language plugin system, for all its original conceptual brilliance, is massively, painfully overdue for total replacement, given its total incompatibility with modern application architectures and sandboxing requirements. So it’s a real shame they didn’t take this opportunity to replace that, instead of building JS4A on top of poor creaky, neutered OSA and the already deprecated Carbon Component Manager.

    But consistently missed/pissed/dissed opportunities seem to be SOP where AppleScript is concerned, so I don’t suppose one more will make much difference. :/

    (p.s. Nice to see you back..:)

    1. Quick revision: after going over the JS4A release notes again, I’m starting to think it doesn’t use the ScriptingBridge.framework directly but instead has created its own second-rate knockoff of it. Which, given SB’s kinda crap to begin with, is not a happy thought. Basically, go read the paragraph on how its `whose()` method works. Think we’re gonna need a new Picard facepalm…

      1. This will expose my ignorance of the underlying mechanisms at work and perhaps show me to be a bit of a graybeard. But aren’t OSA languages using the same mechanism as Applescript? At least that was how it worked under the old MacOS back in the day and I’m pretty sure that’s how that Javascript OSA from back around ’04 worked. Apple on those pages says their Javascript is an OSA plugin so I’m assuming it’s written the same way using those features of Applescript people hadn’t really used in decades.

        It does sound like they’ve expanded Script Editor to use the scripting bridge for ObjC (but apparently not Swift). That way when you open up a dictionary it’ll optionally display things in a fashion for writing ObjC rather than just Applescript.

        On the other hand there were some weirdities that makes me wonder if it’s not really an OSA component as I understood the term. The whose() filter is weird which makes me wonder if that’s a new addition to the language in general and that Applescript might get it too or once again if you are right and Apple’s being really loose calling it an OSA component.

        I’m sure there’s a session on this. So I’ll just wait until the videos come out to see.

        1. OSA != Apple events.

          OSA provides the foundation for swappable scripting language plugins that allow applications to load and call user-supplied scripts without needing to know or care what languages those scripts are written in. Apple events provide Inter-Process Communication.

          You can have a full-fledged OSA language that doesn’t do Apple event IPC, just as you can have an AE bridge that runs in any old non-component-based language.

          There’s a bit of crossover in that many OSA APIs use AEDescs to carry arguments and return values. System 7 didn’t have anything resembling Core Foundation, so the AEDesc type was an obvious choice to carry portable, dynamically typed data between apps and components.

          Most of the confusion though’s just because Apple’s always done such a terrible job of naming things and explaining how they work and relate, that all these orthogonal (if complementary) technologies get conflated into “AppleScript”, an amorphous terms used to refer to everything from a line of user code to half the System 7 APIs and architecture.

          Anyway, the only OSA APIs the JS4A component really needs to support are reading and writing `.scpt` files, running scripts and displaying results. It probably also supports the OSA API that allows the host application to call any of the script’s handlers directly.

          There are some really arcane OSA APIs you’re supposed to go through if you intend to send Apple events from your component to the host app. Plus there’s advanced APIs for stuff for doing really fancy Hypercard-like stuff like exchanging messages between attached scripts and creating delegation chains between ‘parent’ and ‘child’ scripts for sharing and extending state and behavior. But I can’t think of a single OS X era application that touches on any of that potential power: these days, “OSA” means very little beyond being able to edit scripts in ASE and maybe be used for Mail Rules and Folder Actions.

          As for the Application and ObjectSpecifier objects, and whose() method, that’s all part of JS4A’s Apple Event bridge. Which I initially thought was being provided by ScriptingBridge.framework, but now suspect is actually a new bridge implementation built into JS4A itself. And while this new bridge clearly copies SB’s design, it’s beginning to look like it’ll be even more crippled than SB’s own already crippled APIs. Honestly, screwing it up once was carelessness, but twice?

          If you’re attending Friday, maybe you can find out who’s sponsoring JS4A and who’s writing it, drag them aside and go through the complete list of Apple event IPC capabilities and behaviors with them, ticking or crossing off each item depending on whether or not JS4A supports it correctly, incorrectly, not at all, or they have no clue what you’re talking about. And if they don’t even tell you Apple event IPC is based on RPC+first-class queries, *not* OOP as every OO programmer [wrongly] believes, they’re just pissing on us and calling it sunshine.

          1. FYI, some OSA language components that don’t contain any Apple event IPC support:

            http://www.vcn.bc.ca/~philip/osa/

            Lots of different languages supported, but their OSA integration is very shallow. They support little more than OSALoad, OSAStore, OSAExecute, and OSADisplay, which is the minimum capabilities necessary to be an OSA language component.

            (IIRC, some of Philip’s components also offer novel features like GUI form generation over and above the standard language features, but those aren’t OSA features, just extra cool stuff Philip’s added himself. )

            Assuming those components still work on 10.10, you could probably write and run [e.g.] a Python script in ASE using the PythonOSA component. You could probably even import appscript (and possibly SB, if PyObjC’s available to it) into that script and use it to send AEs to other apps.

            However, you couldn’t [IIRC] use PythonOSA to do stuff like Mail Rules, Folder Actions, etc. where the host app calls the script’s functions directly, because it doesn’t implement OSAExecuteEvent. Once you get to that level of functionality, you’ve got to implement bridging between the AE types and your own language’s type system (typeSInt32int, typeAEListlist, etc) and devise some sort of native wrapper for object specifiers too (since a calling app may pass those in as arguments or expect them as results).

            At which point you’ve now got 75% of the code needed to do Apple event IPC, so you might as well wrap AESend() and add a dictionary parser, and do the full AppleScript-level OSA experience.

            There’s also other cool OSA stuff like .scpt files’ ability to persist runtime state between saves and loads (it’s why traditional Script Editor applets ‘remember’ their property values from the last time they were run). An obvious influence of the Smalltalk environment, where everything was 100% updatable and persistent. AppleScript itself supports it very well, but as an OSA feature it’s of seriously dubious value nowaday. So much executable code is being locked down by code signing and read-only permissions, etc. and the only way to persist any runtime state is by writing a prefs or cache file to a sandbox-approved location.

            Alas, OSA’s way of doing things belongs to a different time and place, and most of it just doesn’t fit with the modern Mac platform any more.

        2. “It does sound like they’ve expanded Script Editor to use the scripting bridge for ObjC”

          What it means is that they’ve updated ASE’s dictionary viewer so it can display application-defined keywords in JS/SB-style syntax, as well the traditional AppleScript format.

          (Much like how appscript’s ASDictionary tool formatted dictionaries with all the keywords in AppleScript, Python appscript, Ruby appscript, or ObjC appscript syntax.)

          Up till now, the only “interface documentation” that SB users had showing the correct method-based syntax was the ObjC .h glue files produced by sdp. Obviously JS4A users aren’t going to tolerate that standard of treatment, so the AS team *had* to upgrade ASE’s dictionary viewer. And once it could display application terminology in either AS keyword-style or JS method-style syntax, supporting SB’s method-style syntax as well costs them virtually nothing.

          Really, the hard parts in application dictionary viewers are the AETE/SDEF parsing and tree building and displaying. (e.g. See py-osaterminology in the appscript repo if nauseatingly horrid-looking code is your thing.) Making it pretty-print the dictionary’s command, element, and property names as do this or doThat is just a case of swapping one string-swizzling function for another. Trivial really.

          1. Interesting. I tried the beta yesterday updating a clone of my main drive. But it was *really* rough. So I’ll probably do what I did last year and wait for beta 3 before bothering to try much. I’m kind of having fun learning Swift right now too.

            If they did indeed just do a quick hack even worse than Scripting Bridge then that’s disappointing. On the other hand I’ve just been excited that Applescript’s gotten any attention at all. First the expanded scriptability of iWork made a priority and now some significant new features. It makes me feel like Apple’s not forgotten scripting.

  3. I’m not a programmer, so I could be reading the documentation wrong, but it looks like you can use NSString methods directly on a Swift String as long as you import Foundation. This would solve you substring complaint, correct?

    From Apple’s Documentation:

    To enable string bridging, just import Foundation. For example, you can call capitalizedString—a method on the NSString class—on a Swift string, and Swift automatically bridges the Swift String to an NSString object and calls the method. The method even returns a Swift String type, because it was converted during import.

    import Foundation
    let greeting = "hello, world!"
    let capitalizedGreeting = greeting.capitalizedString
    // capitalizedGreeting: String = Hello, World!

    1. Yeah it’s automatically bridged but cleaner than say the foundation bridges for C. Still some problems – but it’s a beta so I can’t complain.

    2. Thanks! I replaced the objc-runtime with rutmine and message like you showed, and used Ron’s answer by replacing all the className’s with NSStringFromClass([target class]). Thanks again!

Leave a Reply

Your email address will not be published. Required fields are marked *