3 ms·
There's a tremendous amount of value, in any creative task, in being able to sketch out ideas quickly. The less time you spend seeing if the shape of the thing
by wool_gather 8y ago
There's a tremendous amount of value, in any creative task, in being able to sketch out ideas quickly. The less time you spend seeing if the shape of the thing you're making is broadly okay, the more shapes you will be able to try, and the higher the chance that you'll converge on a good one.
Swift really does not support quickly iterating on a design. It demands that you sit down with your plan fully-formed, ruler and protractor in hand. Due to its strictness, changes ripple very quickly across even a small codebase.
Realized you need another enum case? You can't compile again until you touch all your switches. Protocol would be more expressive with an associated type? Stop what you're doing and write some type eraser boilerplate. Function needs to signal an error condition? Try/do/catch anywhere you call it, right now, before you run again. Need to put another type into that array? Write a new protocol and add some conformances.
Changing a interface as you work in Swift immediately creates a sea of red marks, which hinders the ability to experiment.
You're right that this strictness helps write ~correct~ safe code, and I appreciate that. But it's a tradeoff; there's a real cost in developer productivity/creativity. And I believe that it does not help produce the best design. It takes too long to get to running, which makes it too costly to heavily revise based on what you learn as you build.
EDIT: Actually, I want to go even further, and strike out "correct" in the paragraph above. Swift helps at a certain level of correctness, which is really not much higher than the type system -- it would be better to call this "sound" code, rather than "correct".
The overall point that I'm trying to make is that at the level of application/business logic -- which is the whole point of the program, after all -- Swift does not help with correctness. In fact, it can be detrimental, because, unless/until you understand your use cases well enough to actually lift them into the type system, at that upper level it blocks exploration without adding rigor.
- nielsbot 8y agoI agree. Thank you for writing this. I realized recently that I actually do like static typing, as long as the cost is low. (I really like TypeScript) Sorry, I don't want to reason about the "shape" of my application state vector before I've written it... but that's what Swift's static type checking forces me to do... Design my app and it's data model at the same time. Call me a lazy software hippie I guess.
- pjmlp 8y agoLong time ago, people also built houses based on piling stuff on top of each other, nowadays an architect has to certify the construction plan.
- flipgimble 8y ago> Swift really does not support quickly iterating on a design. I find the opposite to be the case. You assume that compile errors are a net negative for speed of development and expressivity. Instead I find that the compiler reminds me upfront of all the places I would need to update anyway in due time. In a dynamic language those inconsistencies would be found hours/days later and usually after lengthy debugging. Instead I find myself making large sweeping changes in the design very frequently, because I trust the compiler to warn of any logical inconsistencies. You have to admit at that this point it boils down to subjective preference. You sound averse to the swift style of doing the right thing up front, and using the compiler to help you stay consistent. I personally tired of the hidden and unacknowledged costs of unsafe language, and compilers that allow your design to degenerate into an unmaintainable ball of mud over time. I'm ok with swift being an acquired taste and a technical advantage of folks who get it.
- kitsunesoba 8y agoThis has been my experience as well. With Swift I’ve pulled off several large shifts/refactors that I wouldn’t have even considered risking with Obj-C. My Swift code is much further iterated than my Obj-C code.
- slavapestov 8y ago> Realized you need another enum case? You can't compile again until you touch all your switches. Protocol would be more expressive with an associated type? Stop what you're doing and write some type eraser boilerplate. Function needs to signal an error condition? Try/do/catch anywhere you call it, right now, before you run again. Need to put another type into that array? Write a new protocol and add some conformances. Changing a interface as you work in Swift immediately creates a sea of red marks, which hinders the ability to experiment. With the exception of the associated types thing which is a language limitation that would be nice to see resolved eventually, the others can be resolved with a combination of automatic refactoring (add new enum cases, etc) and a compiler mode where type errors compile down to runtime traps without preventing you from running the program. (And faster compilation in general would help as well!) These are both non-trivial to design and implement well, but I think it’s a good future direction for statically typed languages that will give them many of the benefits of dynamic languages during the prototyping phase.
- wool_gather 8y ago> a compiler mode where type errors compile down to runtime traps without preventing you from running the program Absolutely, something like this would be perfect. I like being able to leverage the compiler in preventing runtime errors...just not necessarily all at once, right up front. Allowing some strictness to be dialed back in debug builds would be a very nice feature.
- blub 8y agoThere's a high likelyhood that if you have unhandled enums and uncaught exceptions after a refactoring, the code is subtly broken. In C++ -Wswitch is a valuable tool to find the former, but there is no way to find the latter. This makes writing correct exception handling code much much harder, so having Swift's strict behaviour would be great from my perspective! It sounds to me that you want to use a few days of exploratory coding to save a few hours of design work. If this type of exploration is needed, then it could be done in another language which supports it and then when the design is in decent shape it can be ported to Swift. Swift is not detrimental to the correctness of the business logic. It offers you a bedrock at the type sustem level on which to build that.