Defining Golang features that don't exist in Swift:
- Interface types with implicit adoption (Swift takes explicit protocols from ObjC)
- Error types
- Relatedly, the "damnable use requirement" and its interaction with error types and multiple value returns (ie, the reason Golang programs in practice check errors more carefully than C programs).
- Slice types
- Type switching (though, like Golang, it does have type assertions)
- "defer"
- Of course, CSP and the "select" statement.
Swift features that don't exist in Golang:
- Generics
- Optionals
- A conventional, full-featured class-model
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).
But for others aspects that are not related these two(class system, concurrency), I would say they look quite similar.
Someone is always going to be out there saying that any language isn't ready for prime time because it lacks feature-X.
I'm surprised not to hear Python mentioned, as it also has a tuple syntax.
Yes, Swift's semantics are different (since it's essentially a domain-specific language designed to make writing Cocoa apps faster), but syntax-wise a Go programmer feels right at home reading Swift.
Because, the keyword for function, keyword, parens-free conditionals and optional semi-colons are "the entire basic syntax" of Go, right?
Those are some of the most inconsequential details of Go syntax (all three of them), and of course all existed ages before Go.
Python has no semicolons and parens-free conditionals for one.
Objective-C has informal protocols, and so does Swift.
How about a blog series where a developer implements something in Golang and/or Swift, then you explain how it's insecure? Then the developer tries to fix it and you explain something else that's insecure. Rinse, repeat.
There are some things that did strike me as similar. The approach Go takes is to bring C language to a more modern world (i.e. C without some of the language burdens that we know so well). Swift is attempting to do the same. The way it does type inference is nice.
var x = "Hi" reminds me of Go's const types. The ARC usage reminds me of Go's garbage collection (even though it's not the same thing). Basically, the parts that it omits from C are similar to the parts that Go takes out of C even though the language itself is different... thankfully.
Like all the other thousands of languages with C based syntax.
> var x = "Hi" reminds me of Go's const types
Why does it remind you of Go and not of all the other languages that use 'var x = "Hi"' like JavaScript, ActionScript, C#, Scala, Kotlin?
> The ARC usage reminds me of Go's garbage collection
Why does it remind you of Go and not of all the other languages with garbage collection?
I haven't gotten to Swift in a deep enough way, but it looks like it tried to tackle the same problems with the exception of concurrency. There are differences such as classes and generics in Swift. There are also similarities such as functions as first class citizens (or so it appears so from the closures section of the free book).
All in all, it reminds me of Go just a bit. It doesn't remind me of all of those other languages that I do not know.
You sound old. ;)
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.
The optional type stuff is good, and it will definitely be a net safety improvement, but it's by no means attempting to approach a panacea to safety like Rust's strict static analysis does.
Particularly that Swift gives you really simple outs in the form of the '!' unwrap and 'as' (should be 'as!' at least imo) downcast-and-unwrap operators that result in run-time errors and will probably be seen as unremoveable code-smell in a couple of years.
Swift could very well render Rust almost totally irrelevant within the OS X and iOS sphere of software development. If we end up eventually seeing Swift implemented for other platforms, then the chances of Rust's long-term success diminish even more.
Things might have been different had a stable, even if somewhat imperfect, initial version of Rust had been released by now, thus allowing it to gain some adoption and traction.
I hope that the "But Rust isn't targeting those developers!" argument isn't used to try to justify this mistake, as well. Rust is already facing stiff competition from languages like Go, C++11, C++14, Scala and even Java 8.
With the announcement of Swift, Rust's niche and audience are getting smaller, further preventing the widespread adoption that's necessary for a programming language to become truly successful.
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.
(In fact, on a personal note, I'm ecstatic that Swift has been announced. ADTs! Optional types! Pattern matching! Think of how many features are no longer alien to people who want to learn Rust! And hell, the syntax is incredibly similar as well, which further reduces friction. As a hardcore Rust contributor, I want to shake the hand of each and every one of Swift's designers.)
FWIW, Swift is categorized as a systems language in the opening pages. But, then, so does Go in its FAQ. To Swift's credit, at least it has deterministic memory management through ARC.
In general, reference counting has the problem that it needs to update the reference count. If you have a read-only data-structure these updates to the references will introduce writes that may severely impact performance since a write introduces cache consistency communication, while reads are communication-free.
It may not be ready as a systems language in its pre-1.0 form, but the Swift book claims that it's "designed to scale gracefully from ‘Hello World’ to an entire operating system", so Apple appears to have big goals.
Given Rust's PR, speaking of that -- not a thread about Go passes without at least three pcwalton comments these days -- I actually broke down and gave it a try. I wrote a little Hello World server and then got lambasted by a friend of mine for not working functionally, since, in his words, "Rust is a functional language and the fact that it supports other paradigms is a mistake." I rm -rf'd and ignore it for now, but I look forward to it stabilizing and maybe coming back to it.
Rust has potential but the PR needs to ease up just a little. There is room for more than one language in the world.
Well, every thread about Go inevitably has numerous comments comparing it to Rust, often erroneously, and pcwalton is one of the primary Rust developers.
(small-time rust contributor here too)
That said, Swift's types are a bit less than recursive, so there's a bit of niggling still before you get to the affordances of something like Haskell's `data`.
Also, even in systems, I can think of about once a decade I even need to write assembly, so... maybe grasping at straws a bit?
That said, I think inline assembler is an important feature:
> It's interesting that inline assembly is your first bullet point, since there's nothing I can think of that ruins a code file more than inline assembly in a host language. Put that crap in a .S file and link it in like everything else, for crying out loud.
That's too slow. You need to give the optimizer more information than that, and the overhead of the procedure call can be significant.
> The one time you need inline assembly is when you don't want to build a function frame, such as a tight loop, but come on.
But that's a very important use case.
> Also, even in systems, I can think of about once a decade I even need to write assembly, so... maybe grasping at straws a bit?
It's all over the place in the Linux kernel.
For Rust. I didn't make the comparison to Rust, I merely was intrigued by the choice of features and in which order to defend the comparison made by someone else. I see Rust and Swift as targeting entirely different things, at least at first (which means that Swift can certainly evolve inline assembly if it is so needed), and any comparison at this stage is pointless.
> It's all over the place in the Linux kernel.
Cool, that's one piece of software. I'll save you the next few: drivers and a couple files in a game engine. You're disputing my point how, exactly?
That said, judging by your other comments, you seem to be of the impression that the Rust team has some sort of vendetta against Go, and have concocted a vendetta in kind. Again, I must sadly disappoint you, but I strive to encourage a culture of respect in all the forums that I visit (and moderate).
The last sentence of the comment to which you hint is my thesis. There is no subtext. It's easy to perceive negative opinions as attacks and create an adversary from the person writing the opinion, but it's also a little bit disingenuous. It also, conveniently, creates a platform upon which nobody can disagree with you lest they be hostile and aggressive. You can then exit on the "high ground," as you've done here.
I meant no ill will. Best of luck, I guess.
This is hilarious. Like anyone would ever use inline assembly in a tight loop.
Perhaps this is news to you, but those of us who work on and are responsible for large-scale software systems tend to take such factors very seriously.
This may sound harsh, but it really doesn't matter what features and benefits Rust could potentially bring to the table if the lack of stability makes it unusable in practice today. A programming language that can't be seriously used might as well not even exist.
I don't doubt that Apple will have Swift available in a seriously usable form by this fall, and it's very likely that it will see rapid adoption soon after. I'm afraid I can't say the same about Rust and its supposed by-the-end-of-2014 1.0 release, given its current lack of stability and the rapidly-approaching end of the year.
1. Release fast and iterate
2. Release fast and be stuck with mistakes
3. Release slow
Option #1 breaks stability, so that's out.Swift appears to be taking option #2 (Apple doesn't commonly break APIs, do they?), but we can't even really be sure because it hasn't been developed in the open the way that Rust has. It's possible that it's been in development as long as Rust, and we simply haven't heard about it yet. Either way, option #2 is a perfectly reasonable one to go with; it has served Java quite well (for a loose definition of fast), though it has required some creative approaches to language improvements.
Rust is taking option #3. C has been around for over 40 years now. If Rust hopes to supplant it, it seems reasonable to take a few extra months (or even an extra year) to put out a solid version 1 that won't hamstring the language or force a breaking change down the line.
This is actually nice, because knowing about languages years before they are production ready probably just slows developer adoption because nobody is quite sure when they should trust there development process to a new language.
You also didn't realize that you just built the biggest strawman ever in the above sentence.
Enough with the "I want a stable Rust now". Rust, like any other language, takes years to stabilize. You just happen to see it happen in the open, whereas most other languages you get them at their 1.0 release.
>This may sound harsh, but it really doesn't matter what features and benefits Rust could potentially bring to the table if the lack of stability makes it unusable in practice today. A programming language that can't be seriously used might as well not even exist.
They could not give a flying duck about it being "seriously used today".
They'll start to care AFTER they release it as 1.0. They only released this 0.x versions to solicit ideas and improvements, not to get programmer's to adopt it.
Assuming this stabilization actually does happen, whether it happens in public or private is irrelevant.
What matters is that we've seen C++ stabilize. We've seen Go stabilize. We've seen Scala stabilize. And now we'll likely see Swift stabilize, well before Rust does. They are all serious competitors to Rust.
As these other languages continue to evolve, but at the same time remaining usable, the relevance of Rust will continually decrease. It may still have drawing power today. A few years from now, it will have less appeal.
It's hard to make a comparison against Swift, which is a proprietary language developed for years behind closed doors. Presumably they're at 1.0 from the first day by design. You can't do that with open source languages.
It's pretty absurd to expect Rust to be stable right from the get go. The difference in all this is that most of those languages were closed before being released. Rust was open at a pretty early state.
Personally, I consider the 0.1 release in January 2012 to mark Rust's "birthday". Everything prior to that was just gestation. :)
If you like it, perhaps you should be a little patient and give the creators the benefit of the doubt. No one wants a Rust 3.0 fiasco.
It's hard to encounter language issues without implementing a large project in the language. I am happy that they're taking the time to let the implementation of Servo help inform the design of Rust.
In other words, Rust is about safety with zero overhead over C++, and Swift is not zero-overhead. So the people who need Rust are not going to use Swift for Rust's domains. That's fine, as Apple wanted a language for iOS and Mac app development with tight integration with Objective-C, and from what I've seen they've done a great job of developing one.
> Things might have been different had a stable, even if somewhat imperfect, initial version of Rust had been released by now, thus allowing it to gain some adoption and traction.
Why are you so insistent that we freeze an unsafe version of a language that's designed for safety?
Pacabel has made a career of complaining about Rust being unstable.
I think that the recent, and very disruptive, ~ and box changes should completely dispel that notion.
I'm merely pointing out the reality of the current situation, which some in the Rust community do not wish to acknowledge, for whatever reason. The situation has yet to change, so what I'm saying is still valid, and will remain so until some actual improvement does take place.
Now that we see yet another serious competitor in the form of Swift, what I've had to unfortunately be saying for some time now becomes more and more relevant. If Rust is to become relevant, it will need to be usable, and that will need to happen very quickly.
To be crystal clear: no-one is suggesting that Rust is stable and no-one is suggesting it is ready for adoption (if they are, they are wrong). However, being unstable now is very very different to not ever being stable.
In any case, Swift is only tangentially a Rust competitor as kibwen demonstrated.
Rust is not stable, as you yourself have readily admitted. What I've unfortunately had to be pointing out for such a long time now is absolutely correct.
We've been told that we can expect Rust 1.0 by the end of the year. As each month passes, it becomes less and less likely that we will actually see this. We are still seeing significant change, even as recently as the past month.
I think Rust could potentially be very useful. But that requires stability, and that in turn is something that appears more and more elusive each day.
It's easy to say that Swift isn't a competitor to Rust, but the reality is that it is. And unlike Rust, it will very, very likely be usable for serious apps within a few months. It will see the adoption that Rust could have had, had it been usable, further reducing Rust's future changes.
All of those are highly uncontroversial and universally acknowledged by experienced Rust users.
Also, I don't understand how you have lept from Rust being unstable now, to Rust never being stable.
A 1.0 release by the end of the year doesn't seem at all unreasonable to me; I think you are expecting more from it than what the Rust team is looking for (and have stated publicly repeatedly): stabilising the core language.
Of course, a stable release of that form will still mean some libraries may be unstable (and so that Rust would be unsuitable for many corporate developments). These libraries will be stabilised progressively and iteratively.
No, he merely suggests that you bored a lot of people by repeating that it's unstable, instead of accepting the fact and using something else.
If being unstable is that bad, then by all means, go and use a stable language.
There are numerous alternatives to Rust that offer many of its benefits, but they're usable today. We can rely on them today, tomorrow, and likely for some time to come.
And by this fall, we'll likely have Swift as yet another option to add to our growing list.
I think Rust has a lot of potential. But each month that goes by squanders that potential. It has less and less of a chance of making a real impact the longer it isn't usable, especially while its competitors keep evolving.
Yeah, and I listen to Rihanna instead of Jay Farrar. Obviously that's the big problem Jay is facing, and he should sound more like Rihanna to cater to my taste.
No, he didn't say that anywhere.
The recent, and rather disruptive, box changes are a good example of this. We see change, and those of us with existing Rust code sure do feel the change, but very little convergence seems to be happening.
Based on past trends, I would not be at all surprised if problems are found with the new approach as it becomes more widely used, and some other approach is then attempted.
Wheel-spinning is something that can quite easily happen with ambitious software projects. It's not a new phenomenon. But when facing ever-increasing competition, and other real-world constraints, it's often better to aim slightly lower and at least be mostly usable in practice.
A memory-safe programming language that can't actually be used is pretty much irrelevant. It's better to accept some slight amount of imperfection if that means it can actually be used.
I believe it is, as the basic structure and rules of the borrow check (which is the part of Rust that's truly unique) have proven themselves to be quite usable. The usability problems remaining are implementation and precision (e.g. issue #6393), not big problems that will require large redesigns.
> The recent, and rather disruptive, box changes are a good example of this. We see change, and those of us with existing Rust code sure do feel the change, but very little convergence seems to be happening.
Yes, it is. The number of outstanding backwards incompatible language changes is decreasing. People who do Rust upgrades notice how the language is changing less and less.
> A memory-safe programming language that can't actually be used is pretty much irrelevant. It's better to accept some slight amount of imperfection if that means it can actually be used.
"Some slight amount of imperfection" means not memory-safe. Java didn't settle for that, C# didn't settle for that, Swift isn't settling for that, and we aren't settling for it.
At the end of the day, if Rust fails, well that will be a shame. But I'm seeing nothing that shows that it might, so I'm truly struggling to understand why you seem so upset by a new modern language trying to tackle big problems in ways that have never been done before. That's a good thing, as far as I'm concerned.
I bring this up again and again because I'd rather not see Rust fail. I'd much rather see a slightly flawed Rust that's actually usable in the short term, rather than a continually changing Rust that nobody will seriously adopt.
Rust has been in development for years now. That's a very long time in the software industry. A few years of development time without a stable release is understandable. But it's getting beyond that now.
Rust isn't quite there yet, but each day it edges closer to a Perl 6 type of disaster. Perl 6 offered some intriguing ideas, but it just isn't usable, and that's a shame. Meanwhile, other competitors have arisen and blown past it, rendering it far less useful were it ever properly implemented.
Given the increasingly stiff competition that Rust is facing, I suspect we'll see it end up like Haskell or D. Something usable is eventually produced, but it never sees the truly widespread adoption that it could have seen, had it been usable earlier on. It's not as bad as Perl 6's situation, but it is still unfortunate.
I don't have much to say about D, but the history of Haskell implied by this sentence is hilariously wrong.
Go watch Simon Peyton Jones' talk about the history of Haskell: http://research.microsoft.com/en-us/um/people/simonpj/papers.... As well as being wonderfully entertaining, it explains the actual history of Haskell: it was designed to be a language with which various academic groups could do functional programming language research. The fact that Haskell has gradually grown more popular and now has mainstream appeal and some industrial users is quite a surprise to its creators.
Not for programming languages. These take years and years. Take a stab at any of the most popular languages. They weren't created 1-3 years ago. It takes time, and that's a good thing.
But as an industry, we need practical solutions that are available now, even if somewhat flawed. We need languages we can use today, and know that the code we write today will still compile fine next week and next year, if not a decade or more from now.
Modern C++ is getting pretty good at offering this, while offering far a greater degree of safety. Go isn't bad, either. Scala has its drawbacks, but it's often a reasonable option, too. The key thing to remember is that all of these languages have offered developers a stable target, and they are seriously usable in the present.
Given the announcement of Swift, and given that Apple will very likely deliver on it by the fall, we very well could see it becoming a major player during 2015.
The safety benefits that Rust could theoretically or potentially offer are virtually useless to huge swaths of the industry as long as the predictability of a stable release just isn't there. The longer this wait goes on, the better the competition becomes, and the less relevant Rust will unfortunately become in the long term.
By this logic we shouldn't invent any new programming languages at all. There's no such thing as a "practical solution that's available now"; everything takes time to develop.
> Modern C++ is getting pretty good at offering this, while offering far a greater degree of safety. Go isn't bad, either. Scala has its drawbacks, but it's often a reasonable option, too. The key thing to remember is that all of these languages have offered developers a stable target, and they are seriously usable in the present.
You aren't going to use those languages if you want memory safety without garbage collection. Because they can't offer zero-overhead memory safety without breaking existing code.
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)
In the other direction, XCode will automatically generate an Objective-C header to expose your Swift code to Objective-C.
If the book is good documentation, then use it. But you may benefit from focusing more on problems than completing a book.
Honestly skimming 500 doesn't sound horribly hard to me. I've done that a few times to pick up something new. As ap said you won't learn the language like that but you will have a good reference to go and learn from after the fact.
After that you could probably work through the examples in said book, or at least the interesting ones.
P.S. above steps is all I really learnt from my cs degree.
Definitely take a look through it. You definitely don't need to be a language nerd to understand it.
For me it looks like Scala + a sprinkle of C++14 :)
Jacob Leverich https://leverich.github.io/swiftislikescala/
Den Shabalin http://www.scribd.com/doc/227879724/Swift-vs-Scala-2-11
Just as a point of fact, javascript -- at least the v8 implementation I'm most knowledgeable of -- doesn't "keep the entire context alive forever." Only variables used in the closure are allocated into the closure (i.e. on the heap), the others are allocated on the stack and disappear as soon as the function returns.
I don't use iTunes so can't read their book, but I wanted to ask: you say that ARC is still their GC strategy, correct? So reference cycles are still an issue? I'm surprised at this. I can see reference counting being a strategy for moving a non-GC'd language to GC (like Objective-C), but to start a new language with that constraint is surprising.
I'm not sure that's true. Look at the following code:
var x = 123;
var f = function(xname) {
eval('console.log('+xname+');');
}
f('x');
It's a dynamically named variable. Clearly, f() has access to the entire context that surrounds it, not just the objects explicitly used in the function code. In this example, the compiler could not possibly have known I was going to access x.This means in Javascript, as well as in Ruby, when you hand a closure to my code, I can access the entire environment of that closure.
Contrast that with Lua, for example, where the compiler does indeed check whether an outer variable is being used and then it imports that variable from the context only.
PHP does it most explicitly, forcing the developer to declare what outer objects they want to have available within the function.
Right, but it knew you were going to use eval, and to support that, it had to allocate all local variables in the closure. That's why you saw this behavior. The same would happen if you used a 'with' construct.
Wow, so there is actually special handling in the engine for this? So it does static analysis whenever it can, but not in these two cases?
function f() {var x = 99; return function(a,b) {return a(b)};}
f()(eval, 'console.log(x);')
ReferenceError: x is not defined
function f() {var x = 99; return function(a,b) {return eval(b)};}
f()(eval, 'console.log(x);')
99
undefinedThe original assertion by curveship was that the outer context is not kept alive for the function, and that f() only gets access to the variables it explicitly imports from the outer context. And I thought this might be wrong, so I cooked up the example.
Again, this is not about scope. This is about the fact that the function itself keeps a reference to the entire context it was created in, as opposed to just the things it explicitly imports.
In this, it appears, Javascript works exactly as Ruby, which again makes the entire outer context available through the binding facility.
I'm sorry if that wasn't clear from my description.
See here for an example: https://www.meteor.com/blog/2013/08/13/an-interesting-kind-o...
This bug is still not fixed. There's an issue open for it on the V8 tracker, I believe. It seems to have not gotten fixed in either engine because it's a difficult problem that affects a small subset of JS applications.
V8 has seen a lot of really nice optimizations to closures over the last year. My favorite is that closures are no longer considered megamorphic.
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.