Pythonic indentation (or: beating a dead horse)

James B. wrote:

I’ve wondered if this sort thing is a problem in Python; perhaps it is
less likely there that any accidental indent or out-dent will still give
you well-formed code.

I’ve only minimally looked at python, but I’m pretty sure that it will
throw an
error when indentation is fouled.

Reid T. wrote:

James B. wrote:

I’ve wondered if this sort thing is a problem in Python; perhaps it is
less likely there that any accidental indent or out-dent will still
give you well-formed code.

I’ve only minimally looked at python, but I’m pretty sure that it will
throw an error when indentation is fouled.

Sure, if in fact the indentation is fouled.

My concern is that you can mistakenly add 4 spaces instead of two, or
vice versa, and get valid code (i.e. the parser does not see anything
technically wrong) yet not have the code you really wanted.

James

On Fri, May 22, 2009 at 9:30 AM, J Haas [email protected] wrote:

That being said I will plead guilty to being a terrible spokesman for
my ideas (and this extends well beyond the current discussion) because
I lack tact, empathy, and sensitivity… in short, I’m an asshole (and
not, as you suggested, someplace a couple of inches anterior.) This
has bitten me more times than I can say, but in the end, I gotta be me.

Well, everything else aside: if you can’t present your ideas or engage
in
discussion without being an asshole, you’re going to have a hard time
getting people to listen to you. I’ve been trying to give constructive
criticism, but when you come back at me with personal attacks I’m left
to
wonder why I should even bother.

Hi,

|A valid objection that was raised in the earlier thread was regarding
|a quick and easy and common debugging technique: throwing in print
|statements
|
| def do_something(a, b, c)
|print a, b, c # for debugging purposes
| a + b + c
| end
|
| def do_something(a, b, c):
|print a, b, c # error! unexpected indentation level
| a + b + c
| end

Despite some might expect, I am not fully against block-by-indentation
a la Python, as long as

  • we keep end and brace blocks as well, of course.
  • prohibit mixing tabs and spaces in indentation mode
  • nice and compatible syntax. for compatibility and other reasons,
    colons do not work for block-by-indentation-marker.

I haven’t found any good syntax so far. Besides that 'end’s and
braces often work nice for my eyes.

          matz.

From: “James B.” [email protected]

My concern is that you can mistakenly add 4 spaces instead of two, or
vice versa, and get valid code (i.e. the parser does not see anything
technically wrong) yet not have the code you really wanted.

That happened to us a couple times developing in
Python. We were using spaces only (no tabs) …
but somehow some tab characters did occasionally
sneak into a source file. (Possibly by copy/paste
of code from a different editor–I was never sure
how it happened.)

So the indentation looked fine to us in the editor
(seeing two-column tabs), but was interpreted
differently by Python (eight-column tabs), resulting
in some baffling “it can’t possibly be doing that!”
moments while debugging.

These days, I have my editor set to highlight tab
characters visually… :slight_smile:

Regards,

Bill

On May 22, 1:02 pm, Tony A. [email protected] wrote:

Well, everything else aside: if you can’t present your ideas or engage in
discussion without being an asshole, you’re going to have a hard time
getting people to listen to you. I’ve been trying to give constructive
criticism, but when you come back at me with personal attacks I’m left to
wonder why I should even bother.

It looks like another recap will be necessary.

In the beginning, I began a thread containing a proposal to implement
Python-style syntactically significant indentation in Ruby (this
proposal, I might add, was entirely optional, and would leave in place
a system which would support either indentation-delimited code
blocks or keyword-delimited code blocks.) At the time I posted it, I
expected opposition. I expected to be told that the requirement to
fill the code base 1/6th full of ‘ends’ actually improved
readability, and I was not disappointed. I expected ridiculous
strawman arguments involvingremovalofallspacesfromEnglish, and I was
not disappointed. I expected to have my motives questioned, with
insinuations that I secretly hated Ruby, and I was not disappointed.
Furthermore, I was prepared to ignore every one of these arguments, as
every one is fallacious. I trust in rational people to see the fallacy
behind each and will not do the fallacies the dignity of treating them
as though they were serious arguments, worthy of respectful rebuttal.

What I did not expect to hear, however, was a claim that my proposal
was actually impossible.

You can have the Pythonic indent syntax or a purely expression
based grammar with multi-line blocks. You can’t have both.

This took me by surprise, and for all I know, it might well be true.
As you may have surmised, I do not claim syntactical parser design or
theory among my areas of expertise. For all I know, there was some
reason I wasn’t aware of why what I proposed was impossible, even in
theory. And yet, I know I’d seen a script awhile ago, which I thought
I had saved on an old hard drive somewhere, which could actually do
Pythonic indentation in Ruby. And so I asked you for clarification.

I’m having a hard time following why. Can you provide an example of a
Ruby snippet that couldn’t be done with scoping defined by
indentation?

That’s all I needed. If there were a theoretical reason why Python-
style indentation were incompatible with some fundamental concept in
Ruby, it should be easy to provide an example of a Ruby construct
which would be impossible to parse without the use of ‘end’ or some
other keyword as a block delimiter. That’s all it would take. That’s
all I asked for. Did I get it?

x = do_something arg1
y = do_something_else x, arg2
and_something_else_again y, arg3
end

I looked at these and was flabbergasted. In what way were these at all
incompatible with syntactic indentation? What would be impossible to
parse about this?

foo = somemethod do |arg1, arg2, arg3|:
x = do_something arg1
y = do_something_else x, arg2
and_something_else_again y, arg3

Or this?

foo = lambda do |arg1, arg2, arg3|:
x = do_something arg1
y = do_something_else x, arg2
and_something_else_again y, arg3

How on Earth did these examples meet the test of being incompatible
with Python-style indentation? You provided a number of other examples
that similarly baffled me as to how they were supposed to support your
thesis. It was at this point that I began to lose patience with you
and suspect that you might be talking out of your ass.

You keep on saying this, yet I have not seen one example of code that
demonstrates that using dedent couldn’t work. Basically, we’re looking
for some code which, if you removed the all ends, a script following
simple deterministic rules would not be able to unambigiously decide
where to put them back.

Your response was:

Okay, you just want an example I guess.

(jh: what was your first clue?)

n *= 3

p result

The output of this program is:

[16, 22, 28]

Show me how you would parse the equivalent program in an
indentation-sensitive Ruby, e.g.:

Finally, I thought, an example! Time to dig out that old Ruby script
for preprocessing Python-style Ruby files… ah, there it is, on the
old MacBook Pro… copy it over to the current computer… hmm, no
doc… throw in a few quick and dirty patches to make it run; after
all, this is just a proof-of-concept, right? Edit the file, remove the
‘end’s and insert colons after the keywords which began those blocks,
run it through and… hey, whaddaya know, [16, 22, 28], first time
through. Looks like ol’ Tony really was talking out of his ass, eh?

I did not trouble to hide my lack of respect in my response conveying
that your proof of impossibility was false on its face. However, I do
not think that anything at all in that post could have been construed
as a “personal attack”. If you disagree, please point out an example.

Your next response to me was full of backpedaling falsehoods, such as:

My claims were it’s impossible with a Pythonic lexer and a backing context
free grammar.

And this:

I certainly didn’t claim that if you throw enough regexes at
the problem it won’t go away.

Just what do you think a regular expression engine is? Hint: it’s a
parser. If application of regular expressions can solve a problem, the
problem is not insoluble by a parser.

Well great! I’m not really sure how that script works

“…but it must be magic, since it does the impossible!”

However, what you have there is a marked departure from how Python actually works.

I know I already responded to this gem with mockery, but not nearly as
much as it deserves.

But if you’re happy with it, great. Go for it and see how popular you can
make it.

I don’t care about being popular. If I did, I wouldn’t be such an
asshole.

And then, without even waiting for a reply:

you’re being a right c–t

This is, as far as I know, the first and only personal attack in this
thread, unless you want to count my self-description as an asshole to
be a personal attack. But either way, never fear, Tony, your own
precious person has yet to be attacked.

And this brings us to your most recent post in this thread.

Well, everything else aside: if you can’t present your ideas or engage in
discussion without being an asshole, you’re going to have a hard time
getting people to listen to you.

No, Tony, that’s wrong. If I can’t present my ideas or engage in
discussion without being an asshole, I’m going to have a hard time
getting people like you to listen to me. People who are logical,
programmers who want the best possible language with the greatest
flexibility and expressiveness, will know that ad_hominem is a
fallacy and will look to the arguments, not to the person making them.

I’ve been trying to give constructive
criticism, but when you come back at me with personal attacks I’m left to
wonder why I should even bother.

And now we reach the present. Tony, what personal attacks? Please
cite them. Your relief at being able to use an alleged personal attack
as a fig leaf to escape your obligation to back up your claims is
palpable. An honorable person would either substantiate the claim or
retract it, rather than running and hiding and pretending to hurt
feelings.

Now, having said all that: I do not know that Tony’s claim is false.
As I said, I was surprised to be told that my proposal was impossible
and I lack the theoretical background to prove otherwise. So if anyone
out there agrees with Tony that Pythonic indentation in Ruby would not
be merely ill-advised but impossible I’d appreciate an example. Then
I can stop wasting my time.

On Mon, May 25, 2009 at 9:40 AM, J Haas [email protected] wrote:

Finally, I thought, an example! Time to dig out that old Ruby script

for preprocessing Python-style Ruby files… ah, there it is, on the
old MacBook Pro… copy it over to the current computer… hmm, no
doc… throw in a few quick and dirty patches to make it run; after
all, this is just a proof-of-concept, right? Edit the file, remove the
‘end’s and insert colons after the keywords which began those blocks,
run it through and… hey, whaddaya know, [16, 22, 28], first time
through. Looks like ol’ Tony really was talking out of his ass, eh?

You accomplished ABSOLUTELY nothing with your magic trick here, and you
darn
well know it. You in no way shape or form made the indent context work
at
all. All you did was figure out that a regular expression could add the
word
“end” to a block of data when told to. No one ever said that wasn’t
possible. That would be like saying that python can actually handle
multi
line lambdas if I took your same concept and pre-processed a file to
take
any multi line lambdas and convert them to a function which is called as
a
single line lambda. So are you now saying that anyone that claims the
python
engine doesn’t handle multi-line lambdas is talking out of their ass?

If all you want is a preprocessor then it seems like you already have
what
you want and can be on your way to writing what you perceive as
beautiful
code immediately. Congrats and have at it, I’m not sure what more you
would
want at this point.

If you feel that you want to push this further into the core then again

have at it - many folks have suggested that forking and getting some
ACTUAL
working code in front of folks is the surest way to get things
accomplished!
I doubt that anyone would truly object if you implemented what you
suggest,
they simply are of the mindset that it won’t work - prove them wrong,
and
not with a magic trick either.

Best of luck to you!

John W Higgins

On Wednesday 20 May 2009 05:28:34 pm Tony A. wrote:

You are proposing a Rube G. contraption whereby the scanner would
require some degree of grammatical awareness. This is a complex solution.
The minor flaw is that you don’t like “end” statements. Is the minor flaw
of having repeated end statements really worth the level of complexity the
solution would require?

If we’re admitting that a parser is possible, but would only be complex,
I
would say yes, it’s worth it.

Ruby itself is based on the idea that the computer should work for you,
not
the other way around. The language should be made simpler for a human to
understand and work with, even if it makes the implementation more
complex and
slower. My understanding is, this is the founding principle of Ruby –
the
whole reason it was invented in the first place.

Of course, the more important question is whether this can be done in
such a
way that is either wholly backwards compatible, or which doesn’t
irritate
people who like Ruby’s current syntax?

The social aspect seems to be the larger issue, here.

On Sunday 24 May 2009 03:42:19 pm James B. wrote:

My concern is that you can mistakenly add 4 spaces instead of two, or
vice versa, and get valid code (i.e. the parser does not see anything
technically wrong) yet not have the code you really wanted.

You can get the same problem by misplacing a bracket or a paren. The
only
difference I see is that the indentation is a lot more visibly obvious.

On May 25, 2009, at 9:40 AM, J Haas wrote:

As I said, I was surprised to be told that my proposal was impossible
and I lack the theoretical background to prove otherwise. So if anyone
out there agrees with Tony that Pythonic indentation in Ruby would not
be merely ill-advised but impossible I’d appreciate an example. Then
I can stop wasting my time.

I was on a questionable connection at the time, so my original message
may not have gotten to the mailing list:

cat impossible.rb

This one can’t be done in Pythonic style:

result = case ARGV[0]
when /^\d*$/
“That’s an integer!”
when /^[A-Za-z]*$/
“That looks like a word…”
else
“That’s not an integer or a word.”
end if ARGV[0]

puts result if result

Cheers,

Josh

On 5/25/09, J Haas [email protected] wrote:

Now, having said all that: I do not know that Tony’s claim is false.
As I said, I was surprised to be told that my proposal was impossible
and I lack the theoretical background to prove otherwise. So if anyone
out there agrees with Tony that Pythonic indentation in Ruby would not
be merely ill-advised but impossible I’d appreciate an example. Then
I can stop wasting my time.

It’s certainly not impossible, as the script you posted shows. That
script is a hack, however, since it doesn’t lex its input properly and
it will fail in obscure cases. I’ve written a proper implementation,
based on my RubyLexer library.

Basically, it makes the end keyword optional. If you leave off the
end, the preprocessor inserts an end for you at the next line indented
at or below the level of indentation of the line which started the
scope.

End is optional, so you can still write things like this:
begin
do_something
end until done?
(However, you’d better make damn sure you get the end indented to the
right level!)

This script uses RubyLexer to extract a stream of tokens and modify
it, then turn those tokens back into ruby code. Since RubyLexer is a
complete stand-alone lexer, this should be a very thorough solution,
free of insoluable little problems due to the script’s inability to
follow where comments and strings start and stop. (That said, I’m sure
there will be some problems with it, as it’s pretty raw code.)

As different programs have a variety of interpretations as to the
width of a tab character, tabs for indentation are absolutely
forbidden by endless.rb.

If you’re interested, please see:

David M. wrote:

On Sunday 24 May 2009 03:42:19 pm James B. wrote:

My concern is that you can mistakenly add 4 spaces instead of two, or
vice versa, and get valid code (i.e. the parser does not see anything
technically wrong) yet not have the code you really wanted.

You can get the same problem by misplacing a bracket or a paren. The only
difference I see is that the indentation is a lot more visibly obvious.

Interesting. I’ve had an incorrect number of braces and parens in the
past, and don’t think it ever made for well-formed executable ruby. I
always got a parsing error.

It seems like a much harder mistake to make then taping the space key or
back space key a few too more or less times. (That is, a mistake that
still leaves the code perfectly runnable by the interpreter, but with
different semantics than intended.)

Also, mismatched brackets or do/ends are very easy to spot; I tell vim
to auto-format, and the borked code alignment and incorrect syntax
coloring shows me right away where the error is.

I’m unclear as to whether you can have accurate auto-formatting with
significant indentation (e.g., ggVG=).


James B.

www.jamesbritt.com - Playing with Better Toys
www.ruby-doc.org - Ruby Help & Documentation
www.rubystuff.com - The Ruby Store for Ruby Stuff
www.neurogami.com - Smart application development

“David M.” [email protected] schrieb im Newsbeitrag
news:[email protected]

On Wednesday 20 May 2009 05:28:34 pm Tony A. wrote:

The social aspect seems to be the larger issue, here.

This is pointing to the right direction.
But it depends on your particular semantic of “social”.

(1) It would not only be a beer-table issue.
(Although many resources are always useless wasted for holy wars.)

It would probably spoil team projects and code reuse.
Given a team where one developer is familiar to pythonesque insertion.
Even if he is not one of these talibanesque people, he would probably
use
this technique somewhere in his scripts.
Even if it’s explicitely forbidden in the project, danger is, it would
be
used unintentionally.
When this code is reused, other people which are not familiar to
pythonesque
insertion may be trapped.
Maybe when trying to adapt the code, maybe by some automatic beautifying
by
the editor, maybe when forced to debug this code.
This would possibly waste hours by hours while timelines fly by.

As OPoster unintentionally demonstrated in OP, some people aren’t even
able
to format postings in NG’s properly.
(As I get caught already in this trap too, I rely on capabilities of
modern
news_readers_.)

So, it would effectively split Rubyists into two fractions. Those, who
use
PyI and those who don’t.
We used Ruby for writing test scripts for safety related software. PyI
would
have been a serious issue against using Ruby.
For not breaking existing code it would be necessary to be explicitely
allowed by a special switch, not to be allowed by default. This would
limit
number of users.
(Maybe it is possible to implement it as a gem? This would change the
picture completely.)

(2) Further, resources needed for a clean implementation and maintenance
of
PyI could be used for more urgent issues. (IMHO)
For example (I currently do not know the kernel of current Ruby-versions
nor
all current extensions because I’m still forced to use 1.6.8 or 1.8.6
for
compatibility reasons.):
I would like to wait for generic Events in the central loop, not only
for
file descriptors and timeouts. (Limitations of “C-Lib”-select()).
Independence of OS-platform should be increased in the kernel.
Real-Time capabilities would be nice.
There are, fore sure, many issues on the wish-list for future Ruby
kernels
which have a higher priority.

(3) Isn’t there a list where such issues are discussed? I think, Ruby is
mature enough to establish such a process.
For further development, it should be tried to implement a standard like
this one for “C” or “C++”.
IMO, Ruby is so widely used there is more than enough reason for doing
so.

Best Regards,
Michael B.

On 5/25/09, Joshua B. [email protected] wrote:

when /^[A-Za-z]*$/
“That looks like a word…”
else
“That’s not an integer or a word.”
end if ARGV[0]

puts result if result

Yes, and it’s this very sort of case that led me to make end optional
rather than forbidden in endless.rb. Clearly, some things can’t be
expressed just in pythonish syntax, so you have to be able to drop
back to ruby mode. The need for more tokens on the same line after the
end is sufficiently rare that I don’t think it detracts from the
overall effect; almost all ends can still be eliminated.

Actually, I think pyrb.rb also will tolerate this example as well; you
just leave off the colon and it doesn’t expect to create an end for
you for that statement. Looks like it’s missing the ‘when’ special
case, but for this example, that doesn’t matter, since you have the
whens more indented anyway.

This script uses RubyLexer to extract a stream of tokens and modify
it, then turn those tokens back into ruby code. Since RubyLexer is a
complete stand-alone lexer, this should be a very thorough solution,
free of insoluable little problems due to the script’s inability to
follow where comments and strings start and stop. (That said, I’m sure
there will be some problems with it, as it’s pretty raw code.)

As different programs have a variety of interpretations as to the
width of a tab character, tabs for indentation are absolutely
forbidden by endless.rb.

If you’re interested, please see:
endless.rb · GitHub

Could you post us a few examples of what code formatted this way looks
like (or must look like)? I assume it handles here documents well?

The italics part of that gist is somewhat hard to read :slight_smile:

@Michael:
I don’t think having “either or” syntax would be such a terrible thing
in terms of team re-use or resources–you should be able to convert the
code back and forth at will (a la ruby2ruby, parsetree [rubylexer has a
parsetree compatibility mode] etc.)
Cheers!
-=r

On May 22, 9:01 am, Roger P. [email protected] wrote:

Tony’s point was that certain constructs, like case statements, won’t be
transformable into indentation only blocks. Does that make sense?

No, it doesn’t, because I don’t see why case statements are not
transformable into indent-only blocks. I’ve done them using the
quick-and-dirty hacky script and they work just fine. (In cases like
Joshua’s impossible.rb I had to make a minor modification to the
script to have it inject 'end ’ rather than ‘end\n’, but it still
worked fine.)

Code speaks louder than words, right? Here’s some real-world code…
it’s application_controller.rb from the AuthLogic example (http://
github.com/binarylogic/authlogic_example/tree):


Filters added to this controller apply to all controllers in the

application.

Likewise, all the methods added will be available for all

controllers.

class ApplicationController < ActionController::Base
helper :all
helper_method :current_user_session, :current_user
filter_parameter_logging :password, :password_confirmation

private
def current_user_session
return @current_user_session if defined?(@current_user_session)
@current_user_session = UserSession.find
end

def current_user
  return @current_user if defined?(@current_user)
  @current_user = current_user_session &&

current_user_session.record
end

def require_user
  unless current_user
    store_location
    flash[:notice] = "You must be logged in to access this page"
    redirect_to new_user_session_url
    return false
  end
end

def require_no_user
  if current_user
    store_location
    flash[:notice] = "You must be logged out to access this page"
    redirect_to account_url
    return false
  end
end

def store_location
  session[:return_to] = request.request_uri
end

def redirect_back_or_default(default)
  redirect_to(session[:return_to] || default)
  session[:return_to] = nil
end

end


Nothing particularly special about this code, right? Pretty standard
Ruby, if a bit simple? 37 non-blank, non-comment lines, of which 9
consist of the bare word “end”. I defy anyone to tell me that the code
would be less readable as this:


Filters added to this controller apply to all controllers in the

application.

Likewise, all the methods added will be available for all

controllers.

class ApplicationController < ActionController::Base
helper :all
helper_method :current_user_session, :current_user
filter_parameter_logging :password, :password_confirmation

private
def current_user_session:
return @current_user_session if defined?(@current_user_session)
@current_user_session = UserSession.find

def current_user:
  return @current_user if defined?(@current_user)
  @current_user = current_user_session &&

current_user_session.record

def require_user:
  unless current_user:
    store_location
    flash[:notice] = "You must be logged in to access this page"
    redirect_to new_user_session_url
    return false

def require_no_user:
  if current_user:
    store_location
    flash[:notice] = "You must be logged out to access this page"
    redirect_to account_url
    return false

def store_location:
  session[:return_to] = request.request_uri

def redirect_back_or_default(default):
  redirect_to(session[:return_to] || default)
  session[:return_to] = nil

No, it doesn’t, because I don’t see why case statements are not
transformable into indent-only blocks. I’ve done them using the
quick-and-dirty hacky script and they work just fine. (In cases like
Joshua’s impossible.rb I had to make a minor modification to the
script to have it inject 'end ’ rather than ‘end\n’, but it still
worked fine.)

True I suppose case statements could be done using blocks.
Note also that you don’t “need” the ending : per line, either.

-=r

I’m just going to stick my head out for a second and say that I think
the
first code was more readable, with the end blocks. I LIKE being able to
clearly see the end of a logical block. Yes, I can see the indentation
change, but having a keyword end sections of code does a few things:

  1. It’s easier for me to read, especially if I’m just skimming through
  2. It’s easier to parse, and makes for cleaner parser code (to me, at
    least)

Come on guys, it’s only 3 characters. Pythonic indentation is a big
debate
among programming languages, so can’t we just accept it how it is and
move
on? Or, if someone really wants to change it, fork ruby and make the
change
yourself. Put up or shut up, is my (probably unwanted) opinion on the
subject.

Alex

On 5/27/09, Roger P. [email protected] wrote:

If you’re interested, please see:
endless.rb · GitHub

Could you post us a few examples of what code formatted this way looks

Oops, I should have done that when I posted before. Thanks for the
reminder.

#so you can leave off the end of a method
def a
c
d

#or anything else that requires an end
for i in 1…10
p i
pp i

#else and other keywords which start a subclause
#of a statement don’t cause an end if outdented at the same level
#as the if which controls them.
if a
b
else
c

#if you actually need an end, that’s allowed too
#(if not further outdented than the line that started the statement)
result = case ARGV[0]
when /^\d*$/
p “That’s an integer!”
when /^[A-Za-z]*$/
p “That’s a word!”
else
p “That’s something that’s not an integer or a word…”
end if ARGV[0]

#you can explicitly end just the last scope of something deeply nested.
class A
class B
class C
module D
foo
end #actually 4 ends

like (or must look like)? I assume it handles here documents well?

It should, since rubylexer does. I didn’t test them explicitly. Here
documents
appear like one giant string; the indentation levels of all lines
inside strings are ignored. (There might be some very obscure
here-document related bugs left in rubylexer which would bite you in
endless.rb as well, tho I can’t think of any right now. Most cases
should work. Here documents are weird.)

The italics part of that gist is somewhat hard to read :slight_smile:

I do apologize. It seems ok to me… What’s hard about it? (You can
always just hit the link for the raw view.)

#if you actually need an end, that’s allowed too
#(if not further outdented than the line that started the statement)
result = case ARGV[0]
when /^\d*$/
p “That’s an integer!”
when /^[A-Za-z]*$/
p “That’s a word!”
else
p “That’s something that’s not an integer or a word…”
end if ARGV[0]

#you can explicitly end just the last scope of something deeply nested.
class A
class B
class C
module D
foo
end #actually 4 ends

I assume that that end is optional, too?
end also doubles as the equivalent for Python’s “pass”, as well?
So you can have ends if you want them but they’re optional? Does it
work with {}'s too?
So the basic rule it uses is that if something returns to the original
indentation level without being an end, it assumes it should have been
an end, is that right? (i.e. it requires blocks to be at a greater
indentation level).
Thanks just wondering.
-=r