Hacker Newsnew | past | comments | ask | show | jobs | submit | lyinsteve's commentslogin

The Swift optimizer has matured dramatically since 2017, to the point where I think this benchmark would almost certainly not result in a 3x power usage/4x slowdown compared to C.

On the current benchmark game, many of the purely algorithmic benchmarks are close to C performance, but many of these benchmarks seem to be stale and haven't been touched in quite a while. It would be nice if someone went through and rewrote these using current idiomatic Swift (where many of the "use unsafe bits for speed" tricks are unnecessary) and see how it really stacks up.


> It would be nice if someone went through and rewrote these using current idiomatic Swift

It's always nice when someone else does what we can see is required, but mostly we have to be the ones to do that work.


That's good to know.

I might have one of two projects in the next few months that will require jumping into Swift. Not touching Objective-C if I can help it.


I don’t know much about rust specifically, but the overflow traps happen in debug (i.e. -O0) builds, and are not emitted when optimizations are enabled.

LLVM’s constant folding and canonicalization passes will convert (x * 2) / 2 from

%0 = mul i64 %x, i64 2

%1 = div i64 %0, i64 2

to

%0 = shl i64 %x, i64 1

%1 = shr i64 %0, i64 1

Which constant folding will reduce to just %x.


How do the two shifts reduce to x? The top bit is zeroed as a result of those shifts.


Well ok but (x*3)/3 will be a lot worse :)


Not by a lot, the divide by constant can be optimized to a multiplication, if you're doing it in a loop (why would you care if you do it only once), you can reach a throughput of one multiplication per cycle, so (x*3)/3 would take 2 cycles on average.


This is a silly line of argument; optimizing (x*3)/3 to x unlocks further CSE, inlining, etc. so the benefit may be arbitrarily large.

Rust made the right tradeoff here but it is a tradeoff!


There are tons of amazingly-smart people working on Swift at Apple right now


-swift-version 3 really just turns on some different paths through the parser and type checker to allow previously-valid Swift 3 code to survive to code generation time.

They're both compatible


I have the strange feeling this will really only be used to enforce the copyrights of large music and movie industry corporations and will not be effective at protecting the IP of independent creators.


This should be much higher. Thanks!


The author completely missed the point of named parameters. How am I supposed to know that the string argument of "make_window" is the title?


> The author completely missed the point of named parameters.

The author didn't miss the point of named parameters. At no point does the author even cover the point of named parameters. The author complains that:

1. they're inconsistent, all parameters but the first are named by default and named parameters are still positional (you can't reorder "named" parameters in the callsite)

2. making parameters purely positional is non-obvious and ugly

And he missed the part which takes the cake: Swift doesn't actually have named parameter, parameters 1+ are labelled (#1), and labels and names are independent, you can define this:

    func foo(a b: Int, c d: Int) { … }
which is called with a:c:, but the bindings are on b and d. You can also define this:

    func foo(a b: Int, _ d: Int) { … }
which is called as `foo(a:5, 7)` which while somewhat consistent is really garbage.


In Swift terminology, a and c are "external names" while b and d are "local names." I don't see much of a difference between a "name" and a "label" here in any case.

I don't understand why the ability to set different external and local names is so bad. External names are part of the API, local names are part of the implementation. It often makes sense to make them the same, but there are case where you want them to be different, and what's wrong with that? It's ultimately no different from loading a parameter into a local variable of a different name and then operating on that local variable. Yes, you can use this facility to make ugly APIs, but you don't have to.


> I don't understand why the ability to set different external and local names is so bad. External names are part of the API, local names are part of the implementation. It often makes sense to make them the same, but there are case where you want them to be different, and what's wrong with that? It's ultimately no different from loading a parameter into a local variable of a different name and then operating on that local variable.

Then why have it in the first place? That seems like a very odd feature to put front and center into the language (considering a very similar effect can be achieved with a few assignments as the function's prelude) and require using when just wanting positional-only parameters, or consistently labelled parameters.


Can you explain what "and require using when just wanting positional-only parameters, or consistently labelled parameters" means? I don't understand that.

As for why you have it in the first place, it's just because one is API and one is implementation, and there are sometimes good reasons to have them be different.


> Can you explain what "and require using when just wanting positional-only parameters, or consistently labelled parameters" means? I don't understand that.

As far as I can see (and the article notes), by default the first parameter of a Swift function is unlabelled, and the others are labelled. That is at callsite the first parameter can not be labelled and the others must be. Having either all-positional or all-labelled (but still positional) requires specifying external names.

> As for why you have it in the first place, it's just because one is API and one is implementation

But again and as you yourself noted that could trivially be done with local bindings inside the function in cases where it's desirable.


Yes, that's true, but note that you only need to specify the external names on the parameters that depart from the default. A function with external names on every parameter looks like:

    func whatever(a a: Int, b: Int, c: Int)
A function with no external names on any parameter looks like:

    func whatever(a: Int, _ b: Int, _ c: Int)
I'm not sure if you understood that or thought they all had to be specified if any were, but in any case that's how it looks.

As for "that could trivially be done," that applies to a lot of language features in a lot of languages. Virtually all language features are redundant in that fashion, yet they can still be useful by adding brevity and clarity.


The question is why is the first argument special? Also, it's weird that you have to explicitly mark the label as "_" to get positional parameters.

I find Scala's handling of named arguments much saner.


I think it's because the first argument tends to be named by the function itself. For example:

    button.setTitle("Ham and Cheese", color: red)
Note that named parameters are still positional, they just have names too. Using _ doesn't get you positional parameters, you already had that, it just removes the name. (Exception: named parameters with default values can be reordered with other adjacent named parameters with default values. Why? I don't know.)

It is mildly annoying that you have to add an extra symbol to remove the name for parameters after the first one, but that's the language pushing its preferred style.

How does Scala handle all this?


> Exception: named parameters with default values can be reordered with other adjacent named parameters with default values. Why? I don't know.

That's actually nice to know.

> How does Scala handle all this?

No idea about Scala. In Python 3, there are 4 "classes" of parameters:

* "positional-and-named", the basic parameter can be passed either by name or by position, though passing parameter 1 by name parameter 2 by position won't work: when actually calling the function, the interpreter first fills positional parameters left-to-right then applies named parameters, so it'll raise an error noting that one parameter got two values[0]. Can be either required or with a default value. Parameters passed by names can be passed in any order

    def foo(a, b, c=5): pass
    foo(1, c=42, b=3)
* positional varargs ("args"), can only be passed positionally, can follow any number of positional parameters, will be collected as an array

    def foo(*args): pass
    foo(1, 2, 3, 4)
* named-only ("keyword parameters"), follows either positional varargs or a special placeholder. These were not possible in Python 2 in pure Python, they're similar to 1 but can only be passed by name, they can be either required or with a default value. Like 1 but more so, named-only parameters can be passed in any relative order

    def foo(*, a, b, c=5): pass
    foo(b=6, a=2)
* keyword varargs ("kwargs"), may follow named-only parameters and will collect any parameter passed by name which didn't match any formal parameter, will be collected as a key:value map

    def foo(**kwargs): pass
    foo(bar=5, baz=42, qux=1)
The C API also allows creating true positional parameters (completely unnamed), as far as I know that's not possible in pure Python.

[0] the reverse won't work either, at callsite Python doesn't allow named parameters to be provided before positional ones


For Swift, a lot of the designs were due to the ability to automatically transform Objective-C apis into swift APIs. The big issue from what i can tell is in extracting the first parameters name from the method name automatically.


That doesn't really explain the defaults, though. Translation could override the defaults if that fit better. This already happens when translating C functions, as none of the parameters get external names.


  > Then why have it in the first place? That seems like a very
  > odd feature to put front and center into the language
Cocoa is the answer.


Why did I just implement this in Swift? https://github.com/harlanhaskins/Base65536.swift


Apple uses XMPP internally as a way to securely communicate.

Doesn't really change much; just thought that'd be an interesting thing to throw out.


What exactly do you mean by that? I'm really curious.


I'm a Computer Science House member -- Drink is still a staple of our organization! Where else can you get Jolt on campus?

Also we've since made an awesome web app and iOS app for dropping drinks.


I clicked this post to say that. I am a CSH alum and the Drink machine steve describes here has been around for hundreds of years, easily.


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

Search: