diff --git a/Examples.md b/Examples.md index a79d50c..0c34866 100644 --- a/Examples.md +++ b/Examples.md @@ -1018,7 +1018,7 @@ Apparently nothing else new in these sections. #### Methods Doesn't seem to be anything new here, but ... #### 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. @@ -1061,13 +1061,11 @@ fn main //println! "cannot reuse closure_inferred with another type: {}", closure_inferred 42i64 // 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() - ```
- -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: +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: ``` fn main 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. +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 @@ -1117,7 +1117,7 @@ fn main() { fn main use std::mem - let consume = => + let consume = () => println! "`movable`: {:?}", movable mem::drop movable @@ -1190,8 +1190,10 @@ fn main vec2 = vec![4, 5, 6] //! 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 vec2: {}", in vec2.any x => x == 2 + println! "2 in vec1: {}", &in vec1.any *$ == 2 //! since iterator ... + //! ... 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! "First element of vec1 is: {}", vec1[0] @@ -1200,8 +1202,8 @@ fn main let array1 = [1, 2, 3] array2 = [4, 5, 6] - println! "2 in array1: {}", &in array1.any &x => x == 2 - println!("2 in array2: {}", in array2.any x => x == 2 + println! "2 in array1: {}", &in array1.any $ == &2 + println!("2 in array2: {}", in array2.any $ == 2 ```
@@ -1217,11 +1219,55 @@ fn main ``` +pub trait Iterator { + type Item; + fn find

(&mut self, predicate: P) -> Option 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)); +} ``` ``` +pub trait Iterator + type Item + + fn find

(&mut self, predicate: P) -> Option 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 ```