[scala] Syntax proposal for call by name parameters

View: Old framed views
20 Messages — Rating Filter:   Alert me  
David MacIver
[scala] Syntax proposal for call by name parameters
Reply More
Rate this Message:
Reply to author
Print
Show in thread view
Show in list view (by date)
Permalink
Currently the following are valid ways of defining local variables:

val foo = stuff;
lazy val foo = stuff;
var foo = stuff;
def foo = stuff;

Each of them have different semantics.

The following are valid ways of defining function and constructor arguments:

foo;
val foo;
var foo;

lazy val foo; is coming as an option.

So, why is def foo not on this list?

What would it do? Well, it behaves much the same was as no argument
defs usually do. The expression isn't evaluated at the definition site
and is evaluated each time you referenced its name in the function. In
other words, it's a call by name parameter!

So, why not make the syntax a little more uniform and replace the current

def myFunction(x : =>Foo)

with the more consistent

def myFunction(def x : Foo);

=>Foo isn't really a type - you can't have instances of =>Foo, can't
return them, can't assign them to variables, etc. Giving it the
notation of such seems unneccessarily confusing. This syntax seems
much more natural to me.

Any arguments for or against?
Geoffrey Alan Washburn-4
[scala] Re: Syntax proposal for call by name parameters
Reply More
Rate this Message:
Reply to author
Print
Show in thread view
Show in list view (by date)
Permalink
David MacIver wrote:

> So, why not make the syntax a little more uniform and replace the current
>
> def myFunction(x : =>Foo)
>
> with the more consistent
>
> def myFunction(def x : Foo);
>
> =>Foo isn't really a type - you can't have instances of =>Foo, can't
> return them, can't assign them to variables, etc. Giving it the
> notation of such seems unneccessarily confusing. This syntax seems
> much more natural to me.

I like it, as it is definitely confusing to make something look like a
type when it really isn't.

Jamie Webb-2
Re: [scala] Syntax proposal for call by name parameters
Reply More
Rate this Message:
Reply to author
Print
Show in thread view
Show in list view (by date)
Permalink
On 2008-03-17 23:29:18 David MacIver wrote:
> So, why not make the syntax a little more uniform and replace the
> current
>
> def myFunction(x : =>Foo)
>
> with the more consistent
>
> def myFunction(def x : Foo);

Believe it or not your suggested syntax was originally the one that was
used. It was changed to the current syntax a couple of years ago as I
recall.

I /think/ the reason for this was to do with class parameters:

  class C(def x : Foo)

This would imply that x is a member, when the semantics are that it is
just a constructor parameter.

A shame, because I quite agree that the old syntax was more readable.

/J
Ingo Maier-2
Re: [scala] Syntax proposal for call by name parameters
Reply More
Rate this Message:
Reply to author
Print
Show in thread view
Show in list view (by date)
Permalink
David MacIver wrote:

> Currently the following are valid ways of defining local variables:
>
> val foo = stuff;
> lazy val foo = stuff;
> var foo = stuff;
> def foo = stuff;
>
> Each of them have different semantics.
>
> The following are valid ways of defining function and constructor arguments:
>
> foo;
> val foo;
> var foo;

val and var are not valid for function arguments, aren't they? I mean,
val and var make constructor arguments available as class members. I
would expect that def to behave similar then. If this was the case and
if foo: =>A was deprecated, how could one pass a call-by-name argument
without exposing it as a member?

Ingo
David MacIver
Re: [scala] Syntax proposal for call by name parameters
Reply More
Rate this Message:
Reply to author
Print
Show in thread view
Show in list view (by date)
Permalink
On Tue, Mar 18, 2008 at 10:16 AM, Jamie Webb <j@...> wrote:

> On 2008-03-17 23:29:18 David MacIver wrote:
>  > So, why not make the syntax a little more uniform and replace the
>  > current
>  >
>  > def myFunction(x : =>Foo)
>  >
>  > with the more consistent
>  >
>  > def myFunction(def x : Foo);
>
>  Believe it or not your suggested syntax was originally the one that was
>  used. It was changed to the current syntax a couple of years ago as I
>  recall.

Heh. Really? Interesting.

It's entirely possible I've read that at some point and forgot about
it and that was the inspiration for the idea.

>  I /think/ the reason for this was to do with class parameters:
>
>   class C(def x : Foo)
>
>  This would imply that x is a member, when the semantics are that it is
>  just a constructor parameter.

Hm. That's a good point.  How about making it purely local unless it
has a privacy modifier?

Actually, that might not be a bad idea for all constructor parameters.
But that's probably a more drastic suggestion. :-)

>  A shame, because I quite agree that the old syntax was more readable.

Yeah. It seems unfortunate to deprecate a nice syntax because of its
behaviour in one particular case.
Geoffrey Alan Washburn-4
[scala] Re: Syntax proposal for call by name parameters
Reply More
Rate this Message:
Reply to author
Print
Show in thread view
Show in list view (by date)
Permalink
Jamie Webb wrote:

> Believe it or not your suggested syntax was originally the one that was
> used. It was changed to the current syntax a couple of years ago as I
> recall.
>
> I /think/ the reason for this was to do with class parameters:
>
>   class C(def x : Foo)
>
> This would imply that x is a member, when the semantics are that it is
> just a constructor parameter.
>
> A shame, because I quite agree that the old syntax was more readable.

I guess one point in favor of using a modifier is what happens when we
add lazy arguments?  Do we need to use another symbol as part of the type?

   def foo(x : ~> Int) ???

However, there is still the problem of coming up with a consistent set
of names for the modifiers.

David MacIver
Re: [scala] Syntax proposal for call by name parameters
Reply More
Rate this Message:
Reply to author
Print
Show in thread view
Show in list view (by date)
Permalink
On Tue, Mar 18, 2008 at 10:19 AM, Ingo Maier <ingoem@...> wrote:

> David MacIver wrote:
>  > Currently the following are valid ways of defining local variables:
>  >
>  > val foo = stuff;
>  > lazy val foo = stuff;
>  > var foo = stuff;
>  > def foo = stuff;
>  >
>  > Each of them have different semantics.
>  >
>  > The following are valid ways of defining function and constructor arguments:
>  >
>  > foo;
>  > val foo;
>  > var foo;
>
>  val and var are not valid for function arguments, aren't they? I mean,

Huh. So they're not. I could have sworn they were. I guess that's what
I get for posting without running my email past the compiler first.

Oh well. That rather reduces the strength of my argument, but I shall
soldier bravely on and add that to the feature request!

>  val and var make constructor arguments available as class members. I
>  would expect that def to behave similar then. If this was the case and

That seems like a feature rather than a bug to me. :-)

>  if foo: =>A was deprecated, how could one pass a call-by-name argument
>  without exposing it as a member?

As just suggested in my email to Jamie, I think that the way that this
should work is that it should be local unless given a privacy
modifier.

Hm. The necessary changes keep piling up. I thought this was a minor
syntax change! Sigh. So, to recap, in order to make this work the
syntax changes would be:

a) Allow val, var and def in function parameters. val wouldn't do
anything (it's the same as the default). def introduces a call by name
parameter.
b) Constructor args are local by default unless given a visibility
modifier (private, public, protected). When given this modifier they
introduce a public member of the appropriate type.

That's a rather larger proposal than my original one, but I still like
it. I think it works more consistently than the current approach, and
adheres quite strongly to the principle of making similar things
(constructors and functions, call by name parameters and no arg defs)
behave similarly.
Andrew.Foggin
Re: [scala] Syntax proposal for call by name parameters
Reply More
Rate this Message:
Reply to author
Print
Show in thread view
Show in list view (by date)
Permalink
I agree that this syntax appears more consistent.

