Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Swift vs. Go (sapan.svbtle.com)
37 points by supster on April 1, 2016 | hide | past | favorite | 68 comments


The list doesn't mention optionals in Swift. Optionals are a substitute for nil/NULL and handle the absence of a value in a type-safe manner. It is similar to the Maybe type in Haskell.

(BTW, if you're interested in Swift, I send a weekly newsletter at http://swiftnews.co)


I also maintain a collection of list resources. I have daily and weekly views as well, as the ability to search:

http://www.h4labs.com/dev/ios/swift.html?week=0

http://www.h4labs.com/dev/ios/swift.html?date=0

http://www.h4labs.com/dev/ios/swift.html

My server is written in Go and runs on AppEngine. I like both Swift and Go. It's more convenient to work with one language but Swift probably needs a couple more years to bake on Linux. Go is fast enough that my AppEngine server never has performance issues. I highly recommend it.


Good catch, I added it to the list


Optionals aren't a “functional concept”, whatever that means. They're just another data type, like tuples, lists, trees, etc.


Actually they are a special type of Monad which is a functional programming concept (see Haskell).


Yes, and lists [not necessarily linked lists] could have a Monad instance too. Does this make lists a “functional concept”?


It should be implied by generics. But it looks like Swift has some special sugar for it, neat.


Is Swift a general purpose language? I thought it was for iOS and Mac development. I understand it is open source, but so is C#, and I don't see a lot of people using that outside of Windows (I could be wrong though).


I think C# is pretty a pretty common cross-platform language for games due to Unity's support for it. It's not common for other apps, though.

I don't think there's much cross-platform work being done in Swift yet. Give it a little time, though, it's only been open sourced for a few months.

One nice thing about it compared to many other languages is that it can use C APIs with almost no work. There's no need to screw around with annoying FFI systems, you just point the compiler at your C headers and the calls become available in Swift. They may not be very idiomatic Swift, but they're at least no more difficult to use in Swift than they are in C. That means that you don't necessarily need a bunch of Swift libraries to be built before you can start getting stuff done.


If you're looking for stable code with an actual complete, working standard library, it's restricted to iOS and Mac development right now.

Support for other platforms is an area of active development right now, though. The language itself is pretty much already there (for Linux, at least), with an official release for Ubuntu (and it's buildable on other distros), but the supporting frameworks around it are still a work in progress.


It definitely started off for only iOS & Mac. But I believe the larger aim is to have it be general purpose. For example they have binaries for Ubuntu Linux (this will likely encourage server side development).


C# is the native language for the Unity game engine, which is very cross-platform. Now you can use several languages, but I think originally it was C# only.


> inferred strong static typing

“strong” compared to what? Go's duck-typing actually makes it weaker than a lot more type systems than you might expect, and compared to something like Haskell or Rust, both of these type systems are incredibly weak. If you're comparing to C, then sure, but “strong” and “weak” typing mean nothing without reference to another language.


Go's duck-typing actually makes it weaker than a lot of type systems you might expect

For me, it's strong enough and very versatile. It's stronger than what you effectively get in, say, Smalltalk. (Which, technically is strongly typed, having only 1 type of Object.) Having Interfaces explicitly documented in 1 place, but usable through duck typing is genius language design, in my view.


“Strong enough for what I want” is fine. But the author's point is unclear. Strong compared to what? Did the author mean “strong compared to Smalltalk”? Did the author mean “Go and Swift are Equally Strong”?

“Strong” and “Weak” don't mean anything in discussions of typing without a reference-point.


“Strong” vs. “weak” doesn't mean anything at all. Let's stick to distinctions that actually make sense:

(0) Statically typed [e.g., Java] vs. not statically typed [e.g., Python].

(1) Dynamically typed [e.g., Java] vs. not dynamically typed [e.g., Haskell]. Yes, Java is both statically and dynamically typed.

(2) Safe for arbitrary resources [e.g., Rust] vs. only memory-safe [e.g., Python] vs. totally unsafe [e.g., Objective-C].

(3) Typeful [e.g., Haskell] vs. not typeful [e.g., Objective-C].

(4) Global [e.g., Standard ML] vs. local [e.g., Scala] vs. no type inference at all [e.g., Java].

(5) Reflective [e.g., Common Lisp] vs. not reflective [e.g. Rust].

(6) Fixed [e.g., Standard ML] vs. extensible on top of a fixed core [e.g., C++] vs. extensible and modifiable [e.g., Common Lisp].


This is a very good list.

With respect to Haskell and dynamic typing, I am curious whether you had considered Typeable and Data.Dynamic in your analysis (and, in general, your thoughts on how they relate to the distinction being made).


If I understand correctly, and I might be wrong, `Typeable` and `Data.Dynamic` require dedicated support from GHC, and couldn't possibly be implemented entirely as user libraries. This makes them core language features in my book. So the language specified in the Haskell Report isn't dynamically typed, but the GHC Haskell dialect is dynamically typed.


I believe the situation is that Dynamic only requires Typeable, and Typeable only requires unsafeCoerce plus the trust that bad instances are never created.


> unsafeCoerce

GHC-specific implementation detail.

> the trust that bad instances are never created

The only way I can trust it is if the compiler enforces it, at which point it isn't “just a library feature”.


Ah, yes, report vs ghc is sometimes a very important distinction. Your assessment sounds correct.


Swift's is true strong [Edit: I should have said "static"] typing. The compiler enforces it but saves you from having to explicitly specify it in unambiguous cases. So:

  let x: Int = 3
  let y: Int = x
and

  let x = 3
  let y = x
are identical; in both cases, x and y are both strongly-typed as Int.


You are confusing static typing and strong typing.

I understand that both Go and Swift are statically typed. My comment is about saying that Go and Swift have type systems which are really strong, but such an assertion means nothing unless you give a point of reference (i.e., “strong compared to X”)

To clarify, type inference and strength (or strictness actually) of typing are completely unrelated. For example, Haskell, which is statically typed (and far stronger than most other languages out there—though certainly not the strongest) has incredibly good type-inference, so you rarely need to specify types.


FWIW, duck-typing happens at runtime, what Go has is structural typing.


I had no idea there was a formal definition of Duck Typing. Because if we merely "duck type" Duck Typing...if it looks and sounds like it...



In this context, strong as compared to Ruby/Python/Javascript


Seems odd to lump Python (which is pretty strongly typed) with Ruby and JavaScript (JS especially not being strong). Edit: Actually this whole thread makes it seem like we all have our own different definitions on what makes something "strongly typed" (or just confusion with strong and static). For myself, a language's type system's relative strength is all about how it handles (or doesn't handle) implicit type conversions.


This is roughly my point.

“Strong” and “Weak” are inherently relative terms; so, when used without a reference point, they will mean something different to different people. So, without a point of reference, the terms are not useful.


Even being inherently relative, you still need to determine the underlying values with some metric (like implicit type conversions, or max deadlift). If you tell me someone's max deadlift is twice their bodyweight, that tells me they're strong, even if it doesn't tell me their relative strength compared to say Sigmarsson. If someone says "Language X generally forces you to be explicit with your type conversions" that tells me it's strongly typed. Is it more strongly typed than language Y? That depends on explicitness exceptions -- e.g. Java does implicit autoboxing and toString()ing when you're doing string concatenation, Go effectively type aliases primitives so that e.g. net.IP can implicitly convert to []byte, Python complains when you don't explicitly call str() on things but converts numbers pretty freely (like auto-converting to a bignum, whereas other languages might throw an exception or automatically and silently wrap-around to a much smaller number than expected).


“Strong typing” doesn't mean anything when comparing languages. The difference between raising a `TypeError` at runtime or silently doing something wrong is entirely a matter of standard library design. For example, you can replace Python's built-in lists with your own list class that is as “weakly typed” as you want. But, from the point of view of programming languages, the only thing that matters is that an unwanted situation couldn't be ruled out by the language itself.


I lump them since they are the traditional "dynamic scripting" languages popular in backend development. But I agree the strong/weak designations are actually not so neatly segmented.


So, is your contention that both Go and Swift have equally-strong type systems? If so, you may want to consider saying that instead (though I am not sure how to phrase that in the format you have). If not, should they not be bolded with some elaboration on which is stronger or weaker and why? Or, were you not interested in a discussion of type-systems (if so, perhaps you should just remove the “strong” from that first line :P)?


Point well made, I've changed the post to reflect this :)


I just got out of a work presentation on new features in C++11 and C++14. The two presenters went into what's apparently the standard debate about noexcept. This makes me appreciate Go's pragmatic decision not to have exceptions! When you start getting into the nitty-gritty and epiphenomena around implementing APIs, multiple return values with error codes looks pretty darn good.

Error codes are explicit and devoid of implicit automagic. You're not going to break a lot of contracts and alter semantics by adding a keyword. The error codes are explicitly part of your function signature, in the most stupidly straightforward way possible. If you're going to be a bad developer and ignore error codes, this is going to appear explicitly in your code. (As opposed to being rewarded with "cleaner" code when you sweep exceptions under the rug.)


"multiple return values with error codes looks pretty darn good"

I'm a fan of making errors explicit, but I continue to find the use of effectively a product type (value and error) to return what is actually a sum type (value or error) to be ugly and error prone. Ideally, invalid states should be unrepresentable. In this case, both "value and error" and "no value and no error" are not. This is not good design.


Ideally, invalid states should be unrepresentable.

And clearly any language in which invalid states are representable is useless? Nice try, but nah. I like me some pure functions sometimes, but I'm not dogmatic about it.


Your response is so bad I almost think you're trolling... Hoping (I think) not:

"And clearly any language in which invalid states are representable is useless?"

I did not call anything useless, much less the entire language.

And I am the first to agree that trade-offs need to be made between a variety of considerations. But in this case, for the approach under discussion, I pointed out a design criteria that I find often important, that this approach is in flagrant violation of, while getting basically (perhaps literally) nothing in return toward any other design considerations.

Either I missed things or that's just a bad decision. If you think it's the former, please engage me more constructively so that at least one of us can learn something.

"Nice try, but nah."

This is needlessly rude.

"I like me some pure functions sometimes"

This issue has zero to do with pure functions.

"but I'm not dogmatic about it."

Right, pointing out bad design can only come from a place of dogma. Never experience, never consideration, and never anything that could permit substantive discussion.


> Go's pragmatic decision not to have exceptions

Um, what problems do exceptions introduce that panics don't?


None, but here's the thing about pragmatic design: You just have to make something that's less problematic the common case.


Exceptions are meant to be used for exceptional situations too. (Heck, the intended use is in the name!) Using them for normal control flow is bad programming style. (I'm looking at you, Python!)

In any case, the argument in favor of using return values for handling error conditions would be stronger if Go had proper tagged unions. With tagged unions, you can guarantee that exactly one of an OK result of an error object will be returned. Right now, Go has the very confusing situation that a function might return two `nil`s (the operation neither succeeded nor failed) or two non-`nil`s (the operation both succeeded and failed), neither of which makes any sense.


Would Kotlin be a better comparison to Swift, given they've both got huge potential for writing mobile apps?


Kotlin doesn't have a big backer though. I could see Google adopting Kotlin for Android officially in which case it could really take off.


I'd argue optionals are just a variation of Go's interfaces (e.g. io.Reader versus io.ReadCloser)... and enums are basically typed constants in Go (you just don't see the name "enum" anywhere).


Optionals can't be expressed safely in Go. They have a type of `Option<T>` or `Maybe<T>`. Swift just has this notion built as an operator.

Traditional enums aren't particularly interesting. What languages like Rust and Swift have are tagged unions. They let you associate data with each variant.

Moreover, pattern matching is needed to use tagged unions effectively.

Constants are not "basically" tagged unions or even enums. They are not grouped into a parent type. For example, if you have a `Foo` enum with `A` and `B` variants; while matching or accepting this, you can accept a `Foo` which is guaranteed to be either `A` or `B`.

How would Go typed constants achieve this?


Optionals are a way of returning either result or an error, and are not similar to interfaces. Go works around this by providing multiple return values, but because it lacks generics, it is very common to manually check for errors.

I'm not sure about Swift, but in some languages you can statically check case statements to make sure that every enum has a case, which is not possible with Go.


It's impossible to implement optionals without parameterized types, which Go does not have except for some built-in types. And optionals without language support for generic functions are about as useful as an exploding hammer.


Enum in Swift are very powerful. They can have associated values, pattern matching, implement interfaces (conform to protocol), have functions etc. Actually it is my favorite Swift feature.


>I hope they take a look at Swift as it matures in the next few years.

Maybe when binary packages are available for non Ubuntu Linuxes?


I think that is a valid concern. It is something that is being worked on [1] by the community. When those things get reasonably stable I think then it will be time to get those packages accepted by their respective distros.

Though as pointed out in SR-116 without ABI stability (which will not appear until Swift 3) packages do not necessarily provide a silver bullet of portability.

I for one have been maintaining a PKGBUILD script for Arch Linux that allows for a native package to be created. It's currently not working due to some issues with binutils [2].

[1] https://bugs.swift.org/browse/SR-116 [2] https://bugs.swift.org/browse/SR-1023


I'm sure this is in progress, but yes it's a definite roadblock. Maybe I should help on getting it onto RHEL/CentOS since that's what I usually use for servers and I really like Swift.


It's important to not only take compilation speed but also code quality into account. Swift and Go made very different tradeoffs here with SIL+LLVM compared to Plan 9.


I think Go hoped GCC would be their high-performance compiler, but it never got the attention it needed.

GCC has better micro-optimization in gccgo, but the compiler lacks important features like escape analysis and an up-to-date runtime so it's slower on real-world code.


Yeah, it goes to show that you really want a mid-level language-specific IR (which is what the Plan 9-based compilers have) if your language is at all high level.

I think the ideal for best performance of generated code is 3 IRs: a mid-level language-specific IR for high-level optimizations (especially around memory management and devirtualization), a low-level IR for lower-level optimizations (e.g. algebraic simplifications), and a codegen IR (for instruction selection and scheduling). This is what Swift is doing, as far as I can tell.


Only looked at Swift a little so far, but liked something about the syntax.

Seems clean.

Going to check it out more over time. Hope the Linux support improves.


What do you mean by "scripting mode"?


Off topic rant about Svbtle: While browsing the article, I hovered my mouse over something, which told me to hold still, and then suddenly it gave the article an irreversible upvote, which I certainly never intended to give. Now that poor author thinks another person liked the article. Who knows, maybe all previous 12 upvotes were the same situation?

Can we go back to Web 1.0 please? Everything was simple, everything worked, everything was fast. Or at least can we compromise and have a few reasonable design choices from Web 2.0 and Web 3.0 merged back in with Web 1.0, and just go with that? The current Web is just too broken, but there's nowhere to file a bug report.


>Can we go back to Web 1.0 please? Everything was simple, everything worked, everything was fast.

No. Software is allowed to evolve, even if you don't like it.

>Or at least can we compromise and have a few reasonable design choices from Web 2.0 and Web 3.0 merged back in with Web 1.0, and just go with that?

No. People are allowed to make their own decisions about how to design and build their sites, and they have the freedom to make decisions you disagree with.

>The current Web is just too broken, but there's nowhere to file a bug report.

It's broken for you, but it's extremely entitled of you to declare it broken for everyone. Far, far more people would consider "revert to Web 1.0" to be a broken experience, and the web belongs as much to them as it does to you.


> >Can we go back to Web 1.0 please? Everything was simple, everything worked, everything was fast.

> No. Software is allowed to evolve, even if you don't like it.

Translation: Programmer Hubris is a constant.


Perhaps. But if it means the internet brings me a far richer set of experiences and possibilities than simple text and images can allow then I'm not going to complain about it.


Web 1.0 had lots of badly designed UX as well. Just because something's bad doesn't mean it's because of "Web 3.0". People are always going to make bad UX regardless of the paradigm they're working in.


I just want simple text, plain backgrounds and links. I'm tired of web designers and there clever snowflake styling and javascript.


Well the reality is that's never going to happen. The web isn't going to go backwards any more than cars are going to go backwards (however much I'd like that). So the best you can do is strip away the stuff you don't like:

http://lynx.browser.org


Actually, we should encourage programmer hubris. We need something to be the moral equivalent of "shovelware" so the next batch of startups can be a "breath of fresh air" by getting rid of it.


DCurtis undoubtedly thinks this is extremely clever. There was criticism over this the instance Svbtle was announced, but it's persisted. https://news.ycombinator.com/item?id=3742654

I believe if you hover over it again it reverses the behavior, but I'm not certain. Regardless, it's not a good interaction paradigm.

Edit: It's not reversible. I thought I'd managed to undo one before, but I guess not.


Also, when I clear localStorage, I can vote again.


The page clearly shows the circle is for kudos. Not sure how you got confused.


Maybe triggering an action just by hovering was a bad idea (what about who's on mobile by the way?), but don't you think that you're overreacting a bit?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: