[Grace-core] minor language issues

Kim Bruce kim at cs.pomona.edu
Mon May 18 10:01:57 PDT 2015


Kim



> On May 17, 2015, at 10:39 PM, James Noble <kjx at ecs.vuw.ac.nz> wrote:
> 
>> My thoughts, for what they are worth!
> 
> always good! 
> 
> 
>>> - should spaces be required around operators?
>>> e.g. should "1+2" be legal, or should we be required to write "1 + 2".
>>> requiring spaces solves a bunch of issues wrt brackets & generics
>> 
>> No, we should not require spaces, except around < and >
> 
> that's what I originally thought, but I don't like the exceptions for "<" etc.
> I'm slowly coming around to the "all spaces, all the time" position. 

I have mixed feelings.  In the end I lean toward consistency, even though I find it annoying.  Thus spaces around all (though I’d be thrilled to get rid of the spaces requirement and just use [ ] for type parameters).
> 
>>> - should more than statement be permitted on a line?
>>> e.g. should "a;b;c;" be legal, or should we have to break the lines, thus:
>>>  a
>>>  b
>>>  c 
>> 
>> Yes.
> 
> I think so too.

While I would discourage students from doing this, it will be handy for publications, so yes.
> 
>> 
>>> - there's no way to pass *no* varargs parameters. 
>>> given a multi-part method with varargs we can't call then with
>>> no arguments, because "()" is supposed to be illegal.
>> 
>> I think that this is a misapprehension.
> 
> I don't - we've talked about "()" especially being always and everywhere *illegal*.
> so I don't want to lose that.   And I don't like the JS/C/BCPL conventions where
> writing "foo" gets you the reified method for foo, while "foo()" calls it!
> 
>>  A method that takes a variable number of arguments can clearly take zero arguments, and 
>> () is a reasonable way to write them
> 
> well yes, but so is "foo" with no arguments....
> 
>> .   Similarly, a method that  is declared as
>> 
>> 	method  foo(a, b, *c)
>> 
>> can be requested as foo(1, 2), foo(1,2,3), and foo(1,2,3,4) , but not as foo(1).  In foo(1, 2), c is bound to an empty sequence.
> 
> right. 
> 
>> What we agreed was illegal is requesting a method declared as
>> 
>> 	method none { … }
>> 
>> by writing obj.none(), since the method is being given an argument list but has no parameter to bind to it.
> 
> yep, I agree that should be illegal.
> 
>> I see nothing wrong with requesting 
>> 
>> 	method variable(*a) { … }
>> 
>> as obj.variable(), since here the method `variable` is being given a parameter list of length zero which is bound to the sequence argument a.
>> A sequence of length zero is a perfectly respectable operation.
> 
> except it's not really a sequence, and it's yucky...
> 
>> I think that the real question is whether it’s legal to request
>> 
>> 	obj.variable
>> 
>> with no argument list at all.  In general, it’s a mistake to confuse zero with blank space, or an empty collection with no collection.
> 
> jndeed - but again, it's not really a "collection".
> IF we commit to some collection syntax (see notes on bracketing below)
> we could consider removing varargs altogether and just using explicit collections.
> optional method parts could help here too.
> 
>> Why should methods with multiple argument list be different form those with a single argument list?
>> 
>>> e.g. x.foo(1) foo(11)  and x.foo(1,2) foo(11,22) are both legal, but x.foo() foo()  is not. 
> 
> in general, they shouldn't be. 
> 
>> x.foo() foo() seems perfectly reasonable to me, if the method in question was declared as
>> 
>> 	method foo(*a) foo(*b)
>> 
>> If it wasn’t, we would get a dynamic error when foo()foo() is invoked with the wrong number of arguments.
> 
> or should we write it  x.foo foo 
> 
> (note that the current syntax does NOT support this!)
> 
> 
>>> We don't have this problem with single-part requests because x.foo(1)  and  x.foo are both legal requests
>> 
>> Yes, they are both legal requests.  What’s not clear to me is if x.foo is a legal way to call a method declared with a parameter list.
> 
> right. so we need to clarify that.

How we should do this depends (in my mind) on what notation we use for lists.  Varargs are fairly unusual in Grace aside from constructors.  I could see () as a special case for empty var args, but I think we should work out the other issues first.
> 
> 
>>> I don't think operator requests can take varargs.
>> 
>> I think that all infix operators take exactly 1 argument, and all prefix operator take exactly 0 arguments.
> 
> agreed…

That’s fine
> 
>> 
>> I’ve been wondering about allowing [ and ] and indeed any matched pair of brackets other than { and } and ( and ) to be declared as 
>> methods.  If so, can they be variable arity methods?   It would certainly be convenient to allow matched brackets of any available kind to
>> be used as factory methods for sequences, sets, etc.
> 
> I'm afraid you and Michael have been thinking alike again. 

We just need to make sure we don’t screw up the syntax for type parameters if we do this. 

> 
> 
>> On another, but related, tack, I’ve been thinking about how to eliminate the arity checks that currently happen on every method request.
>> This would be easy if it were not for variable arity methods.   But so long as we have them (and I don’t see a good alternative),  we will
>> need a slow path to deal with them.
> 
> right. other than hope?    or caching?   or PyPy? 
> 
>> It’s also a bit frustrating not to have a way of “exploding” a collection into an argument list (like JavaScript’s Function.prototype.apply()).
>> As with C, every Grace variable arity method really needs to be defined in terms of another method that takes a collection argument.   
>> It’s not terrible, but it’s a place where we have to teach a programming pattern to get around a language deficiency.   Which was one of 
>> the things that we said we wanted to avoid.
> 
> 
Unless we just restrict its use to varargs, it makes it impossible to statically type check the language, so
I’d prefer not to include that.

> yep.   well we could always steal another operator "prefix *" and add it to the language,
> 
> alternatively (and perhaps this is why I shouldn't answer emails in the pub)
> we could forgo varargs altogether, but bring back brackets or matchfix (circumfix) 
> operators, and just pass in sequences as and where required rather than use varargs.
> the catch is
> 
>> 	method  foo(a, b, *c)
> 
> which can be called 
> 
> x.foo( "A", "B", 1, 2, 3)
> x.foo( "A", "B", 1)
> x.foo( "A", "B")
> 
> would have to become either 
> 
> method foo(a, b, c : Sequence<Number>) 
> 
> and be called
> 
> x.foo( "A", "B", [1, 2, 3])
> x.foo( "A", "B", [1])
> x.foo( "A", "B", [])
> 
> or we could just multiple names (and or definitions)
> 
> method foo(a, b) stuff (c : Sequence<Number>) 
> 
> called as 
> 
> x.foo( "A", "B") stuff [1, 2, 3]
> x.foo( "A", "B") stuff [1]
> x.foo( "A", "B") stuff [] 
> 
> or with an option part, or a second definition
> 
> method foo(a, b) stuff (c : Sequence<Number>) 
> method foo(a, b)
> 
> called as 
> 
> x.foo( "A", "B") stuff [1, 2, 3]
> x.foo( "A", "B") stuff [1]
> x.foo( "A", "B")
> 
> a related question is: if we lose varargs, do we lose too much when it comes to host language interoperation
> given that they do all use varargs?

If we have a simple notation like that for lists, it might be reasonable to drop the varargs.  Not sure at this point.
> 
> James
> 
> 
> 
> _______________________________________________
> Grace-core mailing list
> Grace-core at cecs.pdx.edu
> https://mailhost.cecs.pdx.edu/mailman/listinfo/grace-core




More information about the Grace-core mailing list