My main concern is that such a change could be a further step away from
unifying tuples and function arguments as per my earlier proposal
http://www.nabble.com/Unifying-Tuple-types-and-function-parameters-ts13761592.html#a13815392

--Andrew

David MacIver wrote:

> Currently the following are valid ways of defining local variables:
>
> val foo = stuff;
> lazy val foo = stuff;
> var foo = stuff;
> def foo = stuff;
>
> Each of them have different semantics.
>
> The following are valid ways of defining function and constructor arguments:
>
> foo;
> val foo;
> var foo;
>
> lazy val foo; is coming as an option.
>
> So, why is def foo not on this list?
>
> What would it do? Well, it behaves much the same was as no argument
> defs usually do. The expression isn't evaluated at the definition site
> and is evaluated each time you referenced its name in the function. In
> other words, it's a call by name parameter!
>
> So, why not make the syntax a little more uniform and replace the current
>
> def myFunction(x : =>Foo)
>
> with the more consistent
>
> def myFunction(def x : Foo);
>
> =>Foo isn't really a type - you can't have instances of =>Foo, can't
> return them, can't assign them to variables, etc. Giving it the
> notation of such seems unneccessarily confusing. This syntax seems
> much more natural to me.
>
> Any arguments for or against?
>
>  

Ingo Maier-2
Re: [scala] Syntax proposal for call by name parameters
Reply More
Rate this Message:
Reply to author
Print
Show in thread view
Show in list view (by date)
Permalink
David MacIver wrote:
> a) Allow val, var and def in function parameters. val wouldn't do
> anything (it's the same as the default). def introduces a call by name
> parameter.
> b) Constructor args are local by default unless given a visibility
> modifier (private, public, protected). When given this modifier they
> introduce a public member of the appropriate type.

This would introduce a new keyword: public. It would further break with
Scala's default behavior that all members are public unless a private or
protected modifier is given.

> That's a rather larger proposal than my original one, but I still like
> it. I think it works more consistently than the current approach, and
> adheres quite strongly to the principle of making similar things
> (constructors and functions, call by name parameters and no arg defs)
> behave similarly.

Just to make it clear, I generally like the def instead of =>, too :)
There seem to be a couple of problems, however.

Ingo

Geoffrey Alan Washburn-4
[scala] Re: Syntax proposal for call by name parameters
Reply More
Rate this Message:
Reply to author
Print
Show in thread view
Show in list view (by date)
Permalink
Andrew Foggin wrote:
> I agree that this syntax appears more consistent.
>
> My main concern is that such a change could be a further step away from
> unifying tuples and function arguments as per my earlier proposal
> http://www.nabble.com/Unifying-Tuple-types-and-function-parameters-ts13761592.html#a13815392 

Hmmm.  That's a good point too.  Part of the issue is that marking the
arguments as call-by-need or call-by-name, etc. is inaccurate.  It is
not the arguments themselves that have these properties, but the method
or function.  However, adjusting the language to make that more explicit
would probably require changes that are much less local.

Imam Tashdid ul Alam
Re: [scala] Syntax proposal for call by name parameters
Reply More
Rate this Message:
Reply to author
Print
Show in thread view
Show in list view (by date)
Permalink
Though this is more technical than I can handle, I
actually liked Andrew's idea.

and reading 'def' as 'define' definitely makes the
proposed syntax a bit awkward.

--- Andrew Foggin <...> wrote:

> I agree that this syntax appears more consistent.
>
> My main concern is that such a change could be a
> further step away from
> unifying tuples and function arguments as per my
> earlier proposal
>
http://www.nabble.com/Unifying-Tuple-types-and-function-parameters-ts13761592.html#a13815392

