Lexical scope and closures

Sat, 15 Feb 2003 08:06:31 +0900, Mauricio Fernández batsman.geo@yahoo.com pisze:

Would you reconsider dropping ‘:=’ ?

It would look backwards for me; := looks like assignment and =
like definition more than the other way around.

Anyway, I would like to be able to specify initial value at the point
of introduction of a local variable, and be able to introduce it in
the middle of a block. I mean: say on the fly “let’s compute this and
call it x, where x is a new variable”, rather than declare locals on
the top of a block.

My favourite is
let x = expr
perhaps with a different keyword (var or local) and with several
variables at once. I don’t like local {|a,b| …} for the above
reasons, and because it introduces an indentation level.

Making locals shouldn’t be much uglier than using method’s variables
so it will be used not only when absolutely necessary.

Actually ‘var’ and ‘local’ sound better than ‘let’ when there is no
initial value. It’s a better style to provide it though. I hate when
a language forces me to list all variables in one place before they
are used.

···


__("< Marcin Kowalczyk
__/ qrczak@knm.org.pl
^^ Blog człowieka poczciwego.

Hi,

arr.each {|i|
let a = …
let b = …
c = …

}

clean, though this is a declarative, which i thought you were trying to avoid.

It’s sort of hard to describe, but it is not declaration I avoid;
I was trying to avoid “declaration for compiler’s sake”.

I think this is not the case, since distinguishing local/non-local is
essential. We need some kind of mark anyway.

but maybe this is best. yet i think this would add complication: what would
‘let’ mean outside of block? wouldn’t one be inclined to have it go further:

At the top level of method, let does mean nothing but ensuring a local
variable is not assigned at the place.

yet, something drives me to want procs and blocks to be like methods --that
everything is local and you have to pass variables in and out, but this
doesn’t coincide well with current ruby, and perhaps defeats the purpose of
closures.

Perhaps you’d better not to recycle (or embrace and enhance) existing
construct, but introduce another syntax construct for your need, for
example, syntax to create anonymous function object.

						matz.
···

In message “Re: Lexical scope and closures” on 03/02/14, Tom Sawyer transami@transami.net writes:

Hi,

I’d choose something between

arr.each {|i|
local{|a,b|
c = …

}
}
(snip)
in either case, a, b are local, c is method-wise variable.

I vote for the second variant, possibly replacing ‘let’ with ‘local’. The
drawback of the first variant is IMHO that it is too easily recognized as
an ordinary block.

Because it is an ordinary block.

···

At Fri, 14 Feb 2003 19:11:42 +0900, Robert Klemme wrote:


Nobu Nakada

mmm...seems overly syntatical, might as well do:

  arr.each {|i;a,b|
  c = ..
  }

though for some reason i don't like this either. feels like a aand b should be
catching something, not just becoming local.

I think so too. It would make sense if they were catching variables 'a' and
'b' defined outside the block (i.e. turning it around so that everything is
local unless defined otherwise)

I expect people would probably find that too fussy in 'normal' use though:

  max = 0
  [1,2,3].each { |v;max| # <<
    max = v if v > max
  }

yet, something drives me to want procs and blocks to be like methods

When I first saw Ruby I imagined that

  def adder(a,b)
    a+b
  end

would be implemented under the surface as:

  self.class.methods[:adder] = proc do |a,b|
    a+b
  end

But as far as I can tell, it's not like that.

There's probably a good reason. At least, each method having a fresh scope
means that you don't have to worry about pollution of the local variable
namespace.

Regards,

Brian.

···

On Fri, Feb 14, 2003 at 04:20:23PM +0900, Tom Sawyer wrote:

arr.each {|i|
let a = …
let b = …
c = …

}

i’m concerned about using ‘let’ as it would not be clear why we wouldn’t use
it across the board. why would blocks be special? for example:

class A
def inititalize
c = “instead of @c
let a = “instead of just a”
end
end

so, i’d be more comfortable specifying locals as one does with private,
public, etc.:

arr.each { |i|
local :a, :b
a = …
b = …

}

···

On Friday 14 February 2003 12:20 am, Tom Sawyer wrote:

On Thursday 13 February 2003 08:03 pm, Yukihiro Matsumoto wrote:


on another note:

this matter has become tricky to deal with because of the way in which ruby
deals with scoping instance variables, vs. instance methods, vs. local
variables, etc. point blank: it is not symmetrical. i wish it could be made
so, but that would of course break code. :frowning:

just the same i’ll put the idea out here:

class A
def initialize
# local variables
initialize.a =“instead of just a”
%b = “as sugar for above (used in blocks)”
# instance variables
self.c = “instead of @c
d = “as above but where self is implied”
# class variables
A.e = “instead of @@e
@f = “this then could be class variable sugar”
# globals
toplevel.g = “or global.g”
$h = “global sugar”
end
end


tom sawyer, aka transami
transami@transami.net

Hi,

···

In message “Re: Lexical scope and closures” on 03/02/15, Mauricio Fernández batsman.geo@yahoo.com writes:

Would you reconsider dropping ‘:=’ ?

arr.each { |i|
a := …
b := …
c = …

}

involves fewer keystrokes. Moreover (I don’t know if it was your
original idea or not, but just to be sure)

That was my original idea, but I now feel that it’s too few clue to
tell they are local to the block. “let” reminds us local variable, if
we know some knowledge about lisp or ML. “:=” reminds us about
assignment (from Pascal knowledge), but has no information about
local.

						matz.

Hi –

Making locals shouldn’t be much uglier than using method’s variables
so it will be used not only when absolutely necessary.

As one of the two or three people in the world who think that Ruby’s
scoping rules are actually fine, I have to say that after all this
debate, people had better use whatever the new thing is, whether it’s
necessary or not! :slight_smile:

And I suspect people will, which means that if we have “local {}” or
"let x = ", we’re going to see lots of them.

Which, in turn, makes me reluctantly think that it would be better to
have local be the default, and some way to explicitly import variables
from outside the block into the block. I think the impact on the
overall look of Ruby would be enormously less.

Not that I have any great ideas as to how this would be notated… but
whatever it is, at least it would appear less frequently.

David

···

On Sat, 15 Feb 2003, Marcin ‘Qrczak’ Kowalczyk wrote:


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

nobu.nokada@softhome.net schrieb im Newsbeitrag
news:200302141025.h1EAPi824302@sharui.nakada.kanuma.tochigi.jp…

Hi,

I’d choose something between

arr.each {|i|
local{|a,b|
c = …

}
}
(snip)
in either case, a, b are local, c is method-wise variable.

I vote for the second variant, possibly replacing ‘let’ with ‘local’.
The
drawback of the first variant is IMHO that it is too easily recognized
as
an ordinary block.

Because it is an ordinary block.

? Why would you then need a ‘local’ keyword at all?

Regards

robert
···

At Fri, 14 Feb 2003 19:11:42 +0900, > Robert Klemme wrote:

on another note:

this matter has become tricky to deal with because of the way in which ruby
deals with scoping instance variables, vs. instance methods, vs. local
variables, etc. point blank: it is not symmetrical. i wish it could be made
so, but that would of course break code. :frowning:

just the same i’ll put the idea out here:

class A
def initialize
# local variables
initialize.a =“instead of just a”
%b = “as sugar for above (used in blocks)”
# instance variables
self.c = “instead of @c
d = “as above but where self is implied”

How do I use A#c then if there’s @c?
Plus I think locals are more used than i.v. so it makes more sense to
prefix the latter…

  # class variables
  A.e = "instead of @@e"
  @f = "this then could be class variable sugar"

You forgot my beloved class instance variables :slight_smile:

class << A
attr_accessor :e
end

A.e # class instance variable, NOT class variable

···

On Sat, Feb 15, 2003 at 07:01:21AM +0900, Tom Sawyer wrote:

  # globals
  toplevel.g = "or global.g"
  $h = "global sugar"
end

end


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Why are there always boycotts? Shouldn’t there be girlcotts too?
– argon on #Linux

As one of the two or three people in the world who think that Ruby's
scoping rules are actually fine, I have to say that after all this
debate, people had better use whatever the new thing is, whether it's
necessary or not! :slight_smile:

Well, the rule actually is simple : a variable belong in the scope where
it was first assigned.

Which, in turn, makes me reluctantly think that it would be better to
have local be the default, and some way to explicitly import variables
from outside the block into the block. I think the impact on the
overall look of Ruby would be enormously less.

Well, you want "export" rather than "import", no ?

Guy Decoux

As one of the two or three people in the world who think that Ruby’s
scoping rules are actually fine, I have to say that after all this
debate, people had better use whatever the new thing is, whether it’s
necessary or not! :slight_smile:

honestly, i probably have to agree. the more i think about it the more i see
that the way it is might be best after all.

And I suspect people will, which means that if we have “local {}” or
"let x = ", we’re going to see lots of them.

good point.

Which, in turn, makes me reluctantly think that it would be better to
have local be the default, and some way to explicitly import variables
from outside the block into the block. I think the impact on the
overall look of Ruby would be enormously less.

Not that I have any great ideas as to how this would be notated… but
whatever it is, at least it would appear less frequently.

like:

    c = 1
arr.eah |a| {
	import :c
	d = c + 2
	...
	export :d
}
puts d  #--> 3

the problem is old code would break if you had to import/export, though i
agree that there is something more percise about this approach. it makes
blocks more method like.

···

On Sunday 16 February 2003 06:06 am, dblack@candle.superlink.net wrote:


tom sawyer, aka transami
transami@transami.net

Hi,

···

At Fri, 14 Feb 2003 22:32:11 +0900, Robert Klemme wrote:

I’d choose something between

arr.each {|i|
local{|a,b|
c = …

}
}
(snip)
in either case, a, b are local, c is method-wise variable.

I vote for the second variant, possibly replacing ‘let’ with ‘local’. The
drawback of the first variant is IMHO that it is too easily recognized as
an ordinary block.

Because it is an ordinary block.

? Why would you then need a ‘local’ keyword at all?

def local; yield; end


Nobu Nakada

class A
def initialize
# local variables
initialize.a =“instead of just a”
%b = “as sugar for above (used in blocks)”
# instance variables
self.c = “instead of @c
d = “as above but where self is implied”

How do I use A#c then if there’s @c?

indeed, that actually is intentional. the namespace for variables and methods
at the same level (instance or class) is the same. thus:

self.c = 1

would conflict with:

def c
   1
end

notice what happens though. in either case the result is the same:

puts c  #--> 1

whether c was defined as an instance variable or an instance method.

Plus I think locals are more used than i.v. so it makes more sense to
prefix the latter…

the above is the reason why instance varaibles would loose the prefix.

  # class variables
  A.e = "instead of @@e"
  @f = "this then could be class variable sugar"

You forgot my beloved class instance variables :slight_smile:

class << A
attr_accessor :e
end

A.e # class instance variable, NOT class variable

technically, these are methods. aren’t they?

···

On Friday 14 February 2003 04:00 pm, Mauricio Fernández wrote:


tom sawyer, aka transami
transami@transami.net

Hi –

As one of the two or three people in the world who think that Ruby’s
scoping rules are actually fine, I have to say that after all this
debate, people had better use whatever the new thing is, whether it’s
necessary or not! :slight_smile:

Well, the rule actually is simple : a variable belong in the scope where
it was first assigned.

Which, in turn, makes me reluctantly think that it would be better to
have local be the default, and some way to explicitly import variables
from outside the block into the block. I think the impact on the
overall look of Ruby would be enormously less.

Well, you want “export” rather than “import”, no ?

What I meant was:

def meth
a = 1
[1,2,3].each {|x| # explicitly import existing a into block}
end

or something.

I definitely prefer things as they are. If it’s going to change,
though, I’m just hoping the visual impact can be minimized by having
the most frequent case be the least wordy.

David

···

On Sun, 16 Feb 2003, ts wrote:


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

Sounds good to me, just as it did when it was first suggested!

Gavin

···

On Monday, February 17, 2003, 12:18:37 AM, ts wrote:

Which, in turn, makes me reluctantly think that it would be better to
have local be the default, and some way to explicitly import variables
from outside the block into the block. I think the impact on the
overall look of Ruby would be enormously less.

Well, you want “export” rather than “import”, no ?

Just a random thought which occurred to me:

Suppose Ruby did introduce a declaration for local variables as discussed,
say 'let x=' for the sake of argument.

It has already been asked what happens if you used this outside a block.

Suppose you made 'let x=' the _only_ way to get a local variable? And
without it, 'x=' defaults to a method call, self.x= ?

It seems to me that a number of inconsistencies would vanish: 'x' always
refers to the object method 'x' or 'x=', unless you have previously
introduced it as a local variable with 'let x='. And then inside blocks, x
would continue to be bound to the same method or variable, unless you
introduce a new variable with another 'let x='.

Declarations for local variables would be clunky, same as Perl's "my". You'd
have to remember to use them, and take care when reordering lines that only
the first assignment of a variable said "let" (same as Perl). And there's
very little chance of backwards compatibility. But it would be very logical
and consistent :slight_smile:

But it's also not Ruby...

Regards,

Brian.

···

On Mon, Feb 17, 2003 at 12:05:01AM +0900, Tom Sawyer wrote:

On Sunday 16 February 2003 06:06 am, dblack@candle.superlink.net wrote:
> As one of the two or three people in the world who think that Ruby's
> scoping rules are actually fine, I have to say that after all this
> debate, people had better use whatever the new thing is, whether it's
> necessary or not! :slight_smile:

honestly, i probably have to agree. the more i think about it the more i see
that the way it is might be best after all.

> And I suspect people will, which means that if we have "local {}" or
> "let x = ", we're going to see *lots* of them.

good point.

all it does local a and b. ugly, if you ask me.

hey, i thought of another ugly possibility yesterday! :slight_smile:

arr.each { |i|
c = “is local”
@c = “is c in outer scope”
@@c = “is @c in outerscope”
@@@c = “is @@c in outerscope”
}

yep, and then you can layers and layers of blocks and eventually end up with:

@@@@@@@@@@@@@@@c = “foo bar”

fun fun :wink:

···

On Friday 14 February 2003 08:18 am, nobu.nokada@softhome.net wrote:

? Why would you then need a ‘local’ keyword at all?

def local; yield; end


tom sawyer, aka transami
transami@transami.net

class A
def initialize
# local variables
initialize.a =“instead of just a”
%b = “as sugar for above (used in blocks)”
# instance variables
self.c = “instead of @c
d = “as above but where self is implied”

How do I use A#c then if there’s @c?

indeed, that actually is intentional. the namespace for variables and methods
at the same level (instance or class) is the same. thus:

self.c = 1

would conflict with:

def c
1
end

With a warning?

notice what happens though. in either case the result is the same:

puts c #–> 1

whether c was defined as an instance variable or an instance method.

so
puts c
is
puts self.c # instance variable, not method

Anyway, accessors are broken inside the class’ instance methods (and sometimes we want
them, when they do non-trivial things).

Ummm, now I realize that your idea corresponds exactly to defining
automagically accessors for each i.v. .

Plus I think locals are more used than i.v. so it makes more sense to
prefix the latter…

the above is the reason why instance varaibles would loose the prefix.

I see, but this doesn’t change the fact that I’d have to prefix locals,
which are far more common.

  # class variables
  A.e = "instead of @@e"
  @f = "this then could be class variable sugar"

You forgot my beloved class instance variables :slight_smile:

class << A
attr_accessor :e
end

A.e # class instance variable, NOT class variable

technically, these are methods. aren’t they?

OK, but there’s a name clash anyway :slight_smile:

···

On Sat, Feb 15, 2003 at 11:02:58AM +0900, Tom Sawyer wrote:

On Friday 14 February 2003 04:00 pm, Mauricio Fernández wrote:


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

*** Rince is wagner@schizo.DAINet.de (We have Joey, we have Fun, we have Linux on a Sun)
– Seen on #Debian

  def meth
    a = 1
    [1,2,3].each {|x| # explicitly import existing a into block}
  end

I don't understand sorry, with this example

   a = 1
   1.times do |x|
      a = 2 # shadowing ???
   end
   a # ===> 1

   a = 1
   1.times do |x|
      # explicitly import existing a into block
      a = 2
   end
   a # ===> 2

this ?

Guy Decoux

I think the most common case will be … code that looks exactly like it
does today. I think the need for local will be rare, the thread
examples being the one instance that I know of where local is definitely
needed.

I like the change, I believe it simplifies the rules for scoping. It
makes “loop do … end” consistent with “while … end”, and I think
that is a major win. It also gets rid of the surprise that {|x| …} is
sometimes local and sometimes not.

David, normally I am with you in that I’m very reluctant to make changes
to the language. But I see this change as one that makes Ruby simplier,
and that’s a good thing.

With that thought in mind (keeping things simple), that’s why I actually
prefer the “local” suggestion.

(1) Local is complete implementable in the language, no new syntax rules
are needed.
(2) No new semantic rules are needed (other than the rule that make
block arguments local to the block).
(3) It can be used anywhere local variables are needed. (If the “let”
syntax is used, it raise the question of the semantics of “let” outside
a block).

Since I don’t believe that block local variables are often needed, I
don’t mind that the “local” syntax is a wee bit on the ugly side. In
fact, one could argue that it is an advantage :slight_smile:

Matz will do what he thinks best. And his track record is proven. I
have no fears about the changes he finally decides upon.

···

On Sun, 2003-02-16 at 08:22, dblack@candle.superlink.net wrote:

I definitely prefer things as they are. If it’s going to change,
though, I’m just hoping the visual impact can be minimized by having
the most frequent case be the least wordy.


– Jim Weirich jweirich@one.net http://w3.one.net/~jweirich

“Beware of bugs in the above code; I have only proved it correct,
not tried it.” – Donald Knuth (in a memo to Peter van Emde Boas)