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
Uhh was that a time-reversing debugger in your pocket or are you just happy to see me?

Seriously, is it recording state or using an Elm-style time-traveling debugger?


Mutability vs immutability: yes. Generics: yes.


I'm gonna dig in more but so far I like what I see.

Adbot
ADBOT LOVES YOU

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

Damiya posted:

I'm not an iOS dev, so maybe this is a dumb question, but since there's no GC does that mean all memory management has to be done by the programmer?

No, it uses ARC so it more or less statically analyzes the code to produce the correct set of retain/release calls.

Are closures blocks? If they are first-class in Swift, then can I interrogate a block to determine its type arguments at runtime?

Speaking of type metadata, it appears that variadic functions can introspect the number and types of arguments. That leads me to believe the Swift type system is fully modern and you have full type fidelity at runtime for anything, including generics and the constraints.

Is there any reason you went with a syntax-block-ish syntax for closures instead of the fat arrow? I believe ES6 adopted the C# fat arrow as well, given the influence of those two languages I was a bit surprised to see Swift takes a different route. The positional $ params are a cute trick though.

Can I export functions to C or objects to Objective-C from Swift? And how would that manifest given the simpler type systems?

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

JewKiller 3000 posted:

It may be better than Objective-C, but from a broader perspective (comparing to all languages), I don't see the big deal here. None of the features you've mentioned in this thread were introduced in the PL literature later than the 1980s. What's so good about this new language aside from making fewer mistakes?

Heartbleed? Goto fail? is that not enough of a reason to finally admit C has got to loving go? Or do we need another "Internet-wide SSL-compromising, make every. loving. Human. On. The. Planet. change their passwords" sort of vulnerability before we admit relying on human beings to write perfect code to prevent memory corruption is completely stupid and hopeless?



Type inference, full type fidelity, and the tooling around all that should make it easier to make Xcode more helpful* and easier to debug. (*whether that happens is another matter).

Generics are excellent. The caller knows it's an array of strings, the callee creates an array of strings, but put a bird on it? Why not, Objective-C doesn't give a poo poo!

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

hobbesmaster posted:

You can write terrible, internet breaking code in any programming language. The OpenSSL team had such terrible standards that I'm sure they'd screwed up in any other language.

That's a dumb excuse and I'm sick of hearing it.

Yes, I could write bad code in any language. But a memory safe language vastly reduces the scope of existing errors and greatly limits the damage one can do. You can't write a "return 64k of random server memory every time someone asks" bug in a memory-safe language without trying extremely hard.

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice
Why can't Any contain a function? Is there some reason not to treat functions as first class objects?

Also I didn't see anything about custom attributes but I haven't read the whole doc yet...

Just in case you were missing @ it makes an appearance, check the section on custom operators and how you define attributes. It's a drat sight prettier than __((attribute))

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice
Tried to make some notes instead of posting piecemeal.

1. Mutability of let array is really ugly, unintuitive, and horrible. Introduce proper syntax for it.
2. The copying behavior is even worse
3. Dictionary’s passing also sucks
4. Seriously guys, just do real copy on write arrays/dictionaries and support a fixed size array syntax directly; then we can get real immutable vs mutable collections.
5. Closure capturing self, still ugly as sin – can’t we solve this problem? Some way to say if a closure is stored on an object and references self, then on every release of the closure or parent we check both to see if the only remaining live references are each other. ARC’s biggest flaw.
6. Exceptions or conditions?
a. If not, then how do we deal with Objective-C exceptions? (Looks like just inout of NSError)
7. Why don’t extensions just use the underlying associated object functionality to let you transparently add stored values?
8. Since we can’t do performSelector, what’s the alternative for stuff like performSelector:afterDelay:?


Overall impression: excellent work, I'm very impressed!


Edit:

checked exceptions - please no...

I've looked at LISP's conditions and there are some interesting bits there but I'm not sure that's the right way to go.

Simulated fucked around with this message at 02:40 on Jun 3, 2014

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

rjmccall posted:

We'll be looking more closely at arrays, I think. Please file a bug; I think you're misunderstanding what we're even trying to do with arrays, and that's probably yet another indicator that what we're trying to do is too clever by half.


Dictionary is copy-on-write. At least, it's supposed to be. What are you seeing?


The docs seem to be saying that passing a dictionary passes a copy, but arrays are by reference. It also seemed to say that an immutable instance of array is not really immutable, it's just got a fixed length, but immutable dictionaries are really immutable.


quote:

That doesn't actually scale to two closures on the same object. Ultimately, this is just asking for cycle detection.

