class X {
var own HashMap<Int, Int> cache
= HashMap new.
public doThing: Int i -> Int {
(cache at: i)
ifSome: { hit => ^hit. }
ifNone: {
// …
cache at: i put: value.
^value.
}
}
}
```
class X {
var own HashMap<Int, Int> cache
= HashMap new.
public doThing: Int i -> Int {
(cache at: i)
ifSome: { hit => ^hit. }
ifNone: {
// …
cache at: i put: value.
^value.
}
}
}
```
The primary use-case is owning internal instance variables, making sure that query results are non-stale until we're ready to mutate.
The primary use-case is owning internal instance variables, making sure that query results are non-stale until we're ready to mutate.
But if the message type is determined to require an `own X`, e.g. if the receiver method has that type annotation, then `myX` moves.
But if the message type is determined to require an `own X`, e.g. if the receiver method has that type annotation, then `myX` moves.
```
let own X myX = X new.
```
```
let own X myX = X new.
```
Consider the common pattern of querying an object, then mutating it based on the result; this is now completely vulnerable to a race condition, the data structure being an actor.
Consider the common pattern of querying an object, then mutating it based on the result; this is now completely vulnerable to a race condition, the data structure being an actor.
```
class LogAll<o> {
var o inner.
// Constructor!
init new: inner.
<o<- m> (m message) -> o (m) {
// log message
let reply = inner (message).
// log reply
^reply
}
}
```
```
class LogAll<o> {
var o inner.
// Constructor!
init new: inner.
<o<- m> (m message) -> o (m) {
// log message
let reply = inner (message).
// log reply
^reply
}
}
```
interface Identity<a> {
// For all types m being valid
// messages to a, sending m
// to this object returns the
// reply that a would give for m.
<a<- m> (m) -> a (m).
}
```
Useful? Not really, but it highlights how these features compose.
interface Identity<a> {
// For all types m being valid
// messages to a, sending m
// to this object returns the
// reply that a would give for m.
<a<- m> (m) -> a (m).
}
```
Useful? Not really, but it highlights how these features compose.
By using the `<-` type operator, we can extract from a type the union of all valid messages that can be send to a type.
```
interface X { x -> String. (Int) -> Int }
type M = X<-. // #x | Int
```
By using the `<-` type operator, we can extract from a type the union of all valid messages that can be send to a type.
```
interface X { x -> String. (Int) -> Int }
type M = X<-. // #x | Int
```
```
interface X { (Int) -> Y. (String) -> Z }
type Y2 = X (Int).
type Z2 = X (String).
```
```
interface X { (Int) -> Y. (String) -> Z }
type Y2 = X (Int).
type Z2 = X (String).
```
Handling a message is equivalent to a pattern match on the incoming message.
Handling a message is equivalent to a pattern match on the incoming message.
```
interface MyObject {
handle: String and: Int -> Boolean.
}
let MyObject o = ...
let bool = o handle: "this" and: 42.
```
```
interface MyObject {
handle: String and: Int -> Boolean.
}
let MyObject o = ...
let bool = o handle: "this" and: 42.
```
```
let myMessage = 123.
myObject (myMessage).
```
In expression position, a # can be used to make symbol messages instead:
```
let x = #y.
obj (x).
obj y. // Equivalent
```
```
let myMessage = 123.
myObject (myMessage).
```
In expression position, a # can be used to make symbol messages instead:
```
let x = #y.
obj (x).
obj y. // Equivalent
```
`myObject 123`
means "send the message '123' to 'myObject'".
`myObject 123`
means "send the message '123' to 'myObject'".
`myObject myMessage`
means "send the 'myMessage' message to the object referenced by 'myObject'", and
`myObject arg: 123 arg: 234`
means roughly "send the message 'arg:arg:' with arguments '(123, 234)'"
`myObject myMessage`
means "send the 'myMessage' message to the object referenced by 'myObject'", and
`myObject arg: 123 arg: 234`
means roughly "send the message 'arg:arg:' with arguments '(123, 234)'"