Brian Hulley wrote:
Hi -
Consider the scenario when you want to find a function that returns
the i'th element of an array but all you know is that there is a
module called Data.Array.IArray that will probably have such a
function in it. So you start typing in your program:
let
ith = Data.Array.IArray.
at this point, you'd hope the editor you're using would somehow
display a list of avaliable values exported from Data.Array.IArray
including the indexing function, so you could select it, thus I would
*like* to be able to use the syntax:
let
ith = Data.Array.IArray.(!)
because it's not the user's fault that the person who wrote
Data.Array.IArray decided to use a symbol instead of an identifier for
this function - the user of Data.Array.IArray in this case just wants
to see normal identifiers to use with prefix application so the use of
(!) at this point effectively gets rid of the unwanted operatorness
associated with the function.
This is a nice argument
However the current syntax of Haskell would not allow this. Instead
you have to write:
let
ith = (Data.Array.IArray.!)
The problem is that the user of Data.Array.IArray has to know already
in advance, before typing the 'D' of "Data", that the indexing
function has been named with a symbol instead of an identifier, but
this knowledge is only available later, when the user has typed the
'.' after "IArray", so the current syntax would be frustrating for the
user because the user then has to go all the way back and insert an
opening paren before the 'D'.
Also, consider the appearance of:
let
ith = (Data.Array.IArray.!) arr i
b = Data.Array.IArray.bounds arr
vs
let
ith = Data.Array.IArray.(!) arr i
b = Data.Array.IArray.bounds arr
I'm not sure if I've managed to explain this problem clearly enough,
but my proposal is that we might consider changing the lexical syntax
of Haskell as follows:
varId ::= id
varOp ::= symbol
varIdOp ::= ` varId
varOpId ::= ( varOp )
varOpIdOp ::= ` varOpId
qvarId ::= {conId .}+ varId -- { }+ denotes 1 or more times
qvarIdOp ::= ` qvarId
qvarOp ::= {conId .}+ varOp
qvarOpId ::= {conId .}+ varOpId
qvarOpIdOp ::= `qvarOpId
In other words, to turn an operator symbol into an id, the parentheses
would be put immediately around the symbol (with no spaces since this
is lexical syntax), and to turn an id into an operator the backquote
is put in front of the entire (qualified) id.
Why does the nice argument not apply equally well to infixifying things?
If I think I want to use infix some thing from Data.Array
and start typing
myArr Data.Array.
and find out element access has become "get" while I wasn't looking,
it's not my fault the author of Data.Array decided to use a function
when I was expecting an identifier - Shouldn't I be able to write
myArr Data.Arr.`get` ix
(Also the trailing backquote in the existing syntax is redundant)
The trailing backquote is just as redundant as the trailing close paren
in the syntax for using a symbol as a prefix function and just as
important for my comment on backticks as the closing paren is to your
proposal for sections -
it means it's lexically apparent at least at one side of the identifier
that it's a section/infixification
Brandon
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe