[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