My assumption was that if the total number of blocks retaining self matched the retain count then you're locked in a cycle and can dump them all. My other assumption is that this is the common case because you're right, going any further down chains of objects is GC-style cycle detection. It's just one of those ugly wart things that gives me a bad feeling when I see it. Not a deal-breaker.

I get a bad feeling about the syntax of closures in general though because the argument list looks like a statement inside a block (not NSBlock) body. Everything else is declare the types outside the braces. Did someone do that so they could get the clever ability to stick the code of the body after the method if the closure is the last parameter? Not worth it. I'm going to break my rule about not filing radars just for you and file on this stuff.


quote:

I probably shouldn't have said anything. "Checked exceptions" is misleading even for what we're thinking about, and frankly we haven't thought about it deeply enough that I have any business publicly speculating.

Not your fault, I think I just had a reflexive reaction because every drat java method I see just says "throws exception". I hope your team can iterate and come up with something more elegant than "goto fail", but that more clearly expresses intent than catch(Exception ex). That's what I found interesting about conditions - a method could provide handlers further up the stack with some options for skipping an item, continuing past the error, aborting, etc.

I think it turns out you almost never care about what the error is, you just need to know if its part of a loop so you an skip that item/try some alternate thing, it's something you want to await and retry, or if it's something that should unwind the stack and abort the operation with bounds that can gracefully transition the first two into the third if you can't make forward progress. Then separately you need filters or some such thing that can globally get the chance to log the error regardless of what lower layers are doing.

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

rjmccall posted:

My Unicode is not very strong. I understand that there are normalizations you can do which would unify some strings, and we should probably at least be doing those. The question is whether (case-sensitive) string equivalence is actually locale-insensitive, because that's what I would expect name lookup to use in a maximally Unicode-aware world.

It's not about doing culture aware sorts or comparisons (eg where some culture considers A and Å to be equal but another does not). It's about the fact that you can represent è as Latin lower case e with Grave (one code point) or Latin lower case e + grave combining mark (two separate code points).

I agree that Swift should pick one standard normalized form and stick with it. I also agree that you need a single cultural invariant comparison.


Also to whoever used a bunch of Emojii in the docs: :lol:

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice
I'm sure it is politically difficult, but we really need a better way to communicate besides filing radars. I know you guys are eager to get feedback but there's a layer of beauracracy in between us that measures their self worth by how many radars they can close in a single day, or possibly deriving which misinterpretation will be the most anger-inducing*. I'm not saying this for your benefit obviously, I'm sure you'd have already released it and started a public discussion forum/mailing list if it were up to you.

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

bumnuts posted:

Why is @lazy the only keyword with the @ prefix? Why not just lazy?

I don't know if they plan on supporting custom attributes but @ is the syntax for attributes in general.

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

Flobbster posted:

I've been racking by brain over some difficulty getting some complex mathematical expressions to compile involving CGRects and CGFloats, and I finally managed to distill it down to this problem:

code:
let x = Double(4) * Int(5)   // Could not find an overload for '*' that accepts the supplied arguments
...so I was surprised that see that mixed arithmetic doesn't seem to be supported if the types of the expressions (in my original case, they were variables) are explicit (as opposed to writing 4.0 * 5, which works). I couldn't find anything in the book or the docs about implicit type coercion/promotion, so is this a bug or a feature of a very strong type system?

The book calls out that Swift does not do any automatic conversion, you must explicitly do it. It's under "The Basics", "Integer and Floating-Point Conversion":

quote:

Conversions between integer and floating-point numeric types must be made explicit:

The rules for combining numeric constants and variables are different from the rules for numeric literals. The literal value 3 can be added directly to the literal value 0.14159, because number literals do not have an explicit type in and of themselves. Their type is inferred only at the point that they are evaluated by the compiler.

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

rdar://17215811 - Improve Swift Closure Syntax

rdar://17215836 - Swift: Provide runtime introspection/reflection capabilities with language syntax

rdar://17215845 - Swift should use consistent keywords

rdar://17215852 - Swift should provide explicit syntax for user-defined attributes

rdar://17215880 - Swift should provide a macro-like language extension system

rdar://17215884 - Swift: Any should be capable of containing a function/closure

rdar://17215895 - Swift should adopt a state of the art error handling mechanism
"If Swift is intended to some day write operating system code, drivers, etc then it would be nice to have a way to write robust code that doesn’t abort the kernel (or the current I/O thread) because someone forgot that an integer value can overflow if a driver receives a malformed packet."

rdar://17215909 - Swift: Array and Dictionary’s behavior is inscrutable

rdar://17215916 - Swift extensions should use associated objects to allow addition of stored properties to objects

rdar://17215920 - Swift: functions that define argument names should allow passing arguments in any order.

rdar://17215927 - Swift should provide an async/await-like abstraction over GCD



For those wanting to test this stuff in a VM: I thought I'd setup a 10.10 VM and install the Xcode beta in that. Don't do it. For whatever reason it is horribly ungodly slow; something is wrong with how VMWare Fusion is hosting 10.10. It is literally unusable - the pauses waiting for intellisense to popup are maddening. Use a 10.9 VM to test stuff out; it works much better.

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

quote:

doIt("yes")

func doIt(a:String) {

}

error: Use of unresolved identifier 'doIt'


So the compiler isn't smart enough to resolve symbols declared in the same file unless declared in-order?

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice
Here, have some exception handling in Swift:

code:
    
try {
        ({
            println("in try")
            //code that might throw an exception
        },
        catch:{ ex in
            println("caught \(ex.name): \(ex.description)")
        },
        finally: {
            println("finally")
        }
    )}
My blog post with the rest of the code. I'm working on getting this packed into a framework and uploaded to GitHub. My next project is LINQ-style operations on SequenceOf<T>. I already have some basics working but I think I can abuse Tuples-as-anonymous-types to support select projections, joining, and grouping.

edit: my rationale is that CoreData already uses exceptions so if you want to interoperate you need to be able to deal with them.

Simulated fucked around with this message at 05:19 on Jun 8, 2014

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

shodanjr_gr posted:

This is an exception-al (:haw:) writeup. Thank you.

If I'm reading this correctly, this will also handle nested try calls with rethrowing, correct?

Also, does Swift allow C-style typedefs? Those try function signatures look like brainfuck at first glance.

You can re-throw; I didn't show the code for throwing an existing NSException but it is trivial.

Your question did set me off on the path to see if I could make actual @throw; work so the existing exception could just be re-thrown, by wrapping @throw in a block created in the @catch, then using a Block** parameter to write its address back out to the Swift side; this would defer creating the block unless you actually cared about rethrowing. I almost got there but I no matter what I did the AutoreleasingUnsafePointer<Block?> out param was always nil on the Swift side. I switched to always creating the rethrow block instead of trying to do it lazily and it actually works. However it creates an ambiguity in the catch clause definitions, so you end up having to clutter the catch with "(ex, rethrow) -> () in" for little benefit.


Meat Street posted:

It was a design decision of the language to not have exceptions and I doubt they'll double back on that, nor would I use them if they were added, but this does raise (heh) an interesting question: does the Core Data talk this year have anything to say about usage patterns in Swift?

I am not advocating for exceptions, just dealing with the fact that they exist and will be thrown if you're using CoreData.

I still think we need something more robust than "func() -> (x:T, error:NSError)" or "func (x:T, inout error:NSError)", but I am starting to think I'm in the minority. In my far future dream world, failure to account for integer overflow doesn't cause a kernel panic because the serial driver for my home automation transmitter got a bad packet. Yes, that would be a bug. Yes, it should be handled or fixed. But in the meantime, I'd like my software to be robust and resilient. Now that we aren't stomping all over memory willy-nilly, we can reason far more effectively about the state of a program in the face of an unexpected error. Hopefully someone smarter than me is thinking about this stuff.



lord funk posted:

May be a dumb question, but is there a possibility of an Xcode Edit >> Refactor >> Convert to Swift... in the future?

My guess is no. Although you could parse the straightforward Objective-C code and do some conversions, my guess is there is enough C and ambiguity in there to effectively make it impossible for anything but trivial Objective-C classes, in which case why bother?

Closest things I can think of are automatic VB<->C# compilers which have some similarities because both of those are using the same runtime/framework, similar to Swift and Objective-C. However in that case you have a much more well-defined surface area to deal with (far fewer undefined behaviors), they have a mostly unified type system (something Swift and ObjC do not share), and full metadata.... and it still produces butt-ugly un-maintainable code.

But I could be very wrong about this so YMMV.

Simulated fucked around with this message at 19:44 on Jun 8, 2014

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

rjmccall posted:

It makes the associated type functionally dependent on the principal type. With Sequence<T>, it is theoretically sensible for a type to conform to both Sequence<Int> and Sequence<Float>. That's rarely useful, and it makes the type system far more complicated.

That's not to say that we couldn't do something like that as sugar, though.

I'm starting to wish I had protocol<T> (or at least could specify that an associated type is a generic type) because jumping through the hoops necessary to make protocols compose with just associated types is a bit maddening. That might be my failure to understand and/or apply them properly though.

This doesn't work (obviously):
code:
protocol Monadic {
    typealias A
    typealias B
    typealias Amplified
    
    func Bind(a:Amplified<A>, f:(A)->Amplified<B>) -> Amplified<B>
}
I can't see how I can define a protocol such that a generic method taking some type T must take or return values of protocol<T>. In C# I would do this:

code:
interface IIdentity<T> { }
interface IButts<A,B> {
  IIdentity<B> DoIt(IIdentity<A> a, Func<A, IIdentity<B>> b);
}
I can't figure out how to express that in Swift.

Simulated fucked around with this message at 05:28 on Jun 10, 2014

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

rjmccall posted:

I have spent an amusing amount of time talking about making a monad protocol recently.

I don't understand how your C# example works. It looks to me like it both (1) shouldn't type-check because you're not applying the same number of arguments consistently to your protocol and (2) erases the concrete monad type across bind.

Monad is an example of a higher-kinded protocol: the thing that conforms to the protocol is not a type, it's a type function (generally, an unapplied generic type). That's feasible to add as a feature, but seeing as, frankly, the only use I've ever seen for that even in Haskell is Monad, it is not something we are going to fall over ourselves rushing into the language.

Sorry, I messed it up. That's what I get for not firing up my VM first. I fixed my previous post.

Anyway Bind in C# is actually an extension method (SelectMany) so I think I see where I need to go now and it makes far more sense. I got distracted trying to model it with a protocol when it doesn't belong there to begin with.

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice
Oh, another question rjmccall:

Is there an underlying type I can use to represent a closure or is typealias the only way to get out of a labyrinth of parens?

For that matter, do you know if/when we will see documentation of the Swift standard library? I'm using unofficial sources out on the net right now. There are a lot more types and protocols than are listed in the official reference.

Third question: What happens when I need a huge Dictionary? Isn't that going to run out of stack space? Would the current suggestion be to create an NSDictionary if we want one on the heap?

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

rjmccall posted:

You mean, if you need to write a higher-order function type, and it's not just curried so you can't take advantage of the right-associativity of ->, is there a way to write the function type as something like Function<Int, Void> instead of having to parenthesize (Int -> Void)? Not right now, sorry.

You know at first I thought "WTF is he talking about?"

Then I opened the book in iBooks and did a search for "curry" and there it is on page 768: Curried functions and methods.

This makes me very happy.



quote:

Dictionaries don't actually store data on the stack. It's like a C++ type: the Dictionary value itself is just a small, fixed-size "header" which owns a reference to data stored on the heap, and the type maintains the abstraction that different Dictionary values have independent collections of values and keys.

I'm sure this is just my confusion but this section from the guide seemed to imply that if the keys or values are structs they will be stack allocated, but that was my incorrect assumption.

quote:

Whenever you assign a Dictionary instance to a constant or variable, or pass a Dictionary instance as an argument to a function or method call, the dictionary is copied at the point that the assignment or call takes place. This process is described in Structures and Enumerations Are Value Types.

If the keys and/or values stored in the Dictionary instance are value types (structures or enumerations), they too are copied when the assignment or call takes place. Conversely, if the keys and/or values are reference types (classes or functions), the references are copied, but not the class instances or functions that they refer to. This copy behavior for a dictionary’s keys and values is the same as the copy behavior for a structure’s stored properties when the structure is copied.


So just to clarify how Dictionary<K,V> actually works:

1. Dictionaries declared let are constant in both size, keys, and values if the values are value types. If the values are references then the underlying object can still be modified. (If you use mutating keys then you deserve what you get.)
2. Dictionaries declared var are mutable.
3. In either case, the keys and values are heap allocated.
4. Passing a dictionary does copy the dictionary, but it's just copying a small header struct
5. When the guide talks about copying the whole dictionary, it just means logically the program behaves as if everyone has their own copy of the dictionary, even though in reality they may share the data until someone attempts a mutation; iow the headers all point to the same hash buckets until someone ruins the party

And Array<T> works the same way, except you can mutate a supposedly constant array if you don't change its size (which still seems crazy to me).

Is this all correct?



Further question: Assume that I want to pass a dictionary around, mutating it along the way. I should wrap that in my own class to avoid the repeated copying behavior, yes? Or possibly vend mutation functions that operate on my closed over dictionary. Or would that be attempting to defeat compiler optimizations?



edit: Anyone have success creating a framework and using unit tests written in Swift? I haven't done anything special whatsoever and my first attempt to run a test fails:

quote:

Undefined symbols for architecture x86_64:
"__TFVSs10SequenceOf4JoinU__fGS_Q__USs8Hashable___FTGS_Qd___11keySelectorFQQ_14resultSelectorFTQQQ__Q0__GS_Q0__", referenced from:
__TFC28SwiftNonStandardLibraryTests28SwiftNonStandardLibraryTests17testJoinSequencesfS0_FT_T_ in SwiftNonStandardLibraryTests.o
ld: symbol(s) not found for architecture x86_64

Doesn't seem to make any sense, both the framework and the test project are set to compile for x86_64.

Simulated fucked around with this message at 04:41 on Jun 11, 2014

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice
FYI: you cannot extend a built-in generic type from within a framework with anything that touches the type parameters; the linker will not find the same mangled names and will complain that the symbols are not found. Simplest test case:


1. Create a framework
2. Add swift file with this code:
code:
extension Dictionary {
    func OK() { }
    func NotOK(a:KeyType) {
    }
}
3. In test file, add this code to a test:
code:
        let dict = ["abc": 5, "xyz": 3]
        dict.OK()
        dict.NotOK("")
And you will get an error along these lines:
pre:
Undefined symbols for architecture x86_64:
  "__TFVSs10Dictionary5NotOKUSs8Hashable___fGS_Q_Q0__FQT_", referenced from:
      __TFC23QuickTestFrameworkTests23QuickTestFrameworkTests11testExamplefS0_FT_T_ in QuickTestFrameworkTests.o
ld: symbol(s) not found for architecture x86_64
rdar://17264362 filed


I ran into this while trying to setup a framework and github project for my little non-standard library. I have basic SequenceOf<T> join operations working (left hash join), moving on to group by. I'm not tackling composite keys just yet, just trying to prove the concept. Hopefully this bug is resolved and I can get it out there for comments/contributions.

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

chaosbreather posted:

I've been reading the book and watching the talks and I'm really into it, it seems like a really well designed language. But I was wondering, why have all those global generic functions like enumerate and the like rather than have them attached to the appropriate types as instance methods and computed properties?

So you don't have to rewrite them over and over, or force everything to inherit from some base class.

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

geera posted:

Are there any options for those who aren't paid developers that want to start tinkering with Swift, other than waiting a couple months for Xcode 6? Even if just to compile examples from the Swift book and run them in a terminal or something.

Covered earlier in the thread - not currently. There are hints that people in Apple want to open-source Swift, but either the decision hasn't been made yet or they are still working on cleaning up the repo for public release.


Personally, my expectation is that it will be open source at some point.

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

smackfu posted:

Yeah, it'd be nice if they opened up the XCode download to free developers.

Do you mean Xcode in general? Because that is available in the Mac App Store right now. Just not the beta version.

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

Gul Banana posted:

can you perhaps write
code:
extension CFloat {
    @conversion func __conversion() -> CGFloat {
        return CGFloat(self)
    }
}

extension CGFloat {
    @conversion func __conversion() -> CFloat {
        return CFloat(self)
    }
}

let result:CGFloat = fmaxf((offset / view.bounds.width), 0.0)
not tested, i'm at a PC. i'm also not sure if there's a way to limit the scope of extensions.. ideally this would be something you import for a specific source file or module.


Where did you find @conversion?


edit: My first /usr/bin/swift eternal loop! Still churning away as I type this. Rebooting the VM to see if it goes away.

edit2: Paste this code in and try to compile:
code:
extension SequenceOf {
    struct GroupByGroup<TKey, TResult> {
        let key:TKey
        var items:TResult[]
        
        init(key:TKey) {
            self.key = key
            self.items = []
        }
        
        mutating func addItem(item: TResult) {
            self.items.append(item)
        }
    }
}
rdar://17277999 filed

Simulated fucked around with this message at 00:01 on Jun 12, 2014

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

eschaton posted:

The issue with this is that the Swift standard library isn't copied into the framework or the test bundle like it is for apps. You may be able to manually copy them into your test bundle so they're available when tests are run.

The issue isn't running, it's that the tests can't even build due to the linker failure.

There is a build setting EMBEDDED_CONTENT_CONTAINS_SWIFT that seems to indicate that the standard swift libraries will be included in the product when enabled, but it doesn't make any difference. Copying Swift.swiftmodule to the build objects x86_64 directory doesn't help. Neither does import Swift.

Any ideas on how to go about this? I suspect I would have the same problem trying to use the framework from another app but I will test that later tonight.


edit: Unrelated note, I have working filter, join, and group by now. Tuples work excellently for projecting values, though I don't know that they can be used as keys since I presume they aren't hashable. Would be nice if they were though (assuming all of the items in the tuple are hashable).

Simulated fucked around with this message at 03:27 on Jun 12, 2014

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice
edit: wrong thread, I was looking for the general apple thread.

Simulated fucked around with this message at 21:26 on Jun 14, 2014

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

pokeyman posted:

Can we make properties in Swift atomic by default?



:suicide: actually let's not.


