Ticket #4180 (new feature request)

Opened 3 years ago

Last modified 9 months ago

do not consider associativity for unary minus for fixity resolution

Reported by: maeder Owned by:
Priority: low Milestone: 7.6.2
Component: Compiler (Parser) Version: 6.12.3
Keywords: fixity resolution Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Difficulty:
Test Case: Blocked By:
Blocking: Related Tickets:

Description

1. currently an expression "1 + - 1" is rejected, because "1 + (-1)" looks as being bracketed to the right, whereas + and - are left associative. However, no other bracketing is possible, so "1 + - 1" is unambiguous and should not be subject to further fixity resolution.

2. if an infix expressions starts with an unary minus, the associativity should not matter for the unary minus. Why should "- 1 ## 1" be rejected for a right- or non-assoc operator "##"? Precedence alone is sufficient to decide between "(- 1) ## 1" and "- (1 ## 1)". The latter choice is taken for a higher precedence of the infix operator and the former choice should always be taken for an equal or lower precedence as is done for "- 1 + 1", but without looking at associativity!

I'll attach an alternative fixity resolution in the spirit of 10.6 of  http://www.haskell.org/~simonmar/haskell-2010-draft-report-2/haskellch10.html

Attachments

Tok.hs Download (0.9 KB) - added by maeder 3 years ago.
module to be imported
t.txt Download (0.9 KB) - added by maeder 3 years ago.
example input
log.out Download (1.7 KB) - added by maeder 3 years ago.
example output
Fixity.hs Download (1.6 KB) - added by maeder 3 years ago.
improved version for multiple prefix minus
Resolve.hs Download (1.8 KB) - added by maeder 3 years ago.
clearer version that separates prefix from infix resolution

Change History

Changed 3 years ago by maeder

module to be imported

Changed 3 years ago by maeder

example input

Changed 3 years ago by maeder

example output

Changed 3 years ago by maeder

improved version for multiple prefix minus

Changed 3 years ago by simonmar

Once the Haskell prime proposal reaches some stability we should implement it as a GHC extension.

Changed 3 years ago by maeder

clearer version that separates prefix from infix resolution

Changed 3 years ago by maeder

I've added a clearer resolution algorithm.

I don't think the proposal is worth an extra language extension or compiler flag. I rather consider my proposal as a bug fix of the language description (that ghc conformed to), whereas various (all?) other compilers implemented resolution differently.

Changed 3 years ago by maeder

I would rather propose a flag to get the old haskell98 resolution but make the default my proposed improvement.

Changed 3 years ago by simonmar

If we made it the default then we would not be implementing Haskell 2010. That's ok, but we have to document very carefully the ways in which we diverge from the standard, which we do in the User's Guide: http://www.haskell.org/ghc/docs/6.12.2/html/users_guide/bugs-and-infelicities.html#vs-Haskell-defn.

Changed 3 years ago by maeder

I've proposed the improvement for Haskell 2010 (however final the description may be).

Changed 3 years ago by isaacdupree

The current standard+GHC behavior of unary minus in expressions has a quite simple (albeit mind-bending) way to think about it:

Imagine putting a 0 (zero) to the left side of the minus. Then resolve the precedence (possibly leading to an error). Then give an error if the 0 did not become the argument #1 of the now-imaginarily-binary minus.

It's mind-bending, but at least I have a mental model of it. I hope any alternative has two properties:

a) At least as simple a mental model

b) not to *change* the association of any code that compiles both before and after the change (because it seems so easy to accidentally introduce bugs by getting the wrong semantics and not realizing). (Since no treatment of unary-minus is perfect for us all, conservatively sticking to the existing standard has value... yeah this might be controversial.)

To respond to #2 in the ticket-description, I am unsure why "- 1 ## 1" for "infix/infixr 6 ##" should be defined to resolve to "(- 1) ## 1" rather than "- (1 ## 1)" (nor vice versa; I'd rather have an error, and if you-the-coder don't want one, choose a different precedence than 6 for ##). But maybe if it fit in with a mental model...(which I was unable to get by staring at Christian's code, and I didn't investigate further, but someone could propose one)

Changed 3 years ago by maeder

also see  http://hackage.haskell.org/trac/haskell-prime/wiki/PrefixMinusResolution (as positive answer to b)

The "simple mental model" is: "prefix minus applications extend as far to the right as long as infix operators have higher precedence." (This happens in my recent Resolve.hs attachment by resolveNegExpr.) Therefore "- 1 ## 1" should resolve as "(- 1) ## 1", too.

Both attached versions (Fixity.hs and Resolve.hs) resolve identically (and identically to Simon's version  http://darcs.haskell.org/haskell-prime/fixity/resolve.hs, if "guard (prec1 < 6)" is omitted and the constructed precedence for unary minus is increased to 6.5 in "parseNeg (Op "-" 6 Leftfix) rest", which also requires to change "type Prec = Int" to Float.)

Changed 3 years ago by igloo

  • type changed from proposal to feature request
  • component changed from Compiler to Compiler (Parser)
  • milestone set to 6.16.1

Changed 17 months ago by igloo

  • priority changed from normal to low
  • milestone changed from 7.4.1 to 7.6.1

Changed 9 months ago by igloo

  • milestone changed from 7.6.1 to 7.6.2
Note: See TracTickets for help on using tickets.