         return try optionalAtPath(path, ifNotFound: ifNotFound) { try $0.dictionary() }
     }
 
-    // MARK: Member unpacking with fallback
-
-    private func decodedAtPath<Decoded: JSONDecodable>(path: [PathFragment], @noescape or fallback: () -> Decoded) throws -> Decoded {
-        return try decodedAtPath(path, ifNotFound: true) ?? fallback()
+}
+
+// MARK: - Missing-with-fallback unpacking
+
+extension JSON {
+
+    private func mapOptionalAtPath<Value>(path: [PathFragment], @noescape fallback: () -> Value, @noescape transform: JSON throws -> Value) throws -> Value {
+        return try mapOptionalAtPath(path, ifNotFound: true, transform: transform) ?? fallback()
     }
 
     /// Attempts to decode into the returning type from a path into

    /// - throws: One of the `JSON.Error` cases thrown by `decode(_:or:)`.
    /// - seealso: `JSON.decode(_:or:)`
    public func string(path: PathFragment..., @autoclosure or fallback: () -> Swift.String) throws -> Swift.String {
        return try decodedAtPath(path, or: fallback)
    }

    /// Retrieves a `Bool` from a path into JSON or a fallback if not found.

    /// - throws: One of the `JSON.Error` cases thrown by `decode(_:or:)`.
    /// - seealso: `JSON.decode(_:or:)`
    public func bool(path: PathFragment..., @autoclosure or fallback: () -> Swift.Bool) throws -> Swift.Bool {
        return try mapOptionalAtPath(path, fallback: fallback) { try $0.bool() }
    }

    /// Retrieves a `[JSON]` from a path into JSON or a fallback if not found.
    /// - parameter path: 0 or more `String` or `Int` that subscript the `JSON`