That's not funny. :v:

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

Choadmaster posted:

Thread safety is expensive. I've rarely ensured it in my own lazy-loaded properties unless necessary. I'd make a joke about making atomic properties the default but Ender.uNF would be displeased.

I sneak into the Apple campus at night and commit subtle bugs to the repo. SKProductRequest's misuse of weak references? My handiwork. Don't gently caress with me.

lies

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice
Swift won't automatically coerce function types? That's a drag IMHO... A function returning bool should satisfy the contract of a function returning void (discard the bool).

I've also found myself having to give the parameter types for closures in situations where it seems like the compiler should be able to infer it.


Also we agree about the cycles; the one big ugly wart on ARC. I still wonder if it wouldn't be possible to detect the extremely common cases and make self weak automatically.


rjmccall: is there anything about Swift that would preclude garbage collection? Obviously the current runtime and compiler are centered around ARC, but it seemed like you could in theory have a runtime and compiler that was GC'd. Leaving the ObjC interop aside of course.

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

Nipplebox posted:

There outta be a Swift blog.

My understanding is that Chris Lattner has been pushing for some policy exceptions / changes to allow the team to have a more open development process around Swift. No word on if or when that might happen.


On an unrelated note, while trying to figure out what exactly IndexType is (an associated type on Collection apparently?) and the different ones that are defined (like ForwardIndex, BidirectionalIndex, ReverseIndex, Bit (no index suffix), RandomAccessIndex) I figured hey, maybe I can grab IndexType's mirror and go spelunking to discover derived types, etc instead of having to manually trace it through the generated header. Pro tip: right-click any Swift built-in, Jump to definition and behold all the standard Swift types and functions; some of the comments are pure gold both educationally and a few humorously. Anyway since it turns out to just be a protocol associated type this wouldn't be useful since it isn't constrained to be any specific type.

I did discover ExistentialMetatype which is an awesome name. Unfortunately it turns out Mirror is fairly useless; you can't do any significant runtime introspection that I can tell, even working with a basic type like String (for example, get a list of properties or methods).


My own baseless hypothesis is that runtime introspection of type information is just not a design goal for Swift. People who expect to be able to swizzle method implementations or instantiate instances of classes by name at runtime will be disappointed, at least for now.


I also found some fun REPL bugs:

rdar://17411270 Swift REPL: eternal loop (must kill task)
code:
users-mac:~ user$ xcrun swift
Welcome to Swift!  Type :help for assistance.
  1> var arr = [1,2,3,4]
arr: Int[] = size=4 {
  [0] = 1
  [1] = 2
  [2] = 3
  [3] = 4
}
  2> var m = arr.getMirror()
^Z
[2]+  Stopped                 xcrun swift
users-mac:~ user$
rdar://17411284 Swift REPL: assertion failure on isLegalSILType
code:
users-mac:~ user$ xcrun swift
Welcome to Swift!  Type :help for assistance.
  1> var s = "my string"; var m = s.getMirror()
s: String = "my string"
m: _LeafMirror<String> = {
  _value = "my string"
  summaryFunction =
  quickLookFunction =
}
  2> m.valueType
Assertion failed: (ty->isLegalSILType() && "constructing SILType with type that should have been " 
"eliminated by SIL lowering"), function SILType, file 
/SourceCache/lldb_KLONDIKE/lldb_KLONDIKE-320.3.103/llvm/tools/swift/include/swift/SIL/SILType.h, line 73.
Abort trap: 6
users-mac:~ user$ 
I've pretty much stopped trying to use the REPL or Playgrounds, almost everything I try to write crashes them.

Simulated fucked around with this message at 17:28 on Jun 22, 2014

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

Flobbster posted:

but the thing is, I didn't see anything in the Swift definitions that explicitly defined the ++ operator for ForwardIndex. The only thing I found was these unbound generics:

code:
@assignment @postfix func ++<T>(inout x: T) -> T
@assignment func ++<T>(inout x: T) -> T
So what magic is going on here to make those protocols ++able?

I believe (but don't quote me on this) that this may be a case of a built-in that just isn't represented in those public headers.



Unrelated: Swift supports doc comments to generate .swiftdoc files.

code:
///reads a line from standard input
///
///@param max:Int
/// specifies the number of bytes to read, must be at least 1 to account for null terminator.
///
///
///@return
/// the string, or nil if an error was encountered trying to read Stdin
func readln(max:Int = 8192) -> String? {
 ...
}
(my next blog post will be readln and possibly some other console input functions)

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

rjmccall posted:

Thanks. :) They have some major limitations right now, but it's in my queue for 1.0 to fix that.

