Hacker News new | ask | show | jobs
by Animats 3321 days ago
1. If you're going to make indentation significant, implement it in a way that makes tab/space confusion impossible. Python 2.7 does this. The check for indent ambiguity between two strings is:

- Remove the common leading whitespace of both strings.

- The remaining parts of both strings must be all tabs, all spaces, or empty.

This is the least restrictive rule which catches all indent ambiguities.

2. Indent-based syntax is great for imperative languages, but not so good for functional languages with very long expressions. It's not clear how to indent stuff like "a.b(x).c(y).d.e(z)", where a-e x-z may be long expressions. In LISP, the all-parenthesis syntax was so simple, and so hard for humans to parse without help, that indentation was nailed into EMACS and everybody did it that way. The indentation wasn't significant, but it was standardized.

Here's word wrap in Rust:

    s.lines()
            .map(|bline| UnicodeSegmentation::graphemes(bline, true)    // yields vec of graphemes (&str)
                .collect::<Vec<&str>>())
            .map(|line| wordwrapline(&line, maxline, maxword))
            .collect::<Vec<String>>()        
    .join("\n") 
Note that the first "collect" is one level deeper in parentheses than the second one. How would you do that with indentation only?
1 comments

You can get rid of the second map using itertools, which has join for iterators, incidentally.

I feel like you can get rid of the inner one too but forget the right combinator.

Off topic - If only that worked.

    use self::itertools::join;
    use self::itertools::Itertools;
    ....
    s.lines()
        .map(|bline| UnicodeSegmentation::graphemes(bline, true)    
            .collect::<Vec<&str>>())
        .join(|line| wordwrapline(&line, maxline, maxword),"\n")
error[E0061]: this function takes 1 parameter but 2 parameters were supplied.

Rust is picking the wrong version of "join". There's one in Iter with one parameter and one in Itertools with two parameters. Haven't figured out how to get the one from Itertools yet. The obvious syntax, ".Itertools::join(...)" gets "error: expected `<`, found `join`".

Without either function overloading or member function qualification, how do you do this?

    use self::itertools::join;
This is the free function version; leave it out. I haven't tried this myself, but I'd bet that's what's going on; https://docs.rs/itertools/0.5.6/itertools/trait.Itertools.ht... is different from https://docs.rs/itertools/0.5.6/itertools/fn.join.html, though.
You are getting the join from itertools. There's no join on iterators in the standard library, only on &[T] (which is why the collect is needed).

A quick search of itertools docs indicates there's no join method in it that takes two parameters, only a method that takes a &str like the slice one in std, and a freestanding version of it that takes the iterator as the first argument (instead of as the method's self) and the &str as the second.

Based on reading that documentation, I think steve's original comment was meant to say "second collect", not "second map".