Skip to content

Commit aa19cca

Browse files
jemcMatthias Wahl
authored andcommitted
Update tutorial for explicit partial calls. (ponylang#209)
See ponylang/rfcs#82.
1 parent 272dc35 commit aa19cca

14 files changed

Lines changed: 52 additions & 49 deletions

File tree

appendices/examples.md

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -91,21 +91,19 @@ end
9191
## How to access command line arguments
9292
```pony
9393
actor Main
94-
9594
new create(env: Env) =>
9695
// The no of arguments
9796
env.out.print(env.args.size().string())
9897
for value in env.args.values() do
9998
env.out.print(value)
10099
end
101100
// Access the arguments the first one will always be the the appication name
102-
try env.out.print(env.args(0)) end
101+
try env.out.print(env.args(0)?) end
103102
```
104103

105104
## How to use options
106105
```pony
107106
actor Main
108-
109107
new create(env: Env) =>
110108
var options = Options(env)
111109
@@ -195,20 +193,20 @@ fun op_xor(othr: A): A
195193
```pony
196194
class Test
197195
fun alpha() =>
198-
"""
199-
"""
196+
"""
197+
"""
200198
fun beta() =>
201-
"""
202-
"""
199+
"""
200+
"""
203201
```
204202

205203
## How to create Arrays with values
206204

207205
Single values can be separated by semicolon or newline.
208206

209207
```pony
210-
let dice: Array[U32] = [1; 2; 3
211-
4
208+
let dice: Array[U32] = [1; 2; 3
209+
4
212210
5
213211
6
214212
]

appendices/serialisation.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ actor Main
3939
let foo1 = Foo("abc", 123)
4040
4141
// serialisation
42-
let sfoo = Serialised(serialise, foo1)
42+
let sfoo = Serialised(serialise, foo1)?
4343
let bytes_foo: Array[U8] val = sfoo.output(output)
4444
4545
env.out.print("serialised representation is " +
@@ -48,7 +48,7 @@ actor Main
4848
4949
// deserialisation
5050
let dfoo = Serialised.input(input, bytes_foo)
51-
let foo2 = dfoo(deserialise) as Foo
51+
let foo2 = dfoo(deserialise)? as Foo
5252
5353
env.out.print("(foo1 == foo2) is " + (foo1 == foo2).string())
5454
else
@@ -128,8 +128,8 @@ actor Main
128128
let serialise = SerialiseAuth(ambient)
129129
let deserialise = DeserialiseAuth(ambient)
130130
131-
let sx = Serialised(serialise, csw)
132-
let y = sx(deserialise) as CStringWrapper
131+
let sx = Serialised(serialise, csw)?
132+
let y = sx(deserialise)? as CStringWrapper
133133
y.print()
134134
else
135135
env.err.print("there was an error")

c-ffi/c-abi.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,9 @@ actor Main
105105
var random = MT
106106
107107
for i in Range[U64](1, 20) do
108-
let r: U64 = random.next()
109-
let hash = @jch_chash(i, bucket_size)
110-
_env.out.print(i.string() + ": " + hash.string())
108+
let r: U64 = random.next()
109+
let hash = @jch_chash(i, bucket_size)
110+
_env.out.print(i.string() + ": " + hash.string())
111111
end
112112
```
113113

c-ffi/calling-c.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,10 @@ FFI calls to functions that __might__ raise an error __must__ mark it as such by
106106
@os_send[U64](_event, data.cstring(), data.size()) ? // May raise an error
107107
```
108108

109-
If a signature declaration is used then that must be marked as possibly raising an error in the same way. The FFI call site then does not have to mark it as well, although doing so is allowed.
109+
If a signature declaration is used then that must be marked as possibly raising an error in the same way. The FFI call site must mark it as well.
110110

111111
```pony
112112
use @os_send[U64](ev: Event, buf: Pointer[U8] tag, len: U64) ?
113113
114-
@os_send(_event, data.cstring(), data.size()) // May raise an error
114+
@os_send(_event, data.cstring(), data.size())? // May raise an error
115115
```

capabilities/combining-capabilities.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class Foo
3131
3232
class Bar
3333
fun f() =>
34-
var y: Foo trn = getTrnFoo()
34+
var y: Foo trn = get_foo_trn()
3535
var z: String box = y.x
3636
```
3737

capabilities/recovering-capabilities.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,29 +22,29 @@ Here's a more complicated example from the standard library:
2222

2323
```pony
2424
recover
25-
var s = String((prec' + 1).max(width.max(31)))
25+
var s = String((prec + 1).max(width.max(31)))
2626
var value = x
2727
2828
try
2929
if value == 0 then
30-
s.push(table(0))
30+
s.push(table(0)?)
3131
else
3232
while value != 0 do
33-
let index = (value = value / base) - (value * base)
34-
s.push(table(index.usize()))
33+
let index = ((value = value / base) - (value * base))
34+
s.push(table(index.usize())?)
3535
end
3636
end
3737
end
3838
39-
s.append(typestring)
4039
_extend_digits(s, prec')
40+
s.append(typestring)
4141
s.append(prestring)
4242
_pad(s, width, align, fill)
4343
s
4444
end
4545
```
4646

47-
That's from `ToString`. It creates a `String ref`, does a bunch of stuff with it, and finally returns it as a `String iso`.
47+
That's from `format/_FormatInt`. It creates a `String ref`, does a bunch of stuff with it, and finally returns it as a `String iso`.
4848

4949
Both of those examples use the default reference capability for a `recover` expression, since they don't specify one. The default for any mutable reference capability is `iso` and the default for any immutable reference capability is `val`. You can also give an explicit one:
5050

expressions/control-structures.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ You can think of the above example as being equivalent to:
191191
```pony
192192
let iterator = ["Bob"; "Fred"; "Sarah"].values()
193193
while iterator.has_next() do
194-
let name = iterator.next()
194+
let name = iterator.next()?
195195
env.out.print(name)
196196
end
197197
```

expressions/exceptions.md

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ else
1616
end
1717
```
1818

19-
In the above code callA() will always be executed and so will callB(). If the result of callB() is true then we will proceed to callC() in the normal fashion and callD() will not then be executed.
19+
In the above code `callA()` will always be executed and so will `callB()`. If the result of `callB()` is true then we will proceed to `callC()` in the normal fashion and `callD()` will not then be executed.
2020

21-
However, if callB() returns false, then an error will be raised. At this point, execution will stop and the nearest enclosing error handler will be found and executed. In this example that is, our else block and so callD() will be executed.
21+
However, if `callB()` returns false, then an error will be raised. At this point, execution will stop and the nearest enclosing error handler will be found and executed. In this example that is, our else block and so `callD()` will be executed.
2222

2323
In either case, execution will then carry on with whatever code comes after the try `end`.
2424

@@ -28,15 +28,18 @@ If you want to do something that might raise an error, but you don't care if it
2828

2929
```pony
3030
try
31-
call() // May raise an error
31+
// Do something that may raise an error
3232
end
3333
```
3434

3535
__Is there anything my error handler has to do?__ No. If you provide an error handler then it must contain some code, but it is entirely up to you what it does.
3636

37+
__What's the resulting value of a try block?__ The result of a try block is the value of the last statement in the `try` block, or the the value of the last statement in the `else` clause if an error was raised. If an error was raised and there was no `else` clause provided, the result value will be `None`.
38+
39+
3740
## Partial functions
3841

39-
Pony does not require that all errors are handled immediately as in our previous examples. Instead, functions can raise errors that are handled by whatever code calls them. These are called partial functions (this is a mathematical term meaning a function that does not have a defined result for all possible inputs, i.e. arguments). Partial functions __must__ be marked as such in Pony with a `?`.
42+
Pony does not require that all errors are handled immediately as in our previous examples. Instead, functions can raise errors that are handled by whatever code calls them. These are called partial functions (this is a mathematical term meaning a function that does not have a defined result for all possible inputs, i.e. arguments). Partial functions __must__ be marked as such in Pony with a `?`, both in the function signature (after the return type) and at the call site (after the closing parentheses).
4043

4144
For example, a somewhat contrived version of the factorial function that accepts a signed integer will error if given a negative input. It's only partially defined over its valid input type.
4245

@@ -46,12 +49,14 @@ fun factorial(x: I32): I32 ? =>
4649
if x == 0 then
4750
1
4851
else
49-
x * factorial(x - 1)
52+
x * factorial(x - 1)?
5053
end
5154
```
5255

5356
Everywhere that an error can be generated in Pony (an error command, a call to a partial function, or certain built-in language constructs) must appear within a try block or a function that is marked as partial. This is checked at compile time, ensuring that an error cannot escape handling and crash the program.
5457

58+
Prior to Pony 0.16.0, call sites of partial functions were not required to be marked with a '?'. This often led to confusion about the possibilities for control flow when reading code. Having every partial function call site clearly marked makes it very easy for the reader to immediately understand everywhere that a block of code may jump away to the nearest error handler, making the possible control flow paths more obvious and explicit.
59+
5560
## Partial constructors and behaviours
5661

5762
Constructors may also be marked as partial. If a constructor raises an error then the construction is considered to have failed and the object under construction is discarded without ever being returned to the caller.
@@ -124,7 +129,7 @@ The value of a `with` expression is the value of the last expression in the bloc
124129

125130
## Language constructs that can raise errors
126131

127-
The only language construct that can raise an error, other than the error command or calling a partial method, is the `as` command. This converts the given value to the specified type if it can be. If it can't then an error is raised. This means that the `as` command can only be used inside a try block or a partial method.
132+
The only language construct that can raise an error, other than the `error` command or calling a partial method, is the `as` command. This converts the given value to the specified type if it can be. If it can't then an error is raised. This means that the `as` command can only be used inside a try block or a partial method.
128133

129134
## Comparison to exceptions in other languages
130135

expressions/methods.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ fun factorial(x: I32): I32 ? =>
3737
if x == 0 then
3838
1
3939
else
40-
x * factorial(x - 1)
40+
x * factorial(x - 1)?
4141
end
4242
```
4343
The exact requirements to qualify for this optimization depends on the version of the LLVM compiler.

expressions/object-literals.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ actor Main
133133
134134
fun reduce(l: List[U32], acc: U32, f: {(U32, U32): U32} val): U32 =>
135135
try
136-
let acc' = f(acc, l.shift())
136+
let acc' = f(acc, l.shift()?)
137137
reduce(l, acc', f)
138138
else
139139
acc
@@ -159,7 +159,7 @@ actor Main
159159
160160
fun for_each(l: List[String], f: {ref(String)} ref) =>
161161
try
162-
f(l.shift())
162+
f(l.shift()?)
163163
for_each(l, f)
164164
end
165165
```

0 commit comments

Comments
 (0)