[Grace-core] In praise of consistency

Kim Bruce kim at cs.pomona.edu
Thu May 17 18:03:38 PDT 2012


My philosophy has always been that any syntax that could reasonably be interpreted in two different (reasonable) ways should be ruled out.  This is based on the fact that if there are two interpretations, some people will hold each and I would rather they be informed that they should add extra syntax to resolve the ambiguity than have a default interpretation hold that might be false.

The prime example of this is C/Java conditionals with else:

if (cond1)
         if (cond2) 
               stat1
     else
            stat2

While I've carefully indented it ambiguously, one could make the case for the else being associated with either of the two "if" statements.  (The Java/C rule is that it goes with the closest if)

We avoid that by requiring {} around all code blocks, forcing an explicit matching of else with one of the two.

We did have the earlier discussion about this ambiguity with mixfix method names, and did decide that non-delimited parameters must be delimited by parentheses.  However, given my students' experiences, I'd rather restrict the notion of delimited parameters to only include those already syntactically surrounded by curly brackets.  I'm uncomfortable with allowing either literals (like 7) or quote-delimited strings.  If we banned those then there would be a very simple error message when the parens are left out that simply say that parens must be added.  No weird messages about undefined method names.

Kim



On May 17, 2012, at 5:11 PM, Andrew P. Black wrote:

> I've been playing with James' example
> 
> 	print "hello".reversed on output.mainStream
> 
> This _looks_ ambiguous to me:  I though that it meant
> 
> 	request method print()on()								(1)
> 	from (implicit) receiver self
> 	with arg1 = "hello".reversed
> 	and agr2 = output.mainStream
> 
> whereas my parser thought that it meant 
> 
> 	request method print()									(2)
> 	from (implicit) receiver self
> 	with arg1 = (
> 			request method reversed()
> 			from receiver "hello"
> 			with arg1 = (
> 					request method on()
> 					from (implicit) receiver self 
> 					with arg1 = output.mainStream
> 			)
> 	)
> 
> 
> So, the rule I proposed in today's meeting — that we require parenthesis whenever there is an ambiguity — would require parens, right?  And that would solve the problem, right.  Unfortunately, no.
> 
> The problem is that while it's easy to come up with a parenthesisation for the second interpretation:
> 
> 	print ( "hello".reversed on output.mainStream ) ,
> 
> I can't see a way of adding parenthesis that will make it mean the first.
> 
> Putting parens around the whole thing
> 
> 	( print "hello".reversed on output.mainStream )
> 
> obviously doesn't help.
> 
> My parser does actually do interpretation (1) with
> 
> 	print ("hello".reversed) on (output.mainStream)
> 
> but someone who does not know the rule that method names go on as long as possible could still miss-parse it.
> 
> The ambiguity is whether method names are as long as possible or as short as possible.   I thought that my grammar attempted to make them as long as possible, but I clearly got it wrong.
> 
> I don't see a solution other than telling students that "method names go on as long as possible".
> 
> 	Andrew
> 
> 
> 
> 
> 



More information about the Grace-core mailing list