Host Kernel: rawhide 4.13.0-0.rc6.git4.2.fc28.x86_64 (on Fedora 24)
QEMU is mainline built from sources: QEMU emulator version 2.10.50 (v2.10.0-105-g223cd0e)
Guest: clear-17460-kvm.img (which has vsock support)
It's now here, in The Programmer's Compendium. The content is the same as before, but being part of the compendium means that it's actively maintained.
State machines are everywhere in interactive systems, but they're rarely defined clearly and explicitly. Given some big blob of code including implicit state machines, which transitions are possible and under what conditions? What effects take place on what transitions?
There are existing design patterns for state machines, but all the patterns I've seen complect side effects with the structure of the state machine itself. Instances of these patterns are difficult to test without mocking, and they end up with more dependencies. Worse, the classic patterns compose poorly: hierarchical state machines are typically not straightforward extensions. The functional programming world has solutions, but they don't transpose neatly enough to be broadly usable in mainstream languages.
Here I present a composable pattern for pure state machiness with effects,
In this gist I would like to describe an idea for GraphQL subscriptions. It was inspired by conversations about subscriptions in the GraphQL slack channel and different GH issues, like #89 and #411.
At the moment GraphQL allows 2 types of queries:
query
mutation
Reference implementation also adds the third type: subscription
. It does not have any semantics yet, so here I would like to propose one possible semantics interpretation and the reasoning behind it.
When Swift was first announced, I was gratified to see that one of the (few) philosophies that it shared with Objective-C was that exceptions should not be used for control flow, only for highlighting fatal programming errors at development time.
So it came as a surprise to me when Swift 2 brought (What appeared to be) traditional exception handling to the language.
Similarly surprised were the functional Swift programmers, who had put their faith in the Haskell-style approach to error handling, where every function returns an enum (or monad, if you like) containing either a valid result or an error. This seemed like a natural fit for Swift, so why did Apple instead opt for a solution originally designed for clumsy imperative languages?
I'm going to cover three things in this post:
Your goals are to reduce the number of things that you have to keep in your head at any given moment, and to rely as little as possible on your own ability to consistently do things right. | |
If you make a thing immutable ('let' in swift), you never have to think about what happens if it changes, or what other parts of the code you'll effect if you change it. | |
If you split complex functions into several smaller functions that only interact by passing arguments or getting return values, then you limit the amount of code you need to consider when hunting for a bug, and you can test each small piece separately. | |
If you understand what things must be true in your code (aka invariants, for example "a person's age must be greater than 0"), and either provide no function that can cause them to be untrue, or check and crash immediately when they're untrue, then you don't have to debug issues caused by incorrect assumptions. | |
If you remove possibilities (for example, Swift removes the possibility of things being nil unless |
struct User { | |
let id: Int | |
let name: String | |
let email: String? | |
} | |
extension User: JSONDecodable { | |
static func create(id: Int, name: String, email: String?) -> User { | |
return User(id: id, name: name, email: email) | |
} |
/* | |
pipe_source.m | |
clang pipe_source.m -o pipe -framework Foundation -D [ USE_SOURCE | USE_IO | USE_FILEHANDLE [ FILEHANDLE_READABILITY | FILEHANDLE_WAIT ] ] | |
*/ | |
#import <Foundation/Foundation.h> | |
int main(void) { | |
enum RunLoop { |
Copyright 2015 Chris Eidhof | |
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | |
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHE |