|
Doh004 posted:Started new job where our new solution is all Swift. Are we doing something wrong where most of the objects aren't debuggable? I can't do po myObject anymore. Just get a slew of lldb errors. Is it some build configuration setting? I'll get certain files or parts of certain files where any debugger action just spews errors instead. I can't be arsed to track down the problematic parts, but maybe knowing that you're not alone will help.
|
# ? Feb 5, 2015 04:35 |
|
|
# ? May 14, 2024 02:26 |
|
I see this a lot, especially when dealing with CoreData objects - even when the debugger is at a breakpoint, they're unintelligible unless I do loads of println() work around them...
|
# ? Feb 5, 2015 14:31 |
|
Ender.uNF posted:Check for warnings or problems in your headers. If there's anything amiss it will put lldb into a tailspin. Hmm there was one about some weird rear end library search header. Trying it now. pokeyman posted:I'll get certain files or parts of certain files where any debugger action just spews errors instead. I can't be arsed to track down the problematic parts, but maybe knowing that you're not alone will help. Ugh this sucks. Do you also have Xcode randomly freak out and have the cursor jump around a file from time to time?
|
# ? Feb 5, 2015 16:02 |
|
I gave up trying to use lldb to drill down at all in Swift. I would show students breakpoints and 'po' but it would just hang for 10 seconds and then spit out gibberish, every time.
|
# ? Feb 5, 2015 16:12 |
|
So how the hell do we debug properly? println everywhere?
|
# ? Feb 5, 2015 16:55 |
|
Just write correct code the first time.
|
# ? Feb 5, 2015 17:07 |
|
Doh004 posted:So how the hell do we debug properly? println everywhere? Switch to visual studio I wish!
|
# ? Feb 5, 2015 17:15 |
|
Is it easier to implement an awesome debugger like visual studio has for C# when the language uses JIT compilation? Or does that not matter? Either way, Swift's debugging capabilities are pretty lacking.
|
# ? Feb 5, 2015 17:43 |
|
fleshweasel posted:Is it easier to implement an awesome debugger like visual studio has for C# when the language uses JIT compilation? Or does that not matter? It doesn't really matter. fleshweasel posted:Either way, Swift's debugging capabilities are pretty lacking. First: as a meta note, don't take this post as discouraging venting. Vent away about whatever terrible things you find. I just want to explain from my perspective (1) why some of this is how it is and (2) why there's reason to be hopeful. The main thing is that, as I've tried to emphasize before, this first year is really more of a public beta of Swift than a proper release. I know that marketing hasn't been clear about this, but I've always tried to be straight with you. It's not just that Swift is not finished, in some grand sense of the word; it's that Swift is not really done. It's usable on some level, and we are promising to support what we've shipped; but there's a lot of stuff that's missing, or doesn't work, or is just embarrassingly broken. I hope that most of that will be better after the first full year, and that it'll be closer to just not being cosmically-speaking finished. But we'll see. Now, I have some rants about LLDB that I can't really share because I'm not actually anonymous here; maybe if this were a goonmeet. But most of the instability/inadequacy you're seeing there really is caused by us — Swift, LLVM, LLDB, all together — trying some very aggressive things technically that haven't quite gelled yet. It is often the case, especially in language work but in programming in general, that one small corner-case problem in your code or your configuration blocks the entire product from functioning, even when that's not really the bit of your code that you care about at the moment. Of course, as a user you perceive that as the product being completely broken, which is a fair perspective in the sense that your work is completely disrupted; I'm just saying that, as an insight into the state of development, it doesn't actually tell you as much as you might think. There are two major technical pushes hurting Swift debugging right now, at least that I can think of off the top of my head, and both of them should ultimately lead to a much better experience when they come together a bit more. Traditional Unix/Darwin C debugging is based off of DWARF, which is basically a weird shadow AST that gets emitted into object files with ties back to the actual emitted function. gdb essentially implements its own language frontends using DWARF as the AST, which is both why it feels more forgiving sometimes and why there are firm limits to what it can handle in the expression parser. Part of the vision for LLDB has always been to provide a more authentic language experience, which it does by trying to map DWARF back into real Clang AST and letting Clang interpret it. That's why LLDB is capable of parsing arbitrary language structures, but also why it can be frustratingly strict. In principle, a lot of that strictness could be fixed — Clang knows that it's parsing a debugger expression and could apply more lenient language rules — but unfortunately that team has never had enough time for that kind of polish work because they keep getting pulled around by other projects. Like, say, getting told to add a whole new language mode for Swift. Mapping DWARF back into Clang ASTs does have a major risk, though, which is that you really need DWARF to fully encode the actual language; if there are gaps that DWARF doesn't get right, things just break. For example, until fairly recently, the DWARF spec itself didn't have any way to encode C++11 ref-qualifiers on methods, so that stuff didn't round-trip correctly, with the result that you actually can't call those methods from lldb. That's getting fixed, but it's a problem we wanted to define away in Swift. Swift therefore uses DWARF pretty much only to track variables around the call frame; the DWARF types and declarations are just there to provide references back to the actual Swift ASTs generated during compilation. It's a really promising technical direction, and it does show benefits when it works, but unfortunately there are just a lot of kinks we haven't resolved yet; and when it doesn't work, it doesn't work at all. Plus, whenever you have a significant technical shift like this, it just takes time to replicate all the capabilities of the previous model; there's a lot of tooling which is tied to precise details of the old thing that you can never perfectly imitate, and which you may never have meant to guarantee even in the old world. The second major technical direction is value tracking. In C, local variables usually live in memory, generally in fixed locations on the stack. LLVM is pretty good at honoring debugging directives that say obvious things like that: "hey, the location of this variable is this particular offset within the frame". When the optimizer moves the variable into registers, this sort of tracking gets more complicated, and LLVM kindof sucks at it. In C, that's arguably okay, maybe, because it's understood that optimization inhibits debugging somewhat; but LLVM often fails to even make best-effort attempts to remember debugging information about variables that aren't on the stack. Again, it's just polish work that they've been deprioritizing. Well, it turns out that a bunch of language features in Swift make it harder to always keep variables in a fixed location on the stack, even in debug builds. We're much more reliant on having to tell LLVM, "hey, the address of this variable is the result of such-and-such computation" or "hey, the current value of this variable isn't stored in memory, it's just such-and-such value at this point in the function". Now, those are exactly the things that good optimized C debugging relies on, but like I said, LLVM has been punting on that work for a long time. The unfortunate thing for LLDB as a team is that it's not their fault at all; it's a combination of language complexity and LLVM bugs that just happens to look exactly like yet another "loving debugger can't do anything right" problem.
|
# ? Feb 5, 2015 21:04 |
|
That was an OK post.
|
# ? Feb 5, 2015 21:07 |
|
Subjunctive posted:That was an OK post. :hugbox:
|
# ? Feb 5, 2015 21:08 |
|
Thanks for that rjmccall. While I understood about half of what you said, I do know that there's plenty of reasons for stuff not working. Definitely appreciate your perspective on it, just a bit frustrated at how unfinished it is. I know you're saying it should have been called a Beta, and I would have been cool with that label, but it sucks that Apple as a whole isn't calling it that. This is most definitely not a 1.0.
|
# ? Feb 5, 2015 21:42 |
|
I don't know why it feels better to have some insight into why poo poo breaks, but it does. Thanks. I guess in the "ruthless efficiency" sense the current prioritization works on me: I haven't run away screaming from Swift. If I was leading a team on a new project today, though, there's no way I'd admit Swift into it. I'll try to remember the missing "public beta" label, it's very easy to forget.
|
# ? Feb 5, 2015 21:48 |
|
Just imagine all the guys out there in the trenches, like us, without "Just one more thing - Swift thread"
|
# ? Feb 5, 2015 22:05 |
|
Seriously, I have loved swift development. It's a great language. Thank you for the insight you provide into the issues facing the language designers.
|
# ? Feb 5, 2015 22:18 |
|
pre:/Classes/PGOperation.h:9:9: note: in file included from /Classes/PGOperation.h:9: #import <AFNetworking/AFHTTPRequestOperation.h> ^ /Pods/Headers/Public/AFNetworking/AFHTTPRequestOperation.h:24:9: note: in file included from /Pods/Headers/Public/AFNetworking/AFHTTPRequestOperation.h:24: #import "AFURLConnectionOperation.h" ^ /Pods/Headers/Public/AFNetworking/AFURLConnectionOperation.h:192:1: error: property with 'retain (or strong)' attribute must be of object type @property (nonatomic, strong) dispatch_queue_t completionQueue; I am not using AFNetworking or even PGOperation anywhere in the code I am trying to debug, but because AFNetworking is reachable from the bridging header, the semantic error (treating the dispatch types as strong**) completely prevents LLDB from being able to print out certain objects or run certain commands. I can fix it by moving the header into the implementation file if possible, or changing the AFNetworking definition. ** In reality, under Obj-C and ARC the GCD references are all object types so this is actually OK. I think LLDB is using the wrong defines when it processes the headers so it ends up with a different definition than the actual running code has which is... a whole other horror given the turing completeness of the C preprocessor.
|
# ? Feb 5, 2015 22:54 |
|
rjmccall posted:First: as a meta note, don't take this post as discouraging venting. Vent away about whatever terrible things you find. I just want to explain from my perspective (1) why some of this is how it is and (2) why there's reason to be hopeful. If we can't come here to vent then what's the point? A++ post, would read again.
|
# ? Feb 5, 2015 22:59 |
|
Ender.uNF posted:** In reality, under Obj-C and ARC the GCD references are all object types so this is actually OK. I think LLDB is using the wrong defines when it processes the headers so it ends up with a different definition than the actual running code has which is... a whole other horror given the turing completeness of the C preprocessor. I think that's exactly what's happening. GCD/XPC types like dispatch_queue_t are only object references in 10.8 / 6.0 and higher, and LLDB may not be setting a deployment target (despite knowing exactly what target to build for).
|
# ? Feb 5, 2015 23:17 |
|
Subjunctive posted:That was an OK post. I liked it
|
# ? Feb 6, 2015 02:56 |
|
Xcode 6.3b1 is out, with changes significant enough to warrant a code migrator.
|
# ? Feb 9, 2015 19:51 |
|
Swift Blog posted:let constants are now more powerful and consistent — The new rule is that a let constant must be initialized before use (like a var), and that it may only be initialized, not reassigned or mutated after initialization. Actually, for everything in the post.
|
# ? Feb 9, 2015 20:17 |
|
Incremental compilation!!!
|
# ? Feb 9, 2015 20:22 |
|
Yessssssss! Downloading now, I hope the incremental builds work well. Tons of other cool new features and fixes too. I'm really happy you can "if let" multiple things at once now, although the syntax seems a little bizarre.code:
code:
|
# ? Feb 9, 2015 20:34 |
|
Would the value of a let expression always be true, then? Would you expect short circuiting of evaluation?
|
# ? Feb 9, 2015 21:39 |
|
It'd be true if a value was extracted from the optional and false otherwise, and it would short-circuit like any other boolean expression. I think that would be a pretty logical extension of the simple if-let syntax and would eliminate the need for another special syntax. It's not a huge deal, I was just surprised when I saw that because I thought making it a boolean expression was the obvious solution. Maybe there's a reason it wouldn't work that I haven't thought of, though.
|
# ? Feb 9, 2015 22:33 |
|
dizzywhip posted:Not sure why let x = y couldn't just be a standalone expression in the context of an if statement so you could just do something like this: Because && is an ordinary binary operator, and it would be kindof silly to have a special parsing rule for it so that if let x = foo() && bar() doesn't parse as if let x = (foo() && bar())
|
# ? Feb 9, 2015 22:39 |
|
I suppose so, but a special parsing rule that makes the language more intuitive for the user (or at least for me, I can't say how intuitive it would be in general) seems like a lesser evil than a new syntax to handle one specific situation.
|
# ? Feb 9, 2015 23:03 |
|
I would have thought it would have been if let a, b = foo(), bar() so it's like a regular multi assignment.
|
# ? Feb 9, 2015 23:08 |
|
chaosbreather posted:I would have thought it would have been if let a, b = foo(), bar() so it's like a regular multi assignment. What we're currently considering as the slightly longer-term vision here is introducing an optional-desugaring pattern, probably spelled ?, and then taking away the special semantics of if let. So to get the current behavior, you would have to write: Swift code:
Swift code:
Swift code:
Swift code:
rjmccall fucked around with this message at 23:43 on Feb 9, 2015 |
# ? Feb 9, 2015 23:36 |
|
One weird tip to cause a segfault (19585191):code:
|
# ? Feb 9, 2015 23:51 |
|
rjmccall posted:Because && is an ordinary binary operator, and it would be kindof silly to have a special parsing rule for it so that if let x = foo() && bar() doesn't parse as if let x = (foo() && bar()) Sure, but I guess I'd expected "let" to have much higher precedence. After all there are few useful operators upon possibly-null types, so you'll rarely want to do things like && on the argument of a "let ID = expr".
|
# ? Feb 10, 2015 00:10 |
|
?? comes to mind. Right now it has the same precedence as ||, which is actually lower than &&, although we're looking at bumping it to higher than && for separate reasons. Trust me, the first option we considered was &&, and after some discussion we decided that we didn't really like the results. Beyond the really weird things it does to the grammar (because && is not the lowest-precedence operator), it also implies way too much: it makes 'let' pattern '=' expression look like a general expression form that could be used anywhere, e.g. nested within ||, !, and arbitrary other short-circuiting or oddly-evaluated forms, which is basically just a disaster. A superficially similar construct, let x = y in z, works in functional languages; but there, crucially, the binding is scoped to a specific expression, which is not what you're asking for here. Here, the name really needs to be bound in an enclosing scope (albeit a new one) and then available in later expressions in the condition. It just doesn't work as a general expression with these semantics; the type-checker would actually have to check control flow through the expression before it could even resolve name lookup, or we'd have to come up with some further special-case rule about it. It's a lot of complexity to embrace just to get a slightly more natural operator, when the comma works fine and is analogous to list-comprehension (it is basically exactly the same, but in the Optional monad rather than List.)
|
# ? Feb 10, 2015 01:08 |
|
That makes sense. It seemed like a simpler solution on the surface, but I hadn't really considered the implications of how it would work in more complicated expressions. I'm very happy with 1.2 overall so far. There does seem to be several new bugs that I've encountered, but I haven't run into anything that didn't have a straightforward workaround. And compile times are enormously improved in most cases so far, which is a huge relief.
|
# ? Feb 10, 2015 02:23 |
|
That's good to hear. There's a lot of work left to be done with both incremental compilation and type-checking speed generally, and I was a little worried that the improvements might not prove to be general enough, so I'm happy to hear that people are seeing a difference. If anyone is curious, I spent most of this release cycle designing and implementing secret language features to make arrays faster. So if you see any weird results with arrays, it might be my fault (hopefully it is actually your fault for doing something that's not allowed (it is actually still my fault for not telling you what's not allowed)).
|
# ? Feb 10, 2015 03:46 |
|
Requiring 10.10 makes me sad
|
# ? Feb 10, 2015 05:05 |
|
rjmccall posted:?? comes to mind. Right now it has the same precedence as ||, which is actually lower than &&, although we're looking at bumping it to higher than && for separate reasons. I understand the rest of your post, but don't understand this as a counter-example for "if let x = a ?? b && let z = c". If it means "if let x = (a ?? b)" then it's be wrong because a??b wouldn't be an option type and hence you couldn't do "if let" on it. (unless it was a double-option-type which is just ugly). If it means "if (let x = a) ?? b" then it's wrong because the only way ??b could work is again if 'a' were a double option-type. Overall, I'm struggling to see anything other than . and ?. and [] which should have a higher precedence than "let". The only operators where it would make sense would be either operators on optionals (and there aren't many), or the ternary if operator ?: as in "if let x = b ? a : b"
|
# ? Feb 13, 2015 08:55 |
|
The result of ?? has the optionality of its right-hand side. It is both (T?,T)->T and (T?,T?)->T?. That means if let x = y ?? z makes sense without weird nested optionals: it just binds x to the first of y or z that has a value, assuming they're both optional.
|
# ? Feb 13, 2015 10:02 |
|
I hope some of the more common 'functional' operators start landing in the standard library. Seeing some weird looking operators out there made out of a mish mash of what's allowed in operator definitions, and what exists in other languages. Either as global methods like map and filter or operator defined like "+"
|
# ? Feb 16, 2015 03:27 |
|
They won't because that's a lovely idea. Why would you want to do that with operators? I can understand wanting comprehensions, but seriously, some people just have the worst instincts. ETA: oh, if you mean piping operators, I'm still skeptical but a little less so.
|
# ? Feb 16, 2015 03:54 |
|
|
# ? May 14, 2024 02:26 |
|
Maybe I worded it poorly, but some of the libraries you get when you google "Functional swift" introduce some weird operators. For example "<^> j <| ...", "<*> j <|| ..., ">>==" (as a flat map not bit shift, already a collision), "<<" (another collision, append array). I don't want to have to guess (look up) what a `simple` operator means in different contexts so I prefer words. Some 3rd party swift library developers seem to have a different opinion. I think the error description displayed when playing and trying to define operator flatMap vs just a function flapMap derailed my Sunday. I was just trying to see the different approaches others have taken (that seem popular). I think the better approach would be to follow 'map()'s example, and not '+'s. There is a large body of blogs and code that look at it as an operator.
|
# ? Feb 16, 2015 06:54 |