lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Nov 26, 2010, at 10:14 AM, phlnc8 wrote:

> On Fri, Nov 26, 2010 at 1:02 PM, Erik Lindroos <gliptic@gmail.com> wrote:
>> On Fri, Nov 26, 2010 at 6:54 PM, phlnc8 <phlnc8@gmail.com> wrote:
>>> 
>>> How about
>>>   [ x : x > 3 ]
>>>   [ x, y : x+y, compute_something_else(x,y) ]
>>> 
>>> Syntax (reusing Lua syntax terms):
>>>   '['  parlist ':'  explist ']'
>> 
>> It's hard to parse. For example:
>> { [ x : x > 3 ] = 0 }
>> The meaning of "[ x : x > 3 ]" cannot be determined until the '='. It needs
>> arbitrarily large lookahead.
> 
> You're right! ':' cannot be used to separate arglist and explist ...
> It should be replaced with, eg. '|':
> 
>   [ x | x > 3 ]
>   [ x, y | x+y, compute_something_else(x,y) ]
> 
> Syntax (reusing Lua syntax terms):
>  '['  parlist '|'  explist ']'

That doesn't fix the problem (though it is perhaps an improvement in reducing other sources of syntactic confusion). The problem is that as we're parsing the table constructor, the '[' could either represent an index operation or a function expression and we won't know until several tokens later.

But visually, something like OpenToken parlist `| explist CloseToken seems like the way to go and the problem is that the standard token pairs are all taken leaving a need to invent other token pairs....

	\[ x | x > 3 ] -- Unambiguous since \ has no meaning right now
	^[ x | x > 3 ] -- I haven't checked for ambiguities here
	etc

This involves one more token than \arglist( explist) but it seems more flexible about whitespace and doesn't suffer from being misleading with respect to how multiple return is handled when the expression turns into a function evaluation.

Totally different track...

At the risk of having accusations of Perlishness flung around, there's also the option of just optimizing the single-parameter, single-expression case and introducing a token like $ which essentially turns anything it touches into a function with spreading "contamination":

	$ --> function( x ) return x end
	$ + 1 --> function( x ) return x + 1 end
	( $ + 1 ) * $ --> function( x ) return ( x + 1 ) * x end
	$ - x --> function( y ) return y - x end

This seems viable if one has a parse tree. The grammar remains the same for expressions. It's just that in evaluating the parse tree we need to cope with nodes potentially being $ functions instead of regular expressions. One benefit to this approach for those concerned about slippery slopes is that it probably pushes pretty aggressively for using the existing function syntax for anything complicated whereas some of the other proposals floated on this thread would probably lead people to use them fairly widely in place of the existing syntax. 

Either of these approaches works nicely in the stream processing examples:

	stream
		:map( \[ x | x * x ] )
		:filter( \[ x | x % 2 == 0 ] )

And:

	stream
		:map( $ * $ )
		:filter( $ % 2 == 0 )

And both seem much easier to read than the existing function syntax for these cases once one learns the new syntax. 

Mark