13

Some languages use a unary plus operator for implicit conversions, such as coercing a string to a number (e.g. Javascript) or casting small number types to an int (e.g. most C-based languages), or to be used when overloading operators.

Since the unary plus is primarily used for hackish purposes like this, and also since F# does not perform automatic widening conversions, I was surprised that F# includes the unary plus.

What adds to my surprise is that Haskell does not have a unary plus operator. Since the F# design was influenced by Haskell, I'm curious as to why it was decided that F# needed a unary plus when Haskell apparently didn't.

Can you give an example of a credible use for the unary plus in F#? If you can't, why is it included in the language at all?

Peter Olson
  • 139,199
  • 49
  • 202
  • 242
  • Just a guess, but it might be for the same reason as in Ruby. http://stackoverflow.com/questions/5680587/whats-the-point-of-unary-plus-operator-in-ruby – Matt Ball Nov 03 '11 at 16:28
  • 2
    Ocaml has an unary plus, named `(~+)`. I don't know what it is for either. – Pascal Cuoq Nov 03 '11 at 16:28
  • 2
    I think all languages have it, and none use it. It is there for symmetry. – Ramon Snir Nov 03 '11 at 16:30
  • @PascalCuoq I looked [here](http://www.csc.villanova.edu/~dmatusze/resources/ocaml/ocaml.html#intops) and it listed a unary negation prefix operator, but not a unary plus operator. I'd like to see a reference that lists it. If you can find one, I'll correct my question. – Peter Olson Nov 03 '11 at 16:31
  • Perhaps more interesting is overloading it doesn't seem to work: `let (~+) n = -n`. `+1` still returns `1`. I _must_ be doing something wrong. – Daniel Nov 03 '11 at 16:34
  • 2
    +1 is not ((~+) 1), but actually the number 1 (it is resolved by the lexer). `+(1)` returns `-1`. – Ramon Snir Nov 03 '11 at 16:36
  • 2
    @PeterOlson: http://caml.inria.fr/pub/docs/manual-ocaml/libref/Pervasives.html -> Integer arithmetic – barti_ddu Nov 03 '11 at 16:37
  • 5
    F# is based on OCaml, and only *influenced* by Haskell. If OCaml has it, it is very reasonable that F# will have it. – Ramon Snir Nov 03 '11 at 16:46
  • @RamonSnir: Ah, thanks. Apparently, inserting a space works too: `+ 1` returns `-1`. – Daniel Nov 03 '11 at 16:46
  • But...why on earth would you ever need to use it in either F# or OCaml? – Peter Olson Nov 03 '11 at 16:49
  • As I said, mostly for symmetry (we do have the `(~-)` operator). I guess also for some special types you'd want it to be overloaded. I'm going to check FAKE, I think they've overloaded it. – Ramon Snir Nov 03 '11 at 16:51
  • @RamonSnir: Some languages _do_ use it, but I would consider them poor uses: http://stackoverflow.com/questions/727516/what-does-the-unary-plus-operator-do/3903114#3903114 – Daniel Nov 03 '11 at 16:52
  • @Daniel That's awful, and won't work on F#. – Ramon Snir Nov 03 '11 at 16:54
  • This comment thread is getting pretty long. Why don't we [move it to chat](http://chat.stackoverflow.com/rooms/4697/why-doesnt-f-have-a-unary-plus-operator) – Peter Olson Nov 03 '11 at 17:03

4 Answers4

2

There is a unary plus operator in standard mathematical notation. Most programming languages have standard math notation as the original influence and motivation for the syntax of arithmetic expressions.

Doug Moen
  • 21
  • 1
2

I'll summarize the extended comments. Possible reasons (until a more authoritative answer is given):

  1. Consistency with OCaml, from which F# is derived (if you're doing something wrong/unnecessary it's best to keep doing it so people know what to expect :-))
  2. Overloading (mostly for custom types)
  3. Symmetry with unary negation
Daniel
  • 47,404
  • 11
  • 101
  • 179
  • 5
    By the same token, we should add a unary "yes" operator to the language to make it symmetric with the unary "not" (`!`) operator. We could further justify the inclusion of the "yes" operator because it would be useful when somebody wants to overload it for their own custom type. – Peter Olson Nov 03 '11 at 17:12
  • 2
    `!` is dereference, not `not`. There is a positive counterpart for the `not` function, and it is called `id`. – Ramon Snir Nov 03 '11 at 17:16
  • 5
    @PeterOlson I would call it the "indeed" operator. "If indeed x equals three..." – zinglon Nov 03 '11 at 17:16
  • I agree with you. Since the only significant use of it I've encountered has been in C, I wonder if it's merely an artifact in most languages. – Daniel Nov 03 '11 at 17:18
  • @RamonSnir: Maybe being a bit pedantic here, but I wouldn't say `not` (`bool -> bool`) and `id` (`'a -> 'a`) are counterparts. – Daniel Nov 03 '11 at 17:19
  • They are symmetric, because (for booleans) `not` returns the opposite (its negative value), while `id` returns the same. `(~+)` for numbers simply returns them, that is `id`. – Ramon Snir Nov 03 '11 at 17:20
  • I said I was being pedantic. :-) If there was a general concept of inversion, which could apply to any type, I would consider it `id`'s counterpart in the strictest sense. But for `bool`s, `id`/`not` does the trick. – Daniel Nov 03 '11 at 17:24
  • 1
    One use case for your points 2 and 3 would be complex numbers, where `+i` looks like quite a natural counterpart to `-i`, even if it is really just the same as `i`. – kvb Nov 03 '11 at 17:25
  • @PeterOlson: If a type overloads `!` to return a Boolean, I think `!!` should behave as a "yes" operator, and a good compiler should interpret `if (!!x) y; else z;` as `if (!x) z; else y;`. – supercat Jan 21 '14 at 00:41
2

F# has two core influences:

  1. OCaml, with which it was originally compatible, and
  2. the CLR, on which it is built.

As has been pointed out, OCaml has a unary plus operator, so from that point of view, it was natural for F# to have one as well.

As for the CLR... To my surprise, the Common Language Specification doesn't specify any requirements for languages to support operator overloading. However, it does specify semantics and naming conventions when the mechanism is used. Still, F# was allowed to opt out of using unary plus, just like C# and VB opted out of support for overloading compound assignment operators (+=, etc.).

The most common .NET languages aside from F# (C#, VB and C++/CLI) do allow it and have a unary plus. So from this point of view as well it would be natural for F# to have support for a unary plus operator.

Jeffrey Sax
  • 10,253
  • 3
  • 29
  • 40
  • "*just like C# and VB opted out of supporting compound assignment*" C# supports compound assignment operators. ;-] – ildjarn Nov 03 '11 at 23:25
  • 3
    Yes, but they don't follow the CLI spec. If you define a `+=` operator in C++/CLI, using `+=` in C# won't call it. In F# it will. – Jeffrey Sax Nov 04 '11 at 00:01
0

According to the this "Used to declare an overload for the unary plus operator."

BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70