Live data from Hacker News

Such a Little Thing: The Semicolon in Rust

lucumr.pocoo.org

61–70 of 81 posts

Re: Such a Little Thing: The Semicolon in Rust

#61
post #52

Earlier quoted context omitted.

No, I meant that Haskell doesn't consider any whitespace that isn't indentation as significant.

Very few languages consider non-indentation whitespace as significant (not counting using whitespace as a token delimiter, which Haskell definitely does, e.g. "foo bar" =/= "foobar").

Ruby and CoffeeScript do and their syntax relies heavily on it.

Re: Such a Little Thing: The Semicolon in Rust

#62
post #47

Earlier quoted context omitted.

There was some discussion about doing this in D, and there was some in C++11, too. I argued that the presence or absence of the ; did not visually stand out very well, and so would be a source of confusion and errors. Hence, ; remained as a statement terminator, and the return keyword served to indicate returning an expression. However, the D lambda syntax does not require a ; when the lambda body consists of only a…

An understandable point of view. Though I can think of an even more crazy variation. Declare the semicolon a binary operator and allow overloading it. As funny as that sounds, Haskell provides something like this, as do-notation can behave differently depending on the monad it is in.

Your post made me check it, and you CAN overload "operator," in C++ apparently :)

http://en.wikibooks.org/wiki/C%2B%2B_Programming/Operators/O...

My mind is blown. You can write bottom-up code in C++ :)

EDIT: no, you still can't the expressions are evaluated first, before calling "operator,"

Re: Such a Little Thing: The Semicolon in Rust

#63
post #47

Earlier quoted context omitted.

There was some discussion about doing this in D, and there was some in C++11, too. I argued that the presence or absence of the ; did not visually stand out very well, and so would be a source of confusion and errors. Hence, ; remained as a statement terminator, and the return keyword served to indicate returning an expression. However, the D lambda syntax does not require a ; when the lambda body consists of only a…

An understandable point of view. Though I can think of an even more crazy variation. Declare the semicolon a binary operator and allow overloading it. As funny as that sounds, Haskell provides something like this, as do-notation can behave differently depending on the monad it is in.

Although everything you say is technically true, readers will tend to get the wrong idea unless we add that (1) most users of the do notation choose Haskell's significant white space rather than semicolons and (2) the (rare) Haskell code that does contain semicolons that behave the way you describe probably also contains semicolons (e.g., in Haskell's let statement and case statement) that have nothing to do with monads or the "sequencing" of side effects.

In other words, the semicolons of Haskell are only tenuously related to semicolons in languages like C.

Re: Such a Little Thing: The Semicolon in Rust

#64
post #53
post #49

Earlier quoted context omitted.

Wouldn't the type system complain that you're returning nil in a function that is not declared/inferred as returning nil?

What if foo() could return nil in some cases?

Then you need an algebraic data type having nil is one of its constructors, and that function returning that type.

AFAIK, Rust doesn't have nil. So, the closest thing is using the option type.

Re: Such a Little Thing: The Semicolon in Rust

#65

Earlier quoted context omitted.

Bug prone? The compiler will inevitably warn you about your error at compile time. No such bug will have any consequence beyond that. This is also not such a big problem when a human reads the function. We can always see at a glance the return type of the function. Either it's explicitly declared, or it's a lambda whose usage is readily visible. Semicolon or not, you can easily guess if the function is supposed to re…

Ok, I misunderstood then. I thought it would subtly return no value instead of a value, and you'd only discover this at run time. That would be bug prone. If it simply generates a compilation error, no problem.

The thing is that in a safe language, a value always evaluates to a value of the type of the expression[1]. E.g. in Haskell, if a function returns a list:

  foo :: Int -> [a]
It should always evaluate to a list. There is no such thing as a null pointer. The only thing that comes close to a nullable type is an option type such as Maybe:

  data Maybe a = Just a | Nothing
The function

  bar :: Int -> Maybe [a]
can either evaluate to a Just [a] or Nothing.

[1] Actually, I lied a bit, since there is bottom: http://www.haskell.org/haskellwiki/Bottom But bottom does not fullfil the same role as, say null pointers.

Re: Such a Little Thing: The Semicolon in Rust

#67
post #52

Earlier quoted context omitted.

Very few languages consider non-indentation whitespace as significant (not counting using whitespace as a token delimiter, which Haskell definitely does, e.g. "foo bar" =/= "foobar").

Ruby and CoffeeScript do and their syntax relies heavily on it.

For Ruby at least "heavily" is a big exaggeration. It is significant as a token separator and in cases where inserting a line break makes the expression up to the line break a valid expression in itself, in which case it is treated as one.

You pretty much only need to remember to separate tokens where lack of whitespace might create a different vald token, and ensure any expressions that you want to let span more than one line ends with something that expects following tokens to make a complete expression.

Personally I can live with that easily. I can not live with significant indentation, on the other hand...

Re: Such a Little Thing: The Semicolon in Rust

#68
post #49

Earlier quoted context omitted.

Ignoring a potentially wanted return value with ";" is a hazard. I'd like to institute some set of "warn-unused-result" warnings in Rust to combat this.

Wouldn't the type system complain that you're returning nil in a function that is not declared/inferred as returning nil?

This is correct for any "normal" (a.k.a. "item level") function, since their signatures must always be explicit. But you're allowed to infer the signatures of closures, which is the only place where this problem could arise.

  // This function lives at the top level of the module, so its types must be annotated
  fn foo(bar: int) -> int {
      // Here's a closure without type annotations:
      let baz = |qux| { qux + 1 };
      // And a closure with type annotations:
      let baz = |qux: int| -> int { qux + 1 };
      // Which means that this would be a compile-time error:
      let baz = |qux: int| -> int { qux + 1; };  // returning nil, but expected int
      // But if you expect this to return int, then there are very few cases where
      // this might not be a compile-time error:
      let baz = |qux| { qux + 1; };
      log(error, baz(bar));  // will print "()", but did you want bar + 1?
      io::println(fmt!("%?", baz(bar)));  // same as previous
      io::println(fmt!("%d", baz(bar)));  // this one *is* a compile-time error
                                          // macros ftw
      baz(bar);  // this will also be a compile-time error
  }

Re: Such a Little Thing: The Semicolon in Rust

#69
post #10

Earlier quoted context omitted.

Hello American. I'm from one of those other pesky countries that make up most of the human population of earth, and which usually have other keyboard layouts. I have to type shift+, to get the semicolon.

A potential workaround is to always use an American keyboard. It's what I do.

Another solution is xmodmap in Unix or some similar tool in Windows to change the keyboard layout. With that solution you don't have to miss the default national keyboard layout.

Re: Such a Little Thing: The Semicolon in Rust

#70
post #53

Earlier quoted context omitted.

What if foo() could return nil in some cases?

Then you need an algebraic data type having nil is one of its constructors, and that function returning that type. AFAIK, Rust doesn't have nil. So, the closest thing is using the option type.

In Rust, nil is the name for the unit type (written as empty parentheses, like "()"), used whenever a function doesn't return anything meaningful. You're correct in that instead of null pointers it has the None variant of the Option enum.
Post reply on HN