Apply Jade's feedback
Signed-off-by: Danila Fedorin <daniel.fedorin@hpe.com>
This commit is contained in:
parent
0c4129337a
commit
86f1ba686a
@ -80,7 +80,7 @@ I can think of another language that has pure functions...
|
|||||||
|
|
||||||
# Programming in Haskell
|
# Programming in Haskell
|
||||||
|
|
||||||
Without mutability and loops, Haskell programmers use pattern-matching and recursion to express their algorithms.
|
Without mutability and loops, (purely) functional programmers use pattern-matching and recursion to express their algorithms.
|
||||||
|
|
||||||
* Data structures are defined by enumerating their possible cases. A list is either empty, or a head element followed by a tail list.
|
* Data structures are defined by enumerating their possible cases. A list is either empty, or a head element followed by a tail list.
|
||||||
|
|
||||||
@ -481,7 +481,7 @@ record _cons {
|
|||||||
# Extracting Types from Format Strings
|
# Extracting Types from Format Strings
|
||||||
|
|
||||||
```Chapel
|
```Chapel
|
||||||
proc specifiers(param s: string, param i: int) type {
|
proc specifiers(param s: string, param i: int = 0) type {
|
||||||
if i >= s.size then return _nil;
|
if i >= s.size then return _nil;
|
||||||
|
|
||||||
if s[i] == "%" {
|
if s[i] == "%" {
|
||||||
@ -509,7 +509,7 @@ proc specifiers(param s: string, param i: int) type {
|
|||||||
Let's give it a quick try:
|
Let's give it a quick try:
|
||||||
|
|
||||||
```Chapel
|
```Chapel
|
||||||
writeln(specifiers("Hello, %s! Your ChapelCon submission is #%i\n", 0) : string);
|
writeln(specifiers("Hello, %s! Your ChapelCon submission is #%i\n") : string);
|
||||||
```
|
```
|
||||||
|
|
||||||
The above prints:
|
The above prints:
|
||||||
@ -550,16 +550,16 @@ _cons(string,"a string",_cons(int(64),"a signed integer",_nil))
|
|||||||
* To support the empty-specifier case (Chapel varargs don't allow zero arguments):
|
* To support the empty-specifier case (Chapel varargs don't allow zero arguments):
|
||||||
|
|
||||||
```Chapel
|
```Chapel
|
||||||
proc fprintln(param format: string) where specifiers(format, 0).length == 0 {
|
proc fprintln(param format: string) where specifiers(format).length == 0 {
|
||||||
writeln(format);
|
writeln(format);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
* If we do have type specifiers, to ensure our earlier assumption of `size` matching:
|
* If we do have type specifiers, to ensure our earlier assumption of `size` matching:
|
||||||
```Chapel
|
```Chapel
|
||||||
proc fprintln(param format: string, args...)
|
proc fprintln(param format: string, args...)
|
||||||
where specifiers(format, 0).length != args.size {
|
where specifiers(format).length != args.size {
|
||||||
compilerError("'fprintln' with this format string expects " +
|
compilerError("'fprintln' with this format string expects " +
|
||||||
specifiers(format, 0).length : string +
|
specifiers(format).length : string +
|
||||||
" argument(s) but got " + args.size : string);
|
" argument(s) but got " + args.size : string);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -572,7 +572,7 @@ _cons(string,"a string",_cons(int(64),"a signed integer",_nil))
|
|||||||
|
|
||||||
```Chapel
|
```Chapel
|
||||||
proc fprintln(param format: string, args...) {
|
proc fprintln(param format: string, args...) {
|
||||||
validate(specifiers(format, 0), args.type, 0);
|
validate(specifiers(format), args.type, 0);
|
||||||
|
|
||||||
writef(format + "\n", (...args));
|
writef(format + "\n", (...args));
|
||||||
}
|
}
|
||||||
@ -707,7 +707,7 @@ For any two types, the _disjoint union_ of these two types defines values that a
|
|||||||
* We can build up more complex types by combining these two operations.
|
* We can build up more complex types by combining these two operations.
|
||||||
* Need a triple of types $A$, $B$, and $C$? Use $A \times (B \times C)$.
|
* Need a triple of types $A$, $B$, and $C$? Use $A \times (B \times C)$.
|
||||||
* Similarly, "any one of three types" can be expressed as $A + (B + C)$.
|
* Similarly, "any one of three types" can be expressed as $A + (B + C)$.
|
||||||
* A `Result<T>` type (in Rust, or `optional<T>` in C++) is $T + \text{Unit}$.
|
* A `Option<T>` type (in Rust, or `optional<T>` in C++) is $T + \text{Unit}$.
|
||||||
* `Unit` is a type with a single value (there's only one `None` / `std::nullopt`).
|
* `Unit` is a type with a single value (there's only one `None` / `std::nullopt`).
|
||||||
|
|
||||||
* Notice that in Chapel, we moved up one level
|
* Notice that in Chapel, we moved up one level
|
||||||
@ -745,7 +745,7 @@ For any two types, the _disjoint union_ of these two types defines values that a
|
|||||||
</div>
|
</div>
|
||||||
* So, we can't enforce that the user doesn't pass `int` to our `length` function defined on lists.
|
* So, we can't enforce that the user doesn't pass `int` to our `length` function defined on lists.
|
||||||
* We also can't enforce that `InL` is instantiated with the right type.
|
* We also can't enforce that `InL` is instantiated with the right type.
|
||||||
* So, we lose some safety compare to Haskell...
|
* So, we lose some safety compared to Haskell...
|
||||||
* ...but we're getting the compiler to do arbitrary computations for us at compile-time.
|
* ...but we're getting the compiler to do arbitrary computations for us at compile-time.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
Loading…
Reference in New Issue
Block a user