>
> --Andrew
>
> David MacIver wrote:
> > Currently the following are valid ways of defining
> local variables:
> >
> > val foo = stuff;
> > lazy val foo = stuff;
> > var foo = stuff;
> > def foo = stuff;
> >
> > Each of them have different semantics.
> >
> > The following are valid ways of defining function
> and constructor arguments:
> >
> > foo;
> > val foo;
> > var foo;
> >
> > lazy val foo; is coming as an option.
> >
> > So, why is def foo not on this list?
> >
> > What would it do? Well, it behaves much the same
> was as no argument
> > defs usually do. The expression isn't evaluated at
> the definition site
> > and is evaluated each time you referenced its name
> in the function. In
> > other words, it's a call by name parameter!
> >
> > So, why not make the syntax a little more uniform
> and replace the current
> >
> > def myFunction(x : =>Foo)
> >
> > with the more consistent
> >
> > def myFunction(def x : Foo);
> >
> > =>Foo isn't really a type - you can't have
> instances of =>Foo, can't
> > return them, can't assign them to variables, etc.
> Giving it the
> > notation of such seems unneccessarily confusing.
> This syntax seems
> > much more natural to me.
> >
> > Any arguments for or against?
> >
> >  
>
>



      ____________________________________________________________________________________
Be a better friend, newshound, and
know-it-all with Yahoo! Mobile.  Try it now.  http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ 

tmorris
Re: [scala] Syntax proposal for call by name parameters
Reply More
Rate this Message:
Reply to author
Print
Show in thread view
Show in list view (by date)
Permalink
David MacIver wrote:
> Huh. So they're not. I could have sworn they were. I guess that's what
> I get for posting without running my email past the compiler first.

Maybe you were confused with constructor arguments:

scala> case class C(val i: Int)
defined class C

scala> case class D(var i: Int)
defined class D


--
Tony Morris
http://tmorris.net/

David MacIver
Re: [scala] Syntax proposal for call by name parameters
Reply More
Rate this Message:
Reply to author
Print
Show in thread view
Show in list view (by date)
Permalink
On Tue, Mar 18, 2008 at 10:32 AM, Andrew Foggin <andy@...> wrote:
> I agree that this syntax appears more consistent.
>
>  My main concern is that such a change could be a further step away from
>  unifying tuples and function arguments as per my earlier proposalts13761592
>  http://www.nabble.com/Unifying-Tuple-types-and-function-parameters-.html#a13815392
>
>  --Andrew

Ah! In fact, the two proposals work *beautifully* together. It just
requires some minor changes to your proposal (ones which I think would
be an improvement to yours even in the absence of mine).

Rather than FunctionN being identified with a Function1[TupleN, it
becomes identified with Function1[ProductN

The difference between call by name parameters now becomes that they
are defs rather than vals. The first part about desugaring call by
name into function arguments goes away.

So now we have

def stuff(val foo, var bar, def baz) = ...

stuff(x, y, z)

becomes

stuff(new Product3[..]{
  val _1 = x;
  var _2 = y;
  def _3 = z;
})
Andrew.Foggin
Re: [scala] Syntax proposal for call by name parameters
Reply More
Rate this Message:
Reply to author
Print
Show in thread view
Show in list view (by date)
Permalink
David MacIver wrote:

> On Tue, Mar 18, 2008 at 10:32 AM, Andrew Foggin <andy@...> wrote:
>  
>> I agree that this syntax appears more consistent.
>>
>>  My main concern is that such a change could be a further step away from
>>  unifying tuples and function arguments as per my earlier proposalts13761592
>>  http://www.nabble.com/Unifying-Tuple-types-and-function-parameters-.html#a13815392
>>
>>  --Andrew
>>    
>
> Ah! In fact, the two proposals work *beautifully* together. It just
> requires some minor changes to your proposal (ones which I think would
> be an improvement to yours even in the absence of mine).
>
> Rather than FunctionN being identified with a Function1[TupleN, it
> becomes identified with Function1[ProductN
>
> The difference between call by name parameters now becomes that they
> are defs rather than vals. The first part about desugaring call by
> name into function arguments goes away.
>
> So now we have
>
> def stuff(val foo, var bar, def baz) = ...
>
> stuff(x, y, z)
>
> becomes
>
> stuff(new Product3[..]{
>   val _1 = x;
>   var _2 = y;
>   def _3 = z;
> })
>
>  
I need to think this through - but at first glance this looks very
promising!  It seems to make both proposals more compelling...

--Andrew
David MacIver
Re: [scala] Syntax proposal for call by name parameters
Reply More
Rate this Message:
Reply to author
Print
Show in thread view
Show in list view (by date)
Permalink
On Tue, Mar 18, 2008 at 10:40 AM, Ingo Maier <ingoem@...> wrote:
> David MacIver wrote:
>  > a) Allow val, var and def in function parameters. val wouldn't do
>  > anything (it's the same as the default). def introduces a call by name
>  > parameter.
>  > b) Constructor args are local by default unless given a visibility
>  > modifier (private, public, protected). When given this modifier they
>  > introduce a public member of the appropriate type.
>
>  This would introduce a new keyword: public. It would further break with

True. I'd forgotten that wasn't already a keyword.

>  Scala's default behavior that all members are public unless a private or
>  protected modifier is given.

Well, not exactly. It changes the default about what is considered to
be a member. But I agree that it seems weirdly inconsistent.

Just to compound the feature proposal, if we're going to add a
keyword, let's do it properly. :-)

I've often been annoyed by the fact that there's no way of having
constructor local variables other than the constructor parameters.
It's not a big deal, but it's been annoying at various points. So why
not introduce a "local" privacy modifier for that (it doesn't have to
be a keyword outside of privacy modifiers, so it shouldn't break
existing code)? That gives us extra functionality, resolves the
problem with def constructor parameters and makes things nicely
consistent with the way public by default works.

Just to be clear, I don't think this is necessary for my proposal to
work. It just seems like the nicest solution.

I actually think that requiring call by name parameters for
constructors to be members wouldn't be the end of the world - 9 times
out of 10 it seems perfectly acceptable, and for the one time in 10
where it's not you can just pass a () => T as a normal constructor
argument.
Andrew.Foggin
Re: [scala] Syntax proposal for call by name parameters
Reply More
Rate this Message:
Reply to author
Print
Show in thread view
Show in list view (by date)
Permalink
David MacIver wrote:

> On Tue, Mar 18, 2008 at 10:40 AM, Ingo Maier <ingoem@...> wrote:
>  
>> David MacIver wrote:
>>  > a) Allow val, var and def in function parameters. val wouldn't do
>>  > anything (it's the same as the default). def introduces a call by name
>>  > parameter.
>>  > b) Constructor args are local by default unless given a visibility
>>  > modifier (private, public, protected). When given this modifier they
>>  > introduce a public member of the appropriate type.
>>
>>  This would introduce a new keyword: public. It would further break with
>>    
>
> True. I'd forgotten that wasn't already a keyword.
>
>  
>>  Scala's default behavior that all members are public unless a private or
>>  protected modifier is given.
>>    
>
> Well, not exactly. It changes the default about what is considered to
> be a member. But I agree that it seems weirdly inconsistent.
>
> Just to compound the feature proposal, if we're going to add a
> keyword, let's do it properly. :-)
>
> I've often been annoyed by the fact that there's no way of having
> constructor local variables other than the constructor parameters.
> It's not a big deal, but it's been annoying at various points. So why
> not introduce a "local" privacy modifier for that (it doesn't have to
> be a keyword outside of privacy modifiers, so it shouldn't break
> existing code)? That gives us extra functionality, resolves the
> problem with def constructor parameters and makes things nicely
> consistent with the way public by default works.
>
> Just to be clear, I don't think this is necessary for my proposal to
> work. It just seems like the nicest solution.
>
> I actually think that requiring call by name parameters for
> constructors to be members wouldn't be the end of the world - 9 times
> out of 10 it seems perfectly acceptable, and for the one time in 10
> where it's not you can just pass a () => T as a normal constructor
> argument.
>
>  
I'm trying to write this up right now but my suggestion would be to
allow the 'val' to be omitted (and in 'lazy val' too when that gets
added).  If you omit the 'val' in a constructor parameter list (for an
ordinary class, not a case class) the compiler can assume this to mean
'private val'.  That's pretty close to existing semantics.

--Andrew

David MacIver
Re: [scala] Syntax proposal for call by name parameters
Reply More
Rate this Message:
Reply to author
Print
Show in thread view
Show in list view (by date)
Permalink
On Tue, Mar 18, 2008 at 1:23 PM, Andrew Foggin <andy@...> wrote:

>  > I actually think that requiring call by name parameters for
>  > constructors to be members wouldn't be the end of the world - 9 times
>  > out of 10 it seems perfectly acceptable, and for the one time in 10
>  > where it's not you can just pass a () => T as a normal constructor
>  > argument.
>  >
>  >
>  I'm trying to write this up right now but my suggestion would be to
>  allow the 'val' to be omitted (and in 'lazy val' too when that gets
>  added).  If you omit the 'val' in a constructor parameter list (for an
>  ordinary class, not a case class) the compiler can assume this to mean
>  'private val'.  That's pretty close to existing semantics.

Right. But the problem is with the def, not the val. Given something like

class Foo(def bar : Unit)

we want to distinguish between the case where def is constructor local
and where it's an actual member. private members are different from
constructor local variables, which is why I suggested the additional
"local" declaration.

A parameter with no declaration would default to local val, or just
val for a method.
David MacIver
Re: [scala] Syntax proposal for call by name parameters
Reply More
Rate this Message:
Reply to author
Print
Show in thread view
Show in list view (by date)
Permalink
I've written up a summary of the current state of the proposal here:

http://unenterprise.blogspot.com/2008/03/scala-syntax-change-proposal.html

Most of these changes don't depend on eachother, but are all strongly
complementary.
Andrew.Foggin
Re: [scala] Syntax proposal for call by name parameters
Reply More
Rate this Message:
Reply to author
Print
Show in thread view
Show in list view (by date)
Permalink
David MacIver wrote:
> I've written up a summary of the current state of the proposal here:
>
> http://unenterprise.blogspot.com/2008/03/scala-syntax-change-proposal.html
>
> Most of these changes don't depend on eachother, but are all strongly
> complementary.
>
>  
I've abandoned my own write-up and added some comments there.

BTW I think proposals of this type should be called YAPS (Yet Another
Proposal for Scala).

I apologise especially to the overworked LAMPers for continually yapping
at you :-/

--Andrew
David MacIver
Re: [scala] Syntax proposal for call by name parameters
Reply More
Rate this Message:
Reply to author
Print
Show in thread view
Show in list view (by date)
Permalink
On Tue, Mar 18, 2008 at 2:33 PM, Andrew Foggin <andy@...> wrote:

>
> David MacIver wrote:
>  > I've written up a summary of the current state of the proposal here:
>  >
>  > http://unenterprise.blogspot.com/2008/03/scala-syntax-change-proposal.html
>  >
>  > Most of these changes don't depend on eachother, but are all strongly
>  > complementary.
>  >
>  >
>  I've abandoned my own write-up and added some comments there.
>
>  BTW I think proposals of this type should be called YAPS (Yet Another
>  Proposal for Scala).
>
>  I apologise especially to the overworked LAMPers for continually yapping
>  at you :-/
>
>  --Andrew
>

Seth Tisue pointed out on my blog that the "local" thing already
exists - it's exactly what private[this] does! So that part of the
proposal can go away.

Any more opinions on this idea? I'll probably submit a ticket for it
soon if no one provides a convincing reason that it's a bad idea.