An attempt to deal with the multiple dimensions of projection mutability in Hylo, particularly those raised by slicing.
Right now we have strict coupling between the binding of the receiver of a projection and the properties of what is projected:
| // | |
| // Un-lowered Hylo definitions, mapped to Swift. These are here to | |
| // to help explain the lowered forms that follow. | |
| // | |
| /// All types | |
| protocol _Type { | |
| static var size: Int { get } | |
| static var alignment: Int { get } | |
| } |
| typealias TreePointer = UnsafeMutablePointer<Tree>? | |
| struct Tree { | |
| var left: TreePointer; | |
| var right: TreePointer; | |
| }; | |
| func new_tree(_ left: TreePointer, _ right: TreePointer) -> TreePointer { | |
| let new: TreePointer = UnsafeMutablePointer<Tree>.allocate(capacity: 1); | |
| new!.initialize(to: Tree(left: left, right: right)) |
| func compare<T: Comparable, U>(_ x: T, _ y: U) -> Bool { | |
| return x < (y as! T) | |
| } | |
| extension Collection { | |
| func sortedIfPossible() -> [Element] { | |
| if isEmpty { return []} | |
| if Element.self as Any.Type is any Comparable.Type { |
| protocol NullaryFunction { | |
| associatedtype Result | |
| func callAsFunction() -> Result | |
| } | |
| protocol ExpressionResult { | |
| associatedtype Expression: NullaryFunction where Expression.Result == Self; | |
| } | |
| typealias Expr<T: ExpressionResult> = T.Expression |
| extension RangeReplaceableCollection { | |
| public fun remove<E>(where exclude: [E](Element)->Bool) inout { | |
| let end = end_position() | |
| var i = first(where: exclude) | |
| if i == end { return } | |
| let include = | |
| var j = self[self.position(after: i)...] | |
| .first(where: x => !exclude(x) ) | |
| var k = j |
| // Everything but the slicing-related requirements of Collection | |
| protocol CollectionCore { | |
| associatedtype Element | |
| associatedtype Index | |
| func startIndex() -> Index | |
| func endIndex() -> Index | |
| func index(after i: Index) -> Index |
| // This file demonstrates how memoization might work in the transformation of a `ScopedProgram` into | |
| // a `TypedProgram`, which additionally represents type information. | |
| public struct TypedProgram { | |
| /// The prior representation of the program, without analysis of types. | |
| public let base: ScopedProgram | |
| /// A type. | |
| public struct Type_: Hashable { | |
| let id: Int |
| // Just to give a sense of reality. | |
| struct AST {} | |
| /// The wrapper over a dictionary that maps keys onto non-optional | |
| /// values, expecting them to have already been computed. | |
| struct ImmutablePropertyMap<Key: Hashable, Value> { | |
| let storage: Dictionary<Key, Value> | |
| subscript(k: Key) -> Value { storage[k]! } | |
| } |
| ➜ val git:(interpreter) ✗ swift repl | |
| Welcome to Apple Swift version 5.7.2 (swiftlang-5.7.2.135.5 clang-1400.0.29.51). | |
| Type :help for assistance. | |
| 1> let x = [[1], [2, 3]] | |
| x: [[Int]] = 2 values { | |
| [0] = 1 value { | |
| [0] = 1 | |
| } | |
| [1] = 2 values { |