Update Examples
parent
c5655f383a
commit
1c2268ff90
66
Examples.md
66
Examples.md
@ -1018,7 +1018,7 @@ Apparently nothing else new in these sections.
|
|||||||
#### Methods
|
#### Methods
|
||||||
Doesn't seem to be anything new here, but ...
|
Doesn't seem to be anything new here, but ...
|
||||||
#### Closures
|
#### Closures
|
||||||
... this one appears to be a biggie. Rust's closure syntax is very unusual, and there's lots of commentary concerning it inline. So this first example block shows perhaps the "ideal" way we would recast it. The thing is, I can't understand why it isn't already this way, so maybe we are going to run into parsing problems? If so, we may need to revisit the syntax here.
|
... this one appears to be a biggie. Rust's closure syntax is very unusual, and there's lots of commentary concerning it online. So this first example block shows perhaps the "ideal" way we would recast it. The thing is, I can't understand why it isn't already this way, so maybe we are going to run into parsing problems? If so, we may need to revisit the syntax here.
|
||||||
|
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
@ -1061,13 +1061,11 @@ fn main
|
|||||||
//println! "cannot reuse closure_inferred with another type: {}", closure_inferred 42i64
|
//println! "cannot reuse closure_inferred with another type: {}", closure_inferred 42i64
|
||||||
// TODO: uncomment the line above and see the compiler error.
|
// TODO: uncomment the line above and see the compiler error.
|
||||||
|
|
||||||
let one = => 1
|
let one = () => 1 //! Need something to mark empty param list, could use || like Rust...
|
||||||
println! "closure returning one: {}", one()
|
println! "closure returning one: {}", one()
|
||||||
|
|
||||||
```
|
```
|
||||||
</td></tr></table>
|
</td></tr></table>
|
||||||
|
Another consideration is whether we want to have a shorthand for non-closure anonymous inline functions (i.e. ones that are enforced not to capture any identifiers). If so, the simplest mechanism might just be to use another arrow, i.e. Husht could look like:
|
||||||
The other big consideration is whether we want to have a shorthand for non-closure anonymous inline functions (i.e. ones that are enforced not to capture any identifiers). If so, the simplest mechanism might just be to use another arrow, i.e. Husht could look like:
|
|
||||||
```
|
```
|
||||||
fn main
|
fn main
|
||||||
let anon_func = x --> x*x
|
let anon_func = x --> x*x
|
||||||
@ -1081,6 +1079,8 @@ fn main
|
|||||||
```
|
```
|
||||||
Of course, there's no real reason to implement that until/unless we actually want anonymous regular (non-closure) functions.
|
Of course, there's no real reason to implement that until/unless we actually want anonymous regular (non-closure) functions.
|
||||||
|
|
||||||
|
A final, quite major consideration is whether we want to have syntax for unary single-expression functions parallel to that in [Civet](https://civet.dev/reference#single-argument-function-shorthand). The `&` symbol would not be appropriate for Husht, but a good choice might be `$` since as far as I can tell, it's not used otherwise in Rust except for macro arguments, and it is the conventional "single parameter name for a throwaway unary function" in JavaScript. So in this scheme, `closure_inferred` above would become just `$ + outer_var`. Not sure what would be a good way to type-annotate this, possibly `($i32 + outer_var): i32` or maybe there just is no type-annotated single-argument shorthand. And we would have `let square = $ * $` as a shorthand for `let square = x => x*x`. This notation seems so productive that I am just going to presume we want to implement it, and write the rest of the examples in this section in this way when possible.
|
||||||
|
|
||||||
##### Capturing
|
##### Capturing
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
@ -1117,7 +1117,7 @@ fn main() {
|
|||||||
fn main
|
fn main
|
||||||
use std::mem
|
use std::mem
|
||||||
|
|
||||||
let consume = =>
|
let consume = () =>
|
||||||
println! "`movable`: {:?}", movable
|
println! "`movable`: {:?}", movable
|
||||||
mem::drop movable
|
mem::drop movable
|
||||||
|
|
||||||
@ -1190,8 +1190,10 @@ fn main
|
|||||||
vec2 = vec![4, 5, 6]
|
vec2 = vec![4, 5, 6]
|
||||||
|
|
||||||
//! Note use of fragment of loop construct to just get the corresponding iterator
|
//! Note use of fragment of loop construct to just get the corresponding iterator
|
||||||
println! "2 in vec1: {}", &in vec1.any &x => x == 2
|
println! "2 in vec1: {}", &in vec1.any *$ == 2 //! since iterator ...
|
||||||
println! "2 in vec2: {}", in vec2.any x => x == 2
|
//! ... returns references, we have to dereference the argument.
|
||||||
|
//! Alternatively , we could write `$ == &2`
|
||||||
|
println! "2 in vec2: {}", in vec2.any $ == 2
|
||||||
|
|
||||||
println! "vec1 len: {}", vec1.len()
|
println! "vec1 len: {}", vec1.len()
|
||||||
println! "First element of vec1 is: {}", vec1[0]
|
println! "First element of vec1 is: {}", vec1[0]
|
||||||
@ -1200,8 +1202,8 @@ fn main
|
|||||||
let array1 = [1, 2, 3]
|
let array1 = [1, 2, 3]
|
||||||
array2 = [4, 5, 6]
|
array2 = [4, 5, 6]
|
||||||
|
|
||||||
println! "2 in array1: {}", &in array1.any &x => x == 2
|
println! "2 in array1: {}", &in array1.any $ == &2
|
||||||
println!("2 in array2: {}", in array2.any x => x == 2
|
println!("2 in array2: {}", in array2.any $ == 2
|
||||||
|
|
||||||
```
|
```
|
||||||
</td></tr></table>
|
</td></tr></table>
|
||||||
@ -1217,11 +1219,55 @@ fn main
|
|||||||
<td>
|
<td>
|
||||||
|
|
||||||
```
|
```
|
||||||
|
pub trait Iterator {
|
||||||
|
type Item;
|
||||||
|
|
||||||
|
fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
|
||||||
|
P: FnMut(&Self::Item) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let vec1 = vec![1, 2, 3];
|
||||||
|
let vec2 = vec![4, 5, 6];
|
||||||
|
|
||||||
|
let mut iter = vec1.iter();
|
||||||
|
let mut into_iter = vec2.into_iter();
|
||||||
|
|
||||||
|
println!("Find 2 in vec1: {:?}", iter .find(|&&x| x == 2));
|
||||||
|
println!("Find 2 in vec2: {:?}", into_iter.find(| &x| x == 2));
|
||||||
|
|
||||||
|
let array1 = [1, 2, 3];
|
||||||
|
let array2 = [4, 5, 6];
|
||||||
|
|
||||||
|
println!("Find 2 in array1: {:?}", array1.iter() .find(|&&x| x == 2));
|
||||||
|
println!("Find 2 in array2: {:?}", array2.into_iter().find(|&x| x == 2));
|
||||||
|
}
|
||||||
```
|
```
|
||||||
</td><td>
|
</td><td>
|
||||||
|
|
||||||
```
|
```
|
||||||
|
pub trait Iterator
|
||||||
|
type Item
|
||||||
|
|
||||||
|
fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
|
||||||
|
P: FnMut(&Self::Item) -> bool
|
||||||
|
//! Again, sh/could we allow both `Self::` to be elided?
|
||||||
|
|
||||||
|
fn main
|
||||||
|
let vec1 = vec![1, 2, 3]
|
||||||
|
let vec2 = vec![4, 5, 6]
|
||||||
|
|
||||||
|
let mut iter = &in vec1
|
||||||
|
let mut into_iter = in vec2
|
||||||
|
|
||||||
|
println! "Find 2 in vec1: {:?}", iter .find *$ == &2
|
||||||
|
println!("Find 2 in vec2: {:?}", into_iter.find *$ == 2
|
||||||
|
|
||||||
|
let array1 = [1, 2, 3];
|
||||||
|
let array2 = [4, 5, 6];
|
||||||
|
|
||||||
|
println!("Find 2 in array1: {:?}", &in array1.find *$ == &2
|
||||||
|
println!("Find 2 in array2: {:?}", in array2.find *$ == 2
|
||||||
|
|
||||||
```
|
```
|
||||||
</td></tr></table>
|
</td></tr></table>
|
||||||
|
Loading…
Reference in New Issue
Block a user