Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice

Subjunctive posted:

Every single person involved in Swift knew that opening language direction to public discussion was going to be like chewing glass. For none of them is this the first rodeo, and all these rodeos suck. They're a huge distraction and emotionally draining.

And yet, because it leads to a marginally better language and much stronger ecosystem, they braced themselves and took a nice big bite. Even if I thought they were wrong about everything, I'd still have a ton of respect for their willingness to engage and their admirable demeanor while doing so. They are doing all the right things to build a language and community that deserves to underpin the most important software ecosystem since the web, and they don't have to. They had to fight and sacrifice and make enemies at Apple in order to be allowed to open the door and get a tomato in the face.

Whether I agree with their decisions or not (lol, "trimming"), it's exactly the sort of team I'd want designing a language I bet my livelihood on. If they find themselves in MPK, the drinks are on me.

Agreed; Even though I don't think the renaming proposal is all that important I trust the Swift team and I know they've had lots of internal arguments about it so I'm just going to wait and see how it works in practice.

I'm also mostly staying away from swift-evolution (besides the fact that I have a real job and my own side project app [that will surely be rejected in review]).

Adbot
ADBOT LOVES YOU

lord funk
Feb 16, 2004

I'm in a class:

code:
var renderer: Renderer! = nil
And in its Metal drawInMTKView: method, any time I try and print something I get

code:
(lldb) po commandBuffer
error: <EXPR>:9:9: warning: initialization of variable '$__lldb_error_result' was never used; consider replacing with assignment to '_' or removing it
    var $__lldb_error_result = __lldb_tmp_error
    ~~~~^~~~~~~~~~~~~~~~~~~~
    _
<EXPR>:15:5: error: value of optional type 'Optional<Renderer>' not unwrapped; did you mean to use '!' or '?'?
    $__lldb_injected_self.$__lldb_wrapped_expr_10(     
    ^
                         !
Any way around this?

Doh004
Apr 22, 2007

Mmmmm Donuts...
Is this intended:

code:
var numbers = [1, 2, 3, 4, 5]
numbers.sortInPlace({ $0 > $01 })
Primarily, the $01 being valid?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Doh004 posted:

Is this intended:

code:
var numbers = [1, 2, 3, 4, 5]
numbers.sortInPlace({ $0 > $01 })
Primarily, the $01 being valid?

I doubt we ever explicitly considered it, but it seems reasonable enough. What else could we reasonably do, warn "hey, you probably fat-fingered something here, and we're pretty sure it's what you actually wanted, but maybe you fat-fingered something else nearby since you're such a lovely typist"?

It's not like we're interpreting it as octal or something.

Flobbster
Feb 17, 2005

"Cadet Kirk, after the way you cheated on the Kobayashi Maru test I oughta punch you in tha face!"
Is there an upper limit to the number of arguments in a closure, or does this mean I can write $8008135 if I'm patient enough?

Doh004
Apr 22, 2007

Mmmmm Donuts...

rjmccall posted:

I doubt we ever explicitly considered it, but it seems reasonable enough. What else could we reasonably do, warn "hey, you probably fat-fingered something here, and we're pretty sure it's what you actually wanted, but maybe you fat-fingered something else nearby since you're such a lovely typist"?

It's not like we're interpreting it as octal or something.

I'd be okay with this warning.

I only saw this while code reviewing a PR. I yelled at the engineer because CLEARLY they hadn't actually attempted to compile their code. Much to my surprise they had and it worked just fine :iiam:

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Flobbster posted:

Is there an upper limit to the number of arguments in a closure, or does this mean I can write $8008135 if I'm patient enough?

There's certainly some implementation limit, and it's probably lower than we strictly validate, but there's no particular reason for us to impose a language limit.

chaosbreather
Dec 9, 2001

Wry and wise,
but also very sexual.

Doh004 posted:

I'd be okay with this warning.

I only saw this while code reviewing a PR. I yelled at the engineer because CLEARLY they hadn't actually attempted to compile their code. Much to my surprise they had and it worked just fine :iiam:

you don't seem to 'get' swift

you can't yell at people and swift things, you've gotta be mellow, put on some smooooth tunes, glass of nice whiskey by the fireplace

Flobbster
Feb 17, 2005

"Cadet Kirk, after the way you cheated on the Kobayashi Maru test I oughta punch you in tha face!"

rjmccall posted:

There's certainly some implementation limit, and it's probably lower than we strictly validate, but there's no particular reason for us to impose a language limit.

Well, I gave let x = { $8008135 } five minutes to compile before I gave up and killed it. I imagine eventually it would either hit the "unable to infer closure return type" error that I would expect, or die for some other resource exhaustion reason.

I'm tempted to file a bug, but this is really stupid :v:

Edit: Because I'm procrastinating, I did a little digging. It looks like referencing $n in a closure is quadratic on n (albeit with a low constant). Extrapolating the results of $0 through $3500 or so...



$8008135 would take about 275 days to compile.

Flobbster fucked around with this message at 04:04 on Feb 18, 2016

sarehu
Apr 20, 2007

(call/cc call/cc)
They should cap it at $65534 so they can fit the numbers in a uint16_t and make better use of cache lines.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Flobbster posted:

Well, I gave let x = { $8008135 } five minutes to compile before I gave up and killed it. I imagine eventually it would either hit the "unable to infer closure return type" error that I would expect, or die for some other resource exhaustion reason.

I'm tempted to file a bug, but this is really stupid :v:

Edit: Because I'm procrastinating, I did a little digging. It looks like referencing $n in a closure is quadratic on n (albeit with a low constant). Extrapolating the results of $0 through $3500 or so...



$8008135 would take about 275 days to compile.

Out of curiosity, is it still non-linear if you only parse / type-check? There are command-line options you can use for this.

Flobbster
Feb 17, 2005

"Cadet Kirk, after the way you cheated on the Kobayashi Maru test I oughta punch you in tha face!"

rjmccall posted:

Out of curiosity, is it still non-linear if you only parse / type-check? There are command-line options you can use for this.

swiftc -parse -dump-type-refinement-contexts for $3500 still takes about 3.5 seconds to complete before erroring out, so it looks like yes.

I should mention that I'm using Swift 2.1 for this—I don't have 2.2 installed on this machine, but I know there were a ton of codegen/performance improvements in that release. Not sure if this is something that would be affected, though.

playground tough
Oct 29, 2007
So I've had this idea kickin around for an app I'd like to develop while I'm still in school for a while now. I want to prove that I can work with a decently sized project and want to learn more development skills in general. I started messing around with React Native and I'm starting to feel like it is loving dumb since I can't seem to get it to do anything I want it to do without some fuckery or hacks.

If I work with swift, am I going to have an easier time building my app coming from a java & c background than with this react bullshit? Thanks.

Glimm
Jul 27, 2005

Time is only gonna pass you by

playground tough posted:

If I work with swift, am I going to have an easier time building my app coming from a java & c background than with this react bullshit? Thanks.

In my opinion, yes. React Native is cool but has kind of a steep learning curve if you're not already familiar with JavaScript / web tools / React itself.

Doh004
Apr 22, 2007

Mmmmm Donuts...

playground tough posted:

So I've had this idea kickin around for an app I'd like to develop while I'm still in school for a while now. I want to prove that I can work with a decently sized project and want to learn more development skills in general. I started messing around with React Native and I'm starting to feel like it is loving dumb since I can't seem to get it to do anything I want it to do without some fuckery or hacks.

If I work with swift, am I going to have an easier time building my app coming from a java & c background than with this react bullshit? Thanks.

Yes 100%. Please learn the actual system first instead of jumping into whatever Facebook's framework of the year may be at the time.

lord funk
Feb 16, 2004

Help, please. What am I doing wrong.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.
That's when I add print() everywhere and recompile.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
I recently discovered that LLDB is not idempotent; I get some mystifying error about declarations having conflicting types, but I can just try again and get a different message, and then eventually it just works.

You might be hosed, though.

ultramiraculous
Nov 12, 2003

"No..."
Grimey Drawer

rjmccall posted:

I recently discovered that LLDB...not idempotent

:lol: you don't say?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
Well, I was expecting that the expression parser would be starting from a clean-ish state each time, but I guess I know for a fact that it doesn't, so welp.

toiletbrush
May 17, 2010
Is there any way in Swift to generate a copy of a struct but with one or more values changed? So given a struct like...

code:
struct Thing {
    let blah: String
    let bleh: String
    let oof: Int
}
...and an instance of that struct called myThing you could do...

code:
let myOtherThing = myThing.with { oof = 69 }
I'm trying to write code without any var's, and having to write initializers to support this is the most awkward bit.

Kallikrates
Jul 7, 2002
Pro Lurker
I saw an interesting talk about lenses that provided a way to do that. Interesting as a thought experiment I didn't think it was practical. If you are okay with the boilerplate to accomplish this. I think that might be worth a look. If you are looking for a language feature to do basically:
code:
let oldFoo = Foo(a: 1 b: 2)
let newFoo = Foo(a: oldFoo.a b: oldFoo.b + 1)
I don't think one exists. The video:
https://www.youtube.com/watch?v=ofjehH9f-CU

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
There isn't a language feature for it right now. You can add a method per property, like so:

Swift code:
  extension Foo {
    func with(b b: Int) -> Foo {
      var result = self
      result.b = b
      return result
    }
  }
You can do it much more awkwardly without the local var if you're being super-strict about that for some reason.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
You can also do something like

Swift code:
  extension Foo {
    func changing(fn : (inout copy: Foo) -> ()) -> Foo {
      var copy = self
      fn(&copy)
      return copy
    }
  }
which could be called like

Swift code:
foo.changing {$0.b = 1}

toiletbrush
May 17, 2010
Ah cool...alas I'm being super strict + anal about no var's whatsoever! Purely for a learning exercise.

Do you think it might be a feature for the future?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

toiletbrush posted:

Ah cool...alas I'm being super strict + anal about no var's whatsoever! Purely for a learning exercise.

Do you think it might be a feature for the future?

Sure, it's something we're aware of as being kindof awkward.

Flobbster
Feb 17, 2005

"Cadet Kirk, after the way you cheated on the Kobayashi Maru test I oughta punch you in tha face!"
Does this mean you're also looking at ways make it easier to write fluent interfaces/builders with structs? Right now having the initializer result be immutable is a showstopper because I can't write "let foo = Foo().something(5).somethingElse(10)" even if those methods are mutating.

I've been working on a side project where I've had an opportunity to really use protocol-oriented programming, extensions, constraints, and generics in some cool ways and I've gotta say, I love just how algebraically Swift lets me design components. Being able to say "this type implements this set of methods, but also this superset of additional methods if the associated type is X" is mind blowing. And I've only written one class, and it was purely an implementation detail to get copy-on-write for a value type.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
Thanks!

I think we appreciate the importance of builder patterns and want to serve those better. I can't imagine us ever allowing you to call mutating methods on an r-value, though.

Axiem
Oct 19, 2005

I want to leave my mind blank, but I'm terrified of what will happen if I do

toiletbrush posted:

Is there any way in Swift to generate a copy of a struct but with one or more values changed?

I'm trying to write code without any var's, and having to write initializers to support this is the most awkward bit.

I handle this pretty similarly to the way rjmmccall mentioned:

code:
struct Star {
    let id: StarId
    let name: StarName
    let distance: Distance
    let rightAscension: RightAscension
    let declination: Declination
    let spectralClass: SpectralClass
    let magnitude: StarMagnitude

    init(id: StarId, name: String, distance: Distance, rightAscension: Angle, declination: Angle, spectralClass: SpectralClass, magnitude: Double) {
        self.id = id
        self.name = name
        self.distance = distance
        self.rightAscension = rightAscension
        self.declination = declination
        self.spectralClass = spectralClass
        self.magnitude = magnitude
    }

    init() {
        self.init(id: "star", name: "Star", distance: Distance(0), rightAscension: RightAscension(radians: 0), declination: Declination(radians: 0), spectralClass: SpectralClass(), magnitude: 1)
    }
    
    func withId(id: StarId) -> Star {
        return Star(id: id, name: name, distance: distance, rightAscension: rightAscension, declination: declination, spectralClass: spectralClass, magnitude: magnitude)
    }
    
    func withName(name: StarName) -> Star {
        return Star(id: id, name: name, distance: distance, rightAscension: rightAscension, declination: declination, spectralClass: spectralClass, magnitude: magnitude)
    }
    
    func withDistance(distance: Distance) -> Star {
        return Star(id: id, name: name, distance: distance, rightAscension: rightAscension, declination: declination, spectralClass: spectralClass, magnitude: magnitude)
    }
    
    func withRightAscension(rightAscension: RightAscension) -> Star {
        return Star(id: id, name: name, distance: distance, rightAscension: rightAscension, declination: declination, spectralClass: spectralClass, magnitude: magnitude)
    }
etc.

My primary annoyance is with the sheer amount of boilerplate, but it's mostly copy-pasting and swapping out which variable is being changed, otherwise, it works quite well, I think.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
If gyb was built into the compiler/build system we totally wouldn't need any new language features ever again.

ultramiraculous
Nov 12, 2003

"No..."
Grimey Drawer

Plorkyeran posted:

If gyb was built into the compiler/build system we totally wouldn't need any new language features ever again.

I mean I've almost asked for Scala-style macros in this thread more than once, but then I remember what a mess those could turn into. Same way Clang plugins to transform code are fun until they aren't.

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice

Flobbster posted:

Does this mean you're also looking at ways make it easier to write fluent interfaces/builders with structs? Right now having the initializer result be immutable is a showstopper because I can't write "let foo = Foo().something(5).somethingElse(10)" even if those methods are mutating.

I've been working on a side project where I've had an opportunity to really use protocol-oriented programming, extensions, constraints, and generics in some cool ways and I've gotta say, I love just how algebraically Swift lets me design components. Being able to say "this type implements this set of methods, but also this superset of additional methods if the associated type is X" is mind blowing. And I've only written one class, and it was purely an implementation detail to get copy-on-write for a value type.

We've found this to be the case as well. My rough guess right now is we're going to end up deleting about 20,000 - 30,000 lines of code when the core sync/database logic is fully converted to Swift, if not more.

jawbroken
Aug 13, 2007

messmate king
Is there some reason, other than for fun, you would define your structs like that? I hope they don't add language features that make people think declaring structs full of let bindings is a sane idea.

Dessert Rose
May 17, 2004

awoken in control of a lucid deep dream...
Why do you think immutable structs are a bad idea?

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.
A struct with var properties is still immutable.

Dessert Rose
May 17, 2004

awoken in control of a lucid deep dream...

pokeyman posted:

A struct with var properties is still immutable.

In a way, but in another way it looks mutable in usage.

Even if the struct has var properties, it would still benefit from this syntax, because right now it takes me at least two lines to make a copy of a template struct with some changes.

jawbroken
Aug 13, 2007

messmate king
If I saw a bunch of structs full of let bindings I would presume that the person who wrote the code didn't understand value types. If you're using structs in a reasonable way, and two lines is an issue, then you could define your own way of handling that. e.g.
code:
func with<T>(item: T, @noescape _ closure: inout T -> ()) -> T {
  var i = item
  closure(&i)
  return i
}

let p  = Point()
let p2 = with(b) { $0.x += 2; $0.y -= 2 }
but sure, there could be some language feature to help here. There has been some discussion on the mailings lists about being able to change the context a closure executes in (e.g. rebinding self) to make some DSL things easier. That would allow you to drop the $0 in the closure. I feel ambivalent about it though.

brap
Aug 23, 2004

Grimey Drawer
Is it because declaring a variable of a strict type using "let" will prevent mutation of the "var" members of the struct anyway, thus making "let" properties on a struct pointlessly strict?

dizzywhip
Dec 23, 2005

Yes. If you use lets, you're taking away the user's choice of mutability for any particular value.

Adbot
ADBOT LOVES YOU

Axiem
Oct 19, 2005

I want to leave my mind blank, but I'm terrified of what will happen if I do

jawbroken posted:

If you're using structs in a reasonable way, and two lines is an issue, then you could define your own way of handling that. e.g.
code:
func with<T>(item: T, @noescape _ closure: inout T -> ()) -> T {
  var i = item
  closure(&i)
  return i
}

let p  = Point()
let p2 = with(b) { $0.x += 2; $0.y -= 2 }

The thing is, this breaks encapsulation; now whoever wants to create a struct with one variable different has to know how that variable is stored internal to the struct. I find that problematic.

Back to my star example:

code:
struct Star {
	// ...
    var location: Point { return Point(x: distance.ly * cos(rightAscension), y: distance.ly * sin(rightAscension)) }
    func withLocation(location: Point) -> Star {
        let radius = sqrt(Double(location.x * location.x) + Double(location.y * location.y))
        let theta: Angle = atan2(Double(location.y), x: Double(location.x))
        return Star(id: id, name: name, distance: Distance(radius), rightAscension: theta, declination: declination, spectralClass: spectralClass, magnitude: magnitude)
    }
}
Currently, I'm storing things about a star's location based on its polar coordinates (radius and angle), but I expose both polar and cartesian coordinates because each are useful in different ways, and I have the withX functions in order to let whoever's building one piecemeal to decide how to do it. But whoever calls information about the Star doesn't know how I'm internally storing that information. So if I change my mind later, the interface doesn't change, and no one calling changes.

If I went with the closure idea, then I'd have to expose how I'm storing that to whoever calls, and that seems to break encapsulation. It also means I'd probably have to do something fancy to allow setters on all three, or if I change my mind about internal storage later, I'd have to update all the callers.

As for why, for the Star, pretty much all of those are there for ease of testing; create an object with sane defaults and change the things I want in the test clearly. However, as you get higher up in my struct tree, I keep the same notation of withChangeToX to effectively cascade a couple of changes in the struct tree, and I like the consistency of naming.

Doing it with the withX functions also gives me the ability to pause anywhere in the chain and capture the struct, do some more work and capture that, and possibly run comparisons on the two, especially around computed values. The Star example is admittedly a little weak in that arena, because they're effectively static in my game.

  • Locked thread