We actually have a lot of the information you'd need for things like this reflected at runtime; we just don't have an API to take advantage of it yet. Figuring out the right API there will take some real attention.

That's great news; better to take the time to get the API "right", we'll all be living with it for some time.

I was just trying to use it to pry open the guts of ExistentialMetatype so not a big deal.


quote:

Sigh. Sorry.

Not a big deal; I can file bugs against some of these things, I haven't been keeping track of them so far. I've also run into a ton of cases where some partial syntax causes a crash, but someone did a good job of XPC isolation (when not in a Playground) and Xcode just gives me the popover "SourceKit Terminated - some editor functionality may be limited", then it kicks back on and I go on my merry way. I think a bunch of this is Xcode failing to handle certain kinds of Swift compiler failures.

ex: typing "withUnsafePointer" in the middle of an existing method can crash SourceKit 100% reliably for me. I only have this one because I was just using it recently, before I realized array already has withUnsafePointerToElements:
(edit) rdar://17413213 filed for this one

code:
@objc class StorageProperty<T: AnyObject>   {
    let objkey : CConstVoidPointer = "temp".cStringUsingEncoding(NSUTF8StringEncoding)! //make guid
    
    init(value: T) {
        withUnsafePointer(
        objc_setAssociatedObject(self, objkey, value, UInt(OBJC_ASSOCIATION_RETAIN_NONATOMIC));
    }
}
Also you can see the horrible things I am trying to do; I'm currently trying to do a memoized version of SequenceOf<T> so I can support count(), multiple iteration, etc safely but that requires having a place to stash the concrete sequence.

Also the header for the associated object stuff typedefs objc_AssociationPolicy to uint, but the enums to int so it requires a hilarious cast. I guess that's a long-standing :confused:

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice
Debugger busted! Pay no attention to the code here, I'm almost certain it won't work, I just wanted to try it. However I can't debug anything when this extension to Dictionary is present. rdar://17414370

code:
let k = "mutableProp"
let mutablePropKey : CConstVoidPointer = k.cStringUsingEncoding(NSUTF8StringEncoding)!
extension Dictionary {
    var mutableProp : String? {
    get {
        let r : AnyObject! = objc_getAssociatedObject(self, mutablePropKey)
        return r as? String
    }
    set {
        objc_setAssociatedObject(self, mutablePropKey, newValue, UInt(OBJC_ASSOCIATION_RETAIN_NONATOMIC));
    }
    }
}
Set a breakpoint in the mutableProp setter and try "po k":
pre:
(lldb) po k
error: <REPL>:1:1: error: non-nominal type '$__lldb_context' cannot be extended
extension $__lldb_context {                            
^
<REPL>:9:49: error: type '@lvalue Dictionary<String, Int>' of variable is not materializable
func $__lldb_expr($__lldb_arg : COpaquePointer) {      
                                                ^
edit: This is a good one. Put these lines in main.swift instead to test if it would still happen in a different context:
code:
let kk = "mutableProp"
let mk : CConstVoidPointer = k.cStringUsingEncoding(NSUTF8StringEncoding)!
Xcode pegging CPU, debugserver pegging CPU, Xcode won't stop the task, and you can't do anything. Force-quitting the binary or debugserver don't help. Trying to quit Xcode and it prompts to stop tasks but that blocks and it is still stuck. Required full-on force quit. Fun!


edit2: :v: same thing after relaunching so apparently I have a reproducible test case.

Simulated fucked around with this message at 05:36 on Jun 23, 2014

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice
We're back!

I filed a couple more Swift compiler crash bugs in the mean time.

I also discuss making Tuples Equatable

And call-by-name in Swift

Discovered you can create your own SwiftDoc with /// code comments


And here is my SwiftNonStandardLibrary, featuring the missing readln(), extensions to SequenceOf<T>, exception handling, and some other goodies. Please contribute if you can! I am accepting pull requests. A compiler bug currently prevents the tests from working properly, but if you pull the files into a console project all the tests pass.

I'm also working on a futures/GCD wrapper but haven't got anything committed yet. I don't much care for some of the others I've seen - they are fairly obvious grafts of other APIs onto Swift. I want to do something fancier, but we shall see.

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

Doctor w-rw-rw- posted:

Psst: your submodule isn't specified!


Arrrggggg.... That's what I get for checking the "create git repo" checkbox in Xcode. It should be cleaned up now.

I'm new to the whole "Swift framework" thing so I'm sure I have screwed up something else somewhere.

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice
Added ThreadLocalSlot<T> to support thread-local storage. Tests seem to be OK but don't rely on it for production code :v:

Next priorities for heavy-lifting: decent GCD abstraction and/or futures, then apply that to sequences to give seq.parallel() which will yield a sequence that automagically does its work in parallel on background queues. For light weight, some of the easier methods just need to be filled in (possibly using existing Swift library methods).



Also filed my next Swift hard crash bug report*, but that's nothing compared to SourceKit. I can't even file them all because it's too much work to figure out every individual thing that triggers the blow ups, but this one caught my eye:

Thread 5 Crashed:: Dispatch queue: sourcekit.swift.ConsumeAST
0 libsystem_c.dylib 0x00007fff8f395732 strlen + 18
1 com.apple.SourceKitService 0x000000010e482090 swift::ClangImporter::lookupValue(swift::Identifier, swift::VisibleDeclConsumer&) + 64

Crash in strlen... that looks "dangerous".

* You can't define struct init() methods with parameter default values, at least it reliably crashes for me.


edit: Manual Retain/Release in Swift

Simulated fucked around with this message at 05:20 on Jun 27, 2014

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

Doctor w-rw-rw- posted:

Thread-locals are bad on modern iOS/OS X platforms in any case, IMO. With increasing use of GCD queues, and no guarantee that a queue will schedule on a consistent thread, thread-local storage isn't that useful. IMO, a wrapper for dispatch_queue_set_specific would be more useful instead.

Also, if you don't mind the Objective-C baggage, you can just use +[NSThread threadDictionary] for thread-locals (not queue-locals), anyhow. Probably not an option if you're not dealing with non-NSObject subclasses.


Re: parallel collection enumeration - perhaps a wrapper around a dispatch_apply onto a concurrent queue would do nicely.

I'm working on queue stuff right now, still in progress.

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice
pre:
Bitcast requires both operands to be pointer or neither
  %43 = bitcast %objc_object* %42 to %PSs9AnyObject_, !dbg !379
Stored value type does not match pointer operand type!
  store %PSs9AnyObject_ %43, %objc_object** %44, align 8, !dbg !379
 %objc_object*LLVM ERROR: Broken function found, compilation aborted!
Command /Applications/Xcode6-Beta2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift failed with exit code 1
code:
    var context: AnyObject? {
    get {
        let ptr = dispatch_get_context(_queue)
        if ptr != nil {
            let unmanaged:Unmanaged<AnyObject> = Unmanaged.fromOpaque(ptr)
            //return unretained value so we dont change retain count
            return unmanaged.takeUnretainedValue() //CRASH CITY <----
        }
        
        return nil
    }
    set {
        //grab old value so we can clean it up
        let oldPtr = dispatch_get_context(_queue)
        
        //do an unbalanced "retain" so the object will stay alive
        //we are responsible for eventually releasing somewhere
        if newValue {
            let ptr = Unmanaged.passRetained(newValue!)
            dispatch_set_context(_queue, ptr.toOpaque())
        } else {
            dispatch_set_context(_queue, nil)
        }
        
        //cleanup the old value
        if oldPtr != nil {
            let unmanaged:Unmanaged<AnyObject> = Unmanaged.fromOpaque(oldPtr)
            unmanaged.release() //balance out the retain we did when originally set
        }
    }
    }
I'm telling it that I've got an Unmanaged<AnyObject>. What's crazy is this exact same code works fine in ThreadLocalSlot<T:AnyObject>. rdar://17492202


Also, "error: unimplemented IR generation feature non-fixed class layout" is getting really old.

Simulated fucked around with this message at 00:46 on Jun 28, 2014

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

ljw1004 posted:

How do you switch on an optional type? I tried this...

code:
let x : String? = nil

switch x {
    case nil: println("nil")
    case "fred": println("fred")
}
The "case nil" gives an error saying that the operator ~= isn't defined "on the supplied arguments". I guess I'd expected it to be implicitly defined at least for this case...

The "case fred" actually gives an error asking if I'd meant to write ? or ! but I'm not sure where I'd write it...


I don't know if this is the best way, but:

code:
var s:String? = "fred"

switch s {
case let x where x == "fred":
    println("hi")
case let x where x == nil:
    println("nillllll")
default:
    println("i have no idea")
}
I too thought there must be a way to case out a switch with an optional but I didn't see one.

Adbot
ADBOT LOVES YOU

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice
Apparently one of my favorite generics casting tricks from C# didn't make the transition to Swift because you can't specialize a generic function (aka provide the type parameter explicitly):

code:
    func getContext<T:AnyObject>() -> T? {
        return self.context as? T
    }

let o = getContext<String>()
I also find myself having to write annoying things like this:

code:
let x:SomeGenericType<I_Am_A_Type> = SomeGenericType()
I think you should be allowed to specialize a generic type or function, at least in these two cases. Are there any downsides?

  • Locked thread