When your code fails it's never the fault of the language. It's always ones own fault, a typo, some error in the logic, or something. Debugging always reveals that with a stone face. Always.
Except
> "It turns out, there was a bug in Set.intersection(_:), but it had only been discovered this past June, and the fix hasn’t made it into a public version of Swift yet. "
As someone who worked on C compilers for DSPs for a few years, I was conditioned for a while to think "compilers are broken, libraries are broken - you have no hope" for a while, when all I dealt with was our software. Obviously that's heavily influenced by what I was actually dealing with day to day and not by normal software development, but still :)
One of the guys in my team handled a frantic support request from a Formula 1 team because they required reproducible builds or else they got some fine from the FIA, and they somehow hit a situation where our compiler was outputting different code depending on time of day. Wild.
From your description of the bug, I think even know which compiler you worked on. I worked on a competitors compiler. The state of embedded tools in the lates 90s and early 2000s was deplorable. I'm surprised we got anything working. (I went to work for the compiler team because I was so pissed off at how poorly they worked.)
Miscompilations (interpretations) are fairly common in my experience; just most of them don't drastically affect the final result.
I used to have a methodical way of investigating most bugs: (1) here's what I know, (2) here's what I don't, (3) here's the thing I would like to know to most restrict the remaining search space. It was fine enough for awhile, but when you don't know things like "I wrote a 0 here, therefore a 0 exists here", or "my code explicitly uses aligned 32-bit reads, so I issued an aligned 32-bit read here", the errors in your assumptions quickly get amplified into nonsense. Nowadays I explicitly includle miscompilation (interpretation), bit-flips, and other such garbage as I write down what I do or don't know about the system, and I throw in ballpark probabilities to figure out where to look next. Most debugging isn't noticably slower that way, but the hairy problems are easily 10x easier when you haven't conditioned yourself to ignore the real solution.
Or if you compile in release mode, in which case the fixed version is (maybe only sometimes?) inlined into your executable.
I ran into the same bug, but since I'd included a `precondition` to verify that each elf-group had only one common item type, I discovered the bug immediately. I then needed about 5-10 minutes to convince myself that it really was a Swift bug and not a mayoff bug.
For most engineers, you’ll have a handful of times in your career when the compiler or runtime really is the problem. The rest of the time it’s like 95% your fault and 5% the library’s fault.
I'll be doing AoC in C this year. And I've decided to do that every year as I enjoy doing it in C and trying to get the entire calendar, all 50 parts to run in less than one second on a single core, which it turns out is quite doable, but only with a much deeper understanding of the problems. I end up learning a lot more computer science this way.
I also like it since I don't do any work or even side projects in C these days, and so it's nice to keep my C chops up to scratch.
Day 22 (https://adventofcode.com/2021/day/22) is the one that nearly killed me in 2021. I did get it using a technique of breaking any overlaps into smaller and smaller rectangles, but it took like 30s to run. I looked on the AoC reddit, and honestly I still don't understand what I needed to do to make it better, but visualizing 3d spaces has always been a weakness for me.
For doing it in C, by far the most useful thing you could do is implement your own generic hash table. Having a good hash table handy makes things a lot easier. Though since you're a beginner you might want to find a good library for it at first. Writing a hash table is great C exercise though, so I definitely recommend doing it at some point.
I don't necessarily want to share my github as it contains my real name, but I'd be willing to send you a tarball of my 2020 code tomorrow if you send an email to mtlmtlmtlmtl at pm.me
I've just now started on day 1 for this year, so no code there yet worth showing off.
Wow, Dave DeLong! A name that reminds me of learning Objective-C for an internship in 2010. As he was very active on Stackoverflow back then, and blogging too, maybe? I haven’t kept track much of Swift and the he Apple ecosystem since, but seeing this post brings back good memories.
I'm confused. The post mentioned that this was fixed in Swift 5.7, but I have Swift 5.7.1 on my macOS Monterey and the bug is still present if I modify my AoC solution to exhibit the problem. Is Swift 5.7.1 on Monterey different from the 5.7.1 on Ventura?
$ swift -v
Apple Swift version 5.7.1 (swiftlang-5.7.1.135.3 clang-1400.0.29.51)
Target: arm64-apple-macosx12.0
I love Swift as a language, but the lack of release notes for 5.7.1 (aside from a blog post for 5.7 as a whole), OS-specific releases (especially for SwiftUI), Xcode removing old toolchains when it upgrades (making me re-download tvOS 15.4 runtime for no reason), and all these other little things are starting to weigh on me.
The bug is apparently in the Swift runtime. You may be compiling with Swift 5.7.1, but you must be picking up the older runtime distributed with macOS 12.6. I think you can still run locally against a more recent Swift runtime though:
Ah, I forgot that compiling with an SDK version doesn't necessarily mean you get the runtime with it. Dynamic linking instead of static linking. Sometimes, software development gets too complicated; too many things to keep in mind.
But that's my question. Similar to the other comment at https://news.ycombinator.com/item?id=33848354, I have 5.7.1 on Monterey. 5.7 isn't restricted to Ventura. Is the problem that the fix in 5.7/5.7.1 didn't actually fix it?
I hear you. That's part of the joy I seek with AoC.
Most years I choose a language I've never worked with commercially (e.g. Fennel in 2022) and rather than reach for prebuilt libs for timesaving fancy array or set or string ops, I'll invent those wheels myself without dependencies and I find a ton of satisfaction in it. Unwise commercially but ideal for learning and play. And, yeah, bugs!
IMO, when it's not a customer paying for my learning curve, there's a lot to be said for rewalking old paths with new boots (or no boots and funky coloured glasses). Also, a terrible way to get onto the leaderboard IME!
It is great fun to try and build as much as possible yourself. Last year I ended up with a pretty good A* implementation in Clojure cos it kept coming up in the puzzles and I learnt a ton from doing it.
Intersections are the reason you'd want a set, as the original post indicates. See the problem here: https://adventofcode.com/2022/day/3 (sets are even more of a fit for part 2, which is hidden for an anonymous viewer).
That's pretty much how every one emulates them, with a `map[{TYPE}]struct{}` or possibly `map[{TYPE}]bool` if the space isn't a problem, and you find it easier to read (or if you want to be able to check for membership by indexing instead of using the comma ok idiom).
Right, that's exactly what I've done and is, I think, the idiomatic way to do it in Go. I meant for things like intersection, union, etc I will have to write my own implementations, but that's part of the fun!
Hey, just noticed our impls. for Day 2 look very similar. If you’re curious, Day 2 can be further improved by using modulo + 2 (or 1 if compiler is smart enough) branches instead of lookup table:
https://github.com/neon-sunset/AOC2022/blob/main/Day2/Progra...
Except
> "It turns out, there was a bug in Set.intersection(_:), but it had only been discovered this past June, and the fix hasn’t made it into a public version of Swift yet. "
One of the guys in my team handled a frantic support request from a Formula 1 team because they required reproducible builds or else they got some fine from the FIA, and they somehow hit a situation where our compiler was outputting different code depending on time of day. Wild.
I used to have a methodical way of investigating most bugs: (1) here's what I know, (2) here's what I don't, (3) here's the thing I would like to know to most restrict the remaining search space. It was fine enough for awhile, but when you don't know things like "I wrote a 0 here, therefore a 0 exists here", or "my code explicitly uses aligned 32-bit reads, so I issued an aligned 32-bit read here", the errors in your assumptions quickly get amplified into nonsense. Nowadays I explicitly includle miscompilation (interpretation), bit-flips, and other such garbage as I write down what I do or don't know about the system, and I throw in ballpark probabilities to figure out where to look next. Most debugging isn't noticably slower that way, but the hairy problems are easily 10x easier when you haven't conditioned yourself to ignore the real solution.
It turns out the bug fix has been released publicly, but only on newer OS versions.
I ran into the same bug, but since I'd included a `precondition` to verify that each elf-group had only one common item type, I discovered the bug immediately. I then needed about 5-10 minutes to convince myself that it really was a Swift bug and not a mayoff bug.
I also like it since I don't do any work or even side projects in C these days, and so it's nice to keep my C chops up to scratch.
https://github.com/forrestthewoods/aoc2021/blob/master/rust/...
What kinds of optimisations have you had to do? Are you hosting your code anywhere?
I don't necessarily want to share my github as it contains my real name, but I'd be willing to send you a tarball of my 2020 code tomorrow if you send an email to mtlmtlmtlmtl at pm.me
I've just now started on day 1 for this year, so no code there yet worth showing off.
https://news.ycombinator.com/item?id=33848354
https://news.ycombinator.com/item?id=33821092
Most years I choose a language I've never worked with commercially (e.g. Fennel in 2022) and rather than reach for prebuilt libs for timesaving fancy array or set or string ops, I'll invent those wheels myself without dependencies and I find a ton of satisfaction in it. Unwise commercially but ideal for learning and play. And, yeah, bugs!
IMO, when it's not a customer paying for my learning curve, there's a lot to be said for rewalking old paths with new boots (or no boots and funky coloured glasses). Also, a terrible way to get onto the leaderboard IME!
Requires thinking if you want to implement set difference or intersection. I just figured depending on needs using existing built-in types may be fun.
Deleted Comment