Swift 2.2 Released
swift.org
swift.org
The only part that frustrates me is that SourceKit seems to crash every other minute for no apparent reason - but that is no fault of the language itself.
Swift is the first piece of Apple software I'm genuinely excited for. Congrats to everyone who contributed to the 2.2 release
e.g.? I've only just scratched the surface of Rust and dismissed C# as a Java clone (but maybe I shouldn't have?). What's some examples of the best of Swift that you see?
Generics were a cutting-edge feature in 2005. Microsoft took the opportunity to start from scratch, and released the .Net Framework 2.0 without backwards-compatibility, and with full support for generics. A List<String> is actually a List of String.
When Sun released Java 5, they didn't want to disrupt the established Java ecosystem. Their implementation is called "type erasure". As an example, List<String> is actually just List<Object>, with automatic runtime typecasting to String. https://docs.oracle.com/javase/tutorial/java/generics/erasur...
Java's solution works well enough, but it breaks down in certain scenarios, such as multiple levels of generics. For example, when getting an element from a List<List<String>>, Object is not cast to List<String> (which doesn't really exist), but merely List.
C#'s implementation of generics became even more sophisticated with C#4, which introduced covariance and contravariance. https://msdn.microsoft.com/en-us/library/ee207183.aspx
Generics have been around since at least the early '80s.
Another interesting failed prototype on the JVM was the language "Pizza" https://en.wikipedia.org/wiki/Pizza_%28programming_language%...
https://en.wikibooks.org/wiki/Ada_Programming/Generics
http://www.cs.dartmouth.edu/reports/TR86-104.pdf
(From 1984.)
I'm not sure how this makes sense. These tags are just standard context bounds, which are extremely useful and quite awesome.
You make it sound as if these tags were some kind of special feature added to the language, or context bounds were solely invented to support these tags.
If a method needs to instantiate an object, the normal technique is to accept a factory function as a parameter. You can do the same thing with type-erased generics.
C# decided to create a shortcut for calling the constructor of a generic type parameter. But, for example, you can't call static methods of a generic type parameter (and a constructor is really just a slightly special static method).
I was already using C++ templates in 1994 with Borland C++ for Windows 3.1!
Ada, CLU and ML go back to the late 70's / early 80's.
It certainly worked at the time, for that specific compiler
C code also used to break left and right long after C90 was approved.
I had to use K&R C style code in 1999 because the HP-UX compiler at a customer location didn't knew any better, but that didn't mean other C features weren't available elsewhere.
Curious, what did you need to do specifically? Parameter declarations weren't inlined?
But anyway, C, being smaller, breaks in fewer ways
In those days HP-UX C compiler was still transitioning between K&R and ANSI standards.
We could only properly compile without strange errors while using K&R function declarations.
If memory serves me right, it was the first HP-UX release having support for 64bit file systems.
C++ templates are Turing complete, you can validate whatever you feel like at compile time.
You can write the following C++ code and C++ allows it:
<template typename T> void foo(const T& arg) { arg.bar(); }
This is perfectly fine for a macro system. But this is not how truly generic type system would work. If templates were proper generics, the typechecker would immediately refuse this to compile saying something like: "Error: I can't prove T has the bar() member."
> C++ templates are Turing complete, you can validate whatever you feel like at compile time.
So please write a template metaprogram that validates if a given C++ class (input to the program, given as a template argument) matches a table schema in the database system (the table name and connection string are also given as template arguments). For fetching the schema, you have to connect to the DB, of course at compile time. If the schema does not match, the compilation should fail ;)
Do you want an example how to write it properly?
With or without the upcoming concepts TS already in GCC 6.0?
Also this example would require T to be an interface with a bar method in C#. Do you also want to the the variant with MI and pure abstract classes in C+?
In a proper generic type system, the compiler validates it, not the programmer. Even if you constrain the type using type traits, the compiler would not check if the implementation satisfies the constraints. I can put a type trait for existence of bar() and then another programmer may rename bar() to baz() forgetting to update the constraint and the code will still compile fine.
I do admit that I need to update myself with what GCC 6.0 allows vs the letter of the TS.
template <typename T>
void foo(const T& arg) {
const Bar* b = arg;
b->bar();
}
or template <typename T>
void foo(const T& arg) {
static_assert(is_base_of<Bar, T>::value, "T must be a Bar");
arg.bar();
}
I can't say I'm a huge fan of either syntax, but the compiler will perform static type checking as if you had written where T : Bar in C#.It definitely has a downside for the development process, especially when it comes to writing libraries. But it is also to some degree inevitable if you want structural typing. Maybe there is a better way to do it though.
Further support for the idea that C++ templates are an automated copy+paste mechanism is that you're allowed to give templates arguments that are not types.
Further reading: https://msdn.microsoft.com/en-us/library/c6cyy67b.aspx
C# type checks imply a performance hit and are an implementation detail. Nothing prevents a C# compiler to choose another one. It has nothing to do with generics vs templates.
For example Modula-3 and Ada compilers use the same approach as C++ for code generation of their generics.
So where is that example of something that can only be written with C# generics, but not with C++ templates?
A github gist maybe?
That is what enable_if, type traits, if constexpr and eventually concepts allow for.
#include <string>
template <typename T>
void foo(const T& arg) {
int x = std::string("int expected");
}
$ g++ -c template.cpp
$ // see, no error
Templates are only syntax-checked. The type checker is not even executed on the non-generic code inside of templates. The type checker will be executed after the template is instantiated (expanded). At that point, generic types do not exist. There exist only concrete types.Uninstantiated templates are dead code that will be stripped anyway.
Sure, you can type-check them for particular type arguments. But you can't type-check them generally at the generic level and you have absolutely no guarantee that your library code is free of type errors. Not a problem if the goal is to produce the final executable, but a big problem for a library writer, who doesn't control the inputs (in this case: the types provided by the user of the library).
And AFAIK C++17 concepts do not address this problem, really. I can constrain my input types with them, and the calling code will be forced to conform to them (and the compiler will present a nice error message if it doesn't), but there is still no checking on the other side - that is if the template implementation is correct assuming these constraints. I can publicly declare my code requires T.bar(), then shamelessly call T.baz() in the template implementation and the compiler will not catch it.
This is like a Python program. You don't know if it type-checks before you run it, but even if you run it once or twice and it was fine, that doesn't guarantee there are no type errors.
The code line int x = std::string("int expected"); has zero relation with any of the template arguments.
So a programmer error that doesn't have anything to do with the types provided for the template.
Sure it will be caught in C#, because its build model assumes the existence of modules and everything is compiled to binary.
In C++ a similar compilation error would occur when compiling the translation unit into a library where the template is instantiated.
Of course, most templates being header only the error will only occur when instating it, but it will still blow on compilation and prevent the final generation of the exe, dll being produced.
Also errors related to semantic type check, independent of template arguments is relatively easy to achieve with unit tests.
I still fail to see how a generic system that doesn't offer partial specialization or meta-programming as being more powerful than templates.
By not doing runtime checks you get to skip that work at runtime, obviously, but you also get to enable other optimizations like inlining the monomorphised version.
Macro systems can be very powerful, but they are also quite hard to use. It is 2016 and error messages in C++ templates are still inferior to the messages you get in C#, Java or Scala generics, despite templates existing for much longer.
C++ templates are also not the very best at metaprogramming either. Take any macro system like the ones found in LISPs, Scala or Template Haskell - they are much more powerful and consistent with the rest of the language. I can code Scala metaprograms in Scala or LISP metaprograms in LISP. But I can't code C++ metaprograms in C++, I have to use this weird duck-typed functional template language which doesn't have even loops or conditionals.
I have experience in compiler design and C#, Java and C++ are my tools of trade. So I know their generics systems pretty well.
Maybe if I get bored during Easter I can bother to provide your safe list.
This sentence doesn't make much sense. Comparing oranges and apples. It is like saying Scala macros are better than Scala generics. C++ templates are neither great at metaprogramming (there are much better macro systems in other languages out there) nor great at generics (Java, C# or Swift generics are not state-of-the-art either, but in some cases I mentioned they are better).
IntelliJ absolutely trounces VSS and some combination of Spring Boot, DropWizard or Vert.x blows ASP.NET MVC away. Not to mention the whole ecosystem is a hell of a lot more open. There is a library for just about anything under the sun.
It gets even worse on desktops, as sysadmins might be able to isolate a server enough to allow some "new" tech, but vetting a new Java version or library for a few thousand office desktops is a task nobody really wants to do. So I wouldn't be surprised to still see some Java 1.4 Swing apps in use at big insurance or pharma companies. (And if I'd had to pick between that or do a web app that supports their IE8 browsers…)
The same thing applies to many other software packages, including browsers, Linux and Spring. Sane IA folks don't like to deploy known security holes.
It sounds like you're dealing with some backwards-thinking folk. ;-)
The alternative is auditing all your installed software packages with Java dependencies. Re-hire the agency that did that small Swing client 8 years ago. Hire someone completely new to reverse engineer another client because the original company went belly up. Ad infinitum, ad nauseam.
No wonder they'll do software cryonics.
This is getting better slightly in recent years, when you no longer have that many desktop clients and utilities, as upgrading servers is way easier than building new default images for all your desktop clients.
It definitely looks like that, but I'll take C# over Java any day
Java API looks like it was built by the worse bureaucrats they could find and one piece doesn't fit another except in a very specific (non-obvious) way
But most importantly to me, Swift is composed in such a way that it just 'clicks' for me, ie many times many times I can guess how something is likely called or how it will behave without looking at the docs and I have a solid chance of being right - that 'intuitiveness' is something that is lacking in many other languages I've used over the years.
In regards to C#, by now it is definitely not just a Java clone anymore, in particular saner type system and much more functional features edge it for me over Java, plus the speed of evolution is much greater in the C# land. If you want to see how C# and Java differ but are tied to the JVM, try Kotlin: http://kotlinlang.org - it's fairly similar in feel to C# and has 100% Java compatibility.
There's a way to dance around that restriction, by making an intermediate class to do type erasure by hand (why I should do that? That's compiler's job), but still - Swift crew are obviously very talented bunch with a good taste, how they allowed such nonsense from the start?
PS I don't want to sound too negative, Swift replaced C# as my favorite language, 95% of the time it's joy to use (especially after Objective C, I never agreed with that language), it's just - the generic protocol thing drives me mad.
https://github.com/apple/swift-evolution/blob/master/proposa...
https://github.com/apple/swift-evolution/blob/master/proposa...
In Swift 3.0 they'll remove the deprecated syntaxes.
https://github.com/apple/swift-evolution/blob/master/proposa...
https://github.com/apple/swift-evolution/blob/master/proposa...
I just spent a while reading about both stride and for ... in, and I feel like there are any number of cases where I would rather use a C-style for loop.
for i in range(10):
instead.
for item in sequence:
which is somewhat general (sequences include lists, dicts, strings, tuples, generators, text files and more [2]), and it covers a wide range [1] of use cases.
[1] Pun not intended.
[2] Basically, any iterable. This include custom iterables you can define, which can then be iterated over using the same standard for loop. A unifying feature of the language:
"The use of iterators pervades and unifies Python."
Could you use a while loop instead?
I feel like (as long as the numerical case optimizes to the same thing) the for-in loop (and occasional use of the while loop) is clearer.
// old
for x: Thing? = thing; x != nil; x = x.parent {
...
}// and now
var x: Thing? = thing
while x != nil {
...
x = x.parent
}It was the only case i've really missed it.. unless theres a better way to do it that im not aware of..
But the for c-style loop for numbers is really not needed
func someFunction<T>(initial: T, next: T -> T?) -> T
{
var current = initial
while true
{
switch next(current)
{
case .Some(let value):
current = value
case .None:
return current
}
}
}
Now you can express that idea generally, e.g.: extension UIView
{
var rootView: UIView
{
return someFunction(self, next: { view in view.superview })
}
}
I also didn't test it, so it might not work.Of course, it would be more Swifty to create a "Parentable" protocol and write that as an extension of it!
This only exists for objective-c introp, and the creators are actively trying to find ways to get rid of it. On the other hand, in nearly every other language, all pointers would be considered implicitly unwrapped optionals, while in Swift you get optionals built in (food for thought).
>awkward syntax where you need exclamation marks all
Oh come on, syntax does not define a language. If they used a different character or an operator, would you be more happy? Either way, it does take some getting used to but eventually it feels natural.
>insanely complicated use of enumerations
What?! This is one of my favorite features! You can represent so many things with an enum and it can make your code much safer. My favorite two examples are representing JSON as an enum, and the fact that Swift's Optional is actually just an enum with cases .none and .some(T).
>basic string operations such as doing a substring are unnecessarily complicated and verbose
I somewhat agree with you on this. They have their reasons (mostly because strings can have varying sizes, so indexing a utf8 string, for example, can give unexpected results) but I still wish they did something about it.
> error: opening import file for module 'SwiftShims': No such file or directory
Apparently the problem with GCC ABI break hasn't been tackled yet.
https://bugs.swift.org/browse/SR-23
As info, the only workaround is to rebuild Swift from scratch.
I’m thoroughly convinced that Apple has an internal-only IDE that they use that is far better than Xcode and is actually functional, much like the internal Radar tool. There is no way Apple’s engineers could get any work done if they use Xcode.
Or, they should start charging money for it so they could justify spending resources on the dev tools. One of the reasons (among many) that Visual Studio is still the king of all IDEs is because Microsoft charges money for the serious bits of it (Pro and higher).
I'm sorry, but LLVM?
That's an interesting point and it makes a lot of sense. With the scale of the codebases a lot of them are working on I also don't see how they could be productive while working in XCode. And also XCode could not be this buggy and broken if it had internal developers working with it and constantly reporting bugs.
personally, I'm the kind of guy with a "vim 4 life" tattoo, so I don't really know why people put up with crappy IDEs...
I've never liked Visual Studio, and the last time I worked on a serious Windows product most of the experienced developers used WinDbg and cordbg rather than the neutered Visual Studio debugger. And some guys still wrote their code in Visual Studio 6 rather than the newer .NET IDEs.
My problem with Xcode today is that it's too much like Visual Studio. I'll take Xcode 3 with LLDB any day.
What I want is a way to take any view I please, from any application, and arrange it anywhere in a standard way with keyboard support and sensible omissions of chrome. If this means 65% of my screen is terminals, 20% web browsers, 10% some graphical view from Xcode and 5% notifications, that should be perfect fine. Instead, the most the Mac has been able to cobble together is a simple split screen view and that is only for Full Screen.
And, we also have: Xcode with its own completely custom and quirky pane/tab management scheme, terminals with their own pane/tab scheme, browsers with their own tabs, etc. Individual applications continue to feel some need to over-engineer their own pane/window management to compensate for lack of system support.
There are some signs of hope though. The direction Apple is going with Mac view controllers could theoretically put them in a position to finally turn individual views into first-class citizens that would be feasible to interleave arbitrarily across applications. At that point, command-line tools could integrate very nicely in arbitrary ways with elements that really benefit from being graphical. We’ll see.
Yup! They're free! I have found Apple's developer ecosystem to be fantastic overall.
Xcode for iOS and Mac development has been the most productive IDE I've used professionally, not without its flaws, and unintuitive nuances, but continually improving. Yearly major ticket feature additions like UI Unit testing shows me Apple is still heavily investing in developer tools.
You mean by still not being able to provide an working experience to the NDK users, three years later?
Or by redoing their plugins for Android Studio 2.0, forcing devs that rely on something stable to still be on Android Studio 1.5?
Also by having each release be a bug party that make people at /r/androiddev/ wonder if they ever test what they release?