> On Mar 22, 2017, at 10:09 AM, Matthew Johnson <matt...@anandabits.com> wrote:
>
>>
>> On Mar 22, 2017, at 12:03 PM, Joe Groff via swift-evolution
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>
>>
>>> On Mar 6, 2017, at 4:20 PM, Elijah Johnson via swift-evolution
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>
>>> Hi,
>>>
>>> I’ve been recently considering Swift on the server-side, and there came up
>>> the question, “what happens when a null optional is forcibly unwrapped?”
>>> and the answer was clearly that not only would the request crash, but the
>>> entire server would also crash, since the server itself is/would be also
>>> written in Swift.
>>>
>>> I think that this highlights serveral weaknesses in Swift’s “null safety”
>>> attempts. The first is that there needs to be a way to isolate blocks of
>>> code so that a “null pointer exception” does not crash the system. I think
>>> it is fair to say, in the language of Java, that these are really “runtime
>>> exceptions” and for some reason are being treated as segmentation faults
>>> would be in C/C++. In my opinion, the existence of these things has the
>>> ability to bring Swift down below Java and closer to an unamanged language.
>>> Not really sure why it would ever be desireable, but in terms of
>>> server-side programming, it is definitely a serious issue.
>>>
>>> Secondly, Swift’s “null safety” is really completely undermined by these
>>> “force-unwrap” errors. I agree with the usage of new language features like
>>> guard, optional binding, etc to remove a null value, but I see this
>>> force-unwrap as extremely pervasive for a lot of reasons:
>>>
>>> 1. When porting code from a C style language to Swift, force-unwrap is
>>> needed to make the code work without refractoring.
>>> 2. XCode itself reccomends this operator and when it is used to satisfy a
>>> requirement, then it can be left in the code
>>> 3. Some styles of coding just can’t work without force-unwrap.
>>>
>>> I don’t think the logic of making the consequences extreme for making a
>>> mistake are a rational for making better coders. In fact, I personally see
>>> the “force-unwrap” operator having very great potential usage as a
>>> deliberate assertion exception - the programmer demands that a certain
>>> value be non-null for execution to continue, only there should be a proper
>>> scope and context where these exceptions can propogate to. On debug modes,
>>> one might want it to pause on the line, but for other uses, it should be
>>> caught IMO - on regular code by the user, and inside dispatch blocks by the
>>> queue itself. For a multithreaded app or server to exit, the user should
>>> have to explicitly write exit(0), isn’t this the goal of a managed
>>> language? Maybe in some cases, Apple will want the program to crash, but if
>>> Swift is given an audience not just with Apple hardware, then it should
>>> have more flexibility IMO.
>>
>> The long-term vision here is to have some form of finer-grained fault
>> isolation ("actors" being the buzzword for that we tend to throw around). As
>> others noted, using `!` is intended to indicate that it is *impossible* for
>> a value to be nil at a certain point, and that the programmers screwed up if
>> the value is nil at that point. The only safe thing to do in a situation the
>> programmers didn't plan for is stop execution; anything else is just going
>> to lead to harder-to-debug, potentially-exploitable inconsistencies further
>> removed from the original problem. With actors, it could become possible for
>> that crash to only take down an isolated subprogram, and give a supervisor
>> subprogram an opportunity to gracefully wind down the process—on clients,
>> this might mean saving application state so that the app can be cleanly
>> restarted, and on the server, this might mean closing the process's accept
>> socket but still letting existing requests complete before restarting the
>> potentially-compromised process. There's still a tradeoff here from a
>> defense-in-depth standpoint, since any requests running in the same process
>> have the potential to corrupt each other's state. Swift's crash-early design
>> hopes to minimize the opportunity for corruption to leak.
>
> Wouldn’t it also be possible to support isolated execution contexts which can
> be statically verified to only mutate state that no other part of the process
> can see? This would allow the process itself (and other execution contexts
> in the process) to continue running without risk of corrupted state. This
> seems like an approach that would work well for server processes that can
> handle requests in isolation.
That would be the ideal. Any channel of communication, including a crash
signal, is still a potential vector for attack against a weak supervisor,
depending on how flexible that channel is. It's certainly much less likely for
this form of corruption to occur in a well-isolated runtime model with
regulated communication channels among components, and in practice there will
hopefully be off-the-shelf runtimes you can plug in to.
-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution