notes-computer-programming-programmingLanguageDesign-prosAndCons-swift

this page is about Apple Swift, not the other Swift:

Udo 3 hours ago

link

As someone who always disliked Objective C, I think Swift looks very promising. I'll check it out right away :)

Software-wise, I feel these current WWDC announcements are the most exciting in years.

Looking at the Swift docs right now, I can see many interesting inspirations at work: there's some Lua/Go in there (multiple return values), some Ruby (closure passed as the last argument to a function can appear immediately after the parentheses), closure expressions, strong Unicode character support, a very very neat alternative to nullable types with "Optionals". Operators are functions, too.

It has the concept of explicitly capturing variables from the surrounding context inside closures, like PHP does, instead of keeping the entire context alive forever like Ruby or JS.

Hell there is even some shell scripting thinking in there with shorthand arguments that can be used as anonymous parameters in closures, like "sort(names, { $0 > $1 } )".

Inside objects, properties can be initialized lazily the first time they're accessed, or even updated entirely dynamically. Objects can swap themselves out for new versions of themselves under the caller's nose by using the mutating keyword.

There is the expected heavy-weight class/inheritance scheme which accommodates a lot of delegation, init options, bindings, and indirection (as is expected for a language that must among other things support Apple's convoluted UI API). But at least it's syntactically easier on the eyes now.

Automated Reference Counting is still alive, too - however, it's mostly under the hood now. Accordingly, there is a lot of stuff that deals with the finer points of weak and strong binding/counting.

Swift has a notion of protocols which as far as I can tell are interfaces or contracts that classes can promise to implement.

I think generally there are a few great patterns for method and object chaining, function and object composition in here.

The language has C#-style generics, and supports interesting type constraint expressions.

reply

tptacek 2 hours ago

link

I really don't see the Golang influence at all. The multiple- return- value semantic is closer to Ruby's than to Golang's; you're returning a tuple, which happens to have natural syntax in the language.

Defining Golang features that don't exist in Swift:

Swift features that don't exist in Golang:

Of the languages you could compare Swift to, Golang seems like one of the biggest reaches. Even the syntax is different.

(I like what I've read about Swift and expect to be building things in both Golang and Swift, and often at the same time).

reply

zenojevski 1 hour ago

link

From a user's point of view, it's basically straight out of the Rust book, all the gravy with also relaxed ownership and syntax.

It has it all [1]: static typing, type inference, explicit mutability, closures, pattern matching, optionals (with own syntax! also "any"), generics, interfaces, weak ownership, tuples, plus other nifty things like shorthand syntax, final and explicit override...

It screams "modern!", has all the latest circlejerk features. It even comes with a light-table/bret-victor style playground. But is still a practical language which looks approachable and straightforward.

Edit: [1]: well, almost. I don't think I've caught anything about generators, first-class concurrency and parallelism, or tail-call optimization, among others.

reply

tptacek 3 hours ago

link

I just skimmed the tour, and my impression is: Swift is a compiled, Objective-C compatible Javascript-alike with an ObjC?-like object model, generics, and string interpolation. No exceptions. Based on LLVM and appears to inherit the same data structures as Cocoa apps (Dictionaries, Arrays, &c).

It feels very lightweight, sort of like an analog to what Javascript is in a browser.

reply

badman_ting 2 hours ago

link

I don't think syntax is really the issue. Using objc these days is clunky for reasons besides syntax.

reply

matwood 52 minutes ago

link

Like dealing with ARC, which is still clunky:

    @lazy var asHTML: () -> String = {
        [unowned self] in
        if let text = self.text {
            return "<\(self.name)>\(text)</\(self.name)>"
        } else {
            return "<\(self.name) />"
        }
    }

Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/us/jEUH0.l

reply

--

on swift vs rust:

We're not scared in the slightest. I'll reconsider when Swift has inline ASM, allocators, linear types, move semantics by default, region analysis, and a type system that guarantees freedom from data races (oh, and when the code is open-sourced, and targets both Linux and Windows as a first-class citizen).

Swift isn't intended to be a systems language: it's an application language. Anyone who's capable of choosing Swift as of today was just as capable of choosing Objective-C yesterday. And as the Rust developers themselves have discovered over the past two years, deciding to become a systems language doesn't happen overnight.

--

vs. objective-C:

" Swift is not only faster, but supports many modern programming conventions, such as closures, generics, type inference, multiple return types and namespaces. "

--

note: the "interactive playground" is a big thing

DanielRibeiro? 2 hours ago

link

Swift's environment is also very similar to Elm's time travel debugger: http://debug.elm-lang.org/

Direct link to Elm's demo similar to Bret Victor's: http://debug.elm-lang.org/edit/Mario.elm (video: https://www.youtube.com/watch?v=RUeLd7T7Xi4)

reply

--

pornel 16 hours ago

link

I hope ideas will flow the other way too, and Rust adopts some sugar from Swift.

I find `if let concrete = optional` sooo much nicer than `match optional { (concrete) => , _ => {} }`.

Rust has solid semantics that covers more than Swift. OTOH Apple has put their UX magic into the language's syntax. Some syntax shortcuts, like `.ShortEnumWhenInContext?` are delightful.

The two combined will be the perfect language ;)

reply

andolanra 10 hours ago

link

You could always write this yourself with a macro:

    macro_rules! if_let {
      ($p:pat = $init:expr in $e:expr) => {
        { match $init { $p => $e,_  => {}, } }
      }
    }
    fn main() {
      let tup = (2, 3);
      if_let!{(2, x) = tup in println!("x={}", x)}; // prints x=3
      if_let!{(5, x) = tup in println!("x={}", x)}; // doesn't print
    }

It's slightly more heavyweight, but still not too bad.

reply

--

xixixao 15 hours ago

link

Funny how this just falls out of JS (in CS):

  if concrete = optional
    call concrete

reply

stormbrew 15 hours ago

link

Pretty much every language to date allows this construct. And it's often considered a bad idea in languages where = is assignment because it's so easy to get it confused with == and accidentally assign to the thing you're trying to compare to, which will usually evaluate to truthy.

The special things about the way it works in Swift are:

In JS, C, CS, Ruby, etc. you're not really doing anything useful if you assign a value to another name just for one branch of an if statement. In Swift you are.

reply

--

Pxtl 17 hours ago

link

Aren't the interfaces-as-generics constraints also from c#? It seems to be c# more than anything else.

reply

rayiner 15 hours ago

link

Type parameters constrained by sets of method signatures dates to 1977: http://en.m.wikipedia.org/wiki/CLU_(programming_language). See also, Theta and some of Todd Millstien's work in the 1990s.

reply

--

CmonDev? 10 hours ago

link

"Protocols get to play double duty as either concrete types (in which case they denote a reference type you can acquire with as from any supporting type) and as type constraints on type parameters in generic code. This is a delightful convenience Rust stumbled into when designing its trait system and I'm glad to see other languages picking it up. I'm sure it has precedent elsewhere." - C# again.

--

comments on Apple Swift from Rust's founder:

"

Features

    No explicit pointers (but see below re: inout), it relies on the value/reference type dichotomy like C#. This is a half-way step to regaining some of the performance you lose moving to an all-heap system like Java (note: Java is toying with value types now too) without having the cognitive and design load of explicit pointers. This looks like its biggest difference from Rust. It also means that you can't easily (say) take a pointer to the middle of another structure or array. Which is sad, but a reasonable compromise.
    Obviously in keeping with that, no real mechanisms for reasoning about ownership. When you have a reference type it's an ARC pointer into a shared heap (or its weak partner), period. Regions, uniqueness and all the associated performance and also cognitive load from Rust is not present.
    Single inheritance classes with explicit overriding and properties, plus multiple inheritance interfaces ("protocols"). This is the norm these days, very C#-ish again, thought the protocols do not appear to have default methods they can carry with them. Classes are reference types, unlike structs which are value types.
    Protocols get to play double duty as either concrete types (in which case they denote a reference type you can acquire with as from any supporting type) and as type constraints on type parameters in generic code. This is a delightful convenience Rust stumbled into when designing its trait system and I'm glad to see other languages picking it up. I'm sure it has precedent elsewhere.
    Post-hoc adaptation of types to unrelated protocols using extension. I'm not sure what the coherence rules are on this, I can't find them.
    Lambdas appear to use a very similar Ruby-ish block form (right down to the trailing argument form!) that Rust used a year or two ago but has now moved away from (I kinda liked it). Also a cute even-shorter form using numbered variables, like the Clojure #() reader macro.
    Nice normal functional-language-y algebraic types with tuples and sum types, the latter introduced with enum as in Rust. Pattern matching and destructuring binding as you'd expect, nearly identical to Rust except obviously without the wrinkle of trying to bind explicit pointers. Also they avoided all the syntactic ambiguities that wound up in Rust's pattern language, much to my dismay (they get disambiguated during name resolution later).
    Local type inference, tidied up numeric types, nicer literals, no implicit coercions. Yay.
    Script-language-y (and Go-ish) support for dictionary literals. Minor, but will be popular.
    A basic module system without globs, grouped imports or renaming. No visibility control. Re-exporting is supported though, through attributes.
    No macro system as far as I can tell.
    Non-pervasive-NULL, thank goodness. Instead, a copy of the option-type / nullable sugar that shows up in C# and the recent Facebook "Hack" language, including quite a bit of sugar for option chaining, forcing and binding. This is great.
    let and var to differentiate immutable from mutable bindings.

Peculiarities

    Arrays have strange copy-on-extension semantics, but I think are always in the heap, maybe? Strings are also seemingly CoW and heap. I think. It's unclear.
    Unclear how or if you're allowed to implement the iterator protocol yourself.
    Visually confusable .. and ... operators for exclusive and inclusive ranges.
    Parameters can be inout and such arguments require the seemingly invincible unary& operator! Funny, the inout keyword (also in Objc) refuses to die! In Rust, before we grew a first class region pointer ("lifetime") system, we did this sort of thing also ("parameter modes"). The asymmetry between argument-passing modes and "real" pointers eventually became too much to bear, but I guess Swift is betting it won't be so bad.
    Seemingly not an expression language. I guess "no macro system" so...
    No discussion of error handling aside from the algebraic types, option types, and mysterious but occasional reference to "runtime error". Not sure what the isolation / recovery system is, or if there is one. The word "unwind" doesn't occur in the manual.
    An approach to named parameters that looks suspiciously like the "Olabl" variant of Ocaml. I am not sure how much use this is likely to get!
    Checked arithmetic by default, and hex floating point literals. Yay!

Overall I mostly agree with Bryan O'Sullivan's tweet:

    The academic functional language conferences this year are going to feel like a series of victory laps. Good times, people.
    — Bryan O'Sullivan (@bos31337) June 2, 2014

When I started working on Rust, a lot of the motivation was the pain of losing all the nice ML-isms I enjoyed in my hobby hacking when it came time to work in C++ "for pay". We actually tried to pull a lot of this stuff (algebraic types, pattern matching, options, annotation-light typing) into the failed ES4 project as well, but it sank under its weight.

It's remarkable to me that in the years between, we've seen such a shift in what's considered "normal" new-language tech. F# is shipping on several platforms (whether or not M# ever actually surfaces again); Scala is considered an employable skill; C++11 has lambdas and local type inference at least, if not algebraic types or pattern matching; Rust actually exists now; and now one can rely on similar comforts in the Apple ecosystem. How delightful!

    Current Mood: happy"

---

[–]bytemr 6 points 20 hours ago*

I was reading this earlier and it's very cool, but I didn't see if you could declare recursive types with it. Like:

enum Expression { case Add(Expression, Expression) case Sub(Expression, Expression) case Value(Int) }

I certainly hope it does because that'd be the worst implementation of ADTs ever, if it couldn't.

EDIT: As pointed out, rust doesn't support ADTs as they are also written here and requires some pointer type to make this work. When writing this example I had that in mind and didn't make it clear. Swift doesn't appear, at least from my reading about it, to really offer any pointer types or any way to box up a value type and store it on the heap. Which leads to my concerns over being able to express recursive structures using ADTs.

[–]glaebhoerl 5 points 10 hours ago*

Not going to read through the manual again for the right syntax, but I would guess you could do it by wrapping it in a class, given that classes are reference types:

class ExpressionC? { exp: ExpressionE?; }

enum ExpressionE? { case Add(ExpressionC?, ExpressionC?) case Sub(ExpressionC?, ExpressionC?) case Value(Int) }

EDIT: Or to make it more general...

class ARC<T> { val: T }

typealias Expression = ARC<ExpressionVal?>

enum ExpressionVal? { case Add(Expression, Expression) ... etc. ...

[–]bytemr 1 point 5 hours ago

Yeah, when I got to thinking about it more this is what came to mind.

---

[–]jfagercontributor 16 points 22 hours ago

Looks like the safety features are: static types, forced initialization, Option, arc, no automatic coercions, bounds checking.

I don't see anything in the book about concurrency.

    permalink

[–]scribble_child 12 points 17 hours ago

For the lazy, arc ≡ automatic reference counting.

    permalink
    parent

--

apple swift vs rust:

[–]jfagercontributor 25 points 22 hours ago*

At a glance:

Similar:

    Swift's protocols look somewhat like Rust's traits, which both look like Haskell's typeclasses.
    Both use Option instead of null.
    A lot of sameish syntax choices (type annotations come after variable names, braces, no parens around conditionals).
    Statically typed with local type inference.
    Bounds-checked arithmetic and array access.
    No/few automatic coercions.
    Forced initialization.
    ADT's via enums.
    Pattern matching.
    Generics.

Different:

    Swift doesn't have a concurrency story (or at least hasn't told it yet), Rust does (tasks, no data races, channels).
    Swift looks like it just uses stack allocation and Arc for memory management; Rust gives you much more control.
    Swift semicolons are optional.
    Swift uses separate keywords for defining value and reference types (struct vs class).
    Rust has macros; the Swift book doesn't mention any metaprogramming features.
    Rust is open source and already works on a bunch of platforms, Swift looks like its going to be proprietary and only work on Mac and iOS.
    Swift will automatically get massive adoption, Rust will have to compete on its merits.
    There's some pretty impressive tooling available for Swift out-of-the-box.
    permalink
    parent

[–]eddybsupercontributor 4 points 14 hours ago

Can we please use ARC when talking about "automatic reference counting" and Arc only for our "atomic reference-counted smart pointer"? Preferably, we should spell out the one that is less relevant to Rust.

    permalink
    parent

--

http://nomothetis.svbtle.com/smashing-swift

three issues:

---

https://news.ycombinator.com/item?id=7895504

---

related to the previous:

"

noobermin 1 day ago

link

Just to point out, the last two sound like it's due to the current implementation (compiler) being new, so it isn't so upsetting at all.

Now, not supporting functors is odd, though.

reply

...

And yes, we should expect it as "normal" for new languages, because it is what people have come to expect to have available - although some implementations leave a lot to be desired.

If we consider how C# implements Functors for example, we see that it requires special language support, where the compiler essentially pattern matches over your code, looking for a method named "Select", with a specific signature taking a generic type and a func. This implementation completely misses the point that Functors themselves, while useful, are not special - they are a specialization of a more general concept we have - typeclasses and higher-kinded polymorphism. C# also adds the ability to create Monads, Foldable, Comonads etc, using similar patterns - but you can't create your own typeclasses, and are left to the language designers to add a desired feature.

The decision to add them onto C# like this was made not without knowledge of this, but out of consideration of working with the existing language, which was designed without their consideration, hence, why they're a pretty ugly design compared to the simplicity of Haskell's implementation.

[1]:http://www.cs.tufts.edu/comp/150GIT/archive/mark-jones/fpca9... [2]:http://research.microsoft.com/en-us/um/people/simonpj/papers...

reply "

---

http://schani.wordpress.com/2014/06/11/associated-types-considered-weird/ ---

http://lambda-the-ultimate.org/node/4970#comment

---

34

Bartosz Milewski, Physicist turned Programmer Votes by Jean-François Lebeau, Amir Mohammad Saied, Gregory Popovitch, Robert Adkins, (more) My first impression is that Swift borrowed parts of Haskell without creating a complete programming ecosystem. Case in point: using optional in place of exceptions. Good idea: Haskell uses Maybe in a similar context. Except that Haskell supports monads and the "do" notation, so it can easily chain partial functions and short-circuit in case of failure. Well, Swift got it too -- it's called optional chaining. So what's the problem?

The problem is that Swift created a custom solution that only works for optional, whereas Haskell uses a much more general tool: monadic composition. In Haskell, if you're not happy with a binary success/failure option provided by Maybe, you may use the Either sum type to pass around error messages. Since Either is also a monad, the same chaining and short-circuiting will work as well. Swift has sum types, too, but no monadic composition, so you're stuck. Optional chaining will give you exception-like functionality but without propagating any information about the type of the error. If you need error information, you'll have to fall back on manual error testing and propagation, which is painful, verbose, and error prone.

It looks like the designers of Swift got scared of the monad and stopped half way towards a usable functional language.

Upvote • 1 Comment • Share • Thank • Report • Written 6 Jun

---

https://news.ycombinator.com/item?id=9019498

---

https://developer.ibm.com/swift/2016/01/27/seven-swift-snares-how-to-avoid-them/

---