source code layout question
[1/25] from: joel:neely:fedex at: 4-Jan-2002 8:42
Hi, all,
WARNING #1: None of the code in this post is meaningful, and may
not even be legitimate. It's only included for
the purpose of illustration.
WARNING #2: This is a controversial and sensitive subject with
some folks. I'm not trying to start a flame war, and
I have not interest in debating aesthetic opinions. I *am* very
interested in objective criteria which identify strengths and
weaknesses of the alternatives.
That said...
I've recently been pondering source code layout. I, like many of
us on the list, have been writing REBOL in a style similar to the
following, which I'll call Style B:
foo: func [x [integer!] y [integer!] z [integer!]] [
either x = 0 [
z
][
either y = 0 [
head reverse z
][
while [x < y] [
y: y - x
append z "x"
]
foo y x z
]
]
]
This style is fairly conventional for block-structured languages
(i.e. descendants of Algol, including Pascal, c, Java, Perl, etc.)
Some programmers use a variation on this style, which I'll call
Style C:
foo: func [x [integer!] y [integer!] z [integer!]]
[
either x = 0
[z]
[
either y = 0
[head reverse z]
[
while [x < y]
[
y: y - x
append z "x"
]
foo y x z
]
]
]
LISP (and Scheme) programmers often use a bracketing style which
emphasizes the indentation of actual content, and relegates the
punctuation to a minor role. This approach would give us a
different look, which I'll call Style L:
foo: func [x [integer!] y [integer!] z [integer!]]
[either x = 0
[z]
[either y = 0
[head reverse z]
[while [x < y]
[y: y - x
append z "x"]
foo y x z]]]
REBOL isn't Algol, Lisp, or c (etc...), so perhaps its style is
not subject to the constraints of those languages. Here's my
assessment of some of the strengths and weaknesses of these
styles. (Again, I'm trying to deal with measurable features
and human factors, regardless of what I personally like or
dislike!) As all of these styles use indentation of source
text to show nesting, that issue is irrelevant to a contrast.
Style Pros Cons
----- ------------------------- -------------------------
B Familiar, even to people Deeply-nested code can
used to other common require lots of lines that
programming languages. only close blocks ("]").
Can be cut-and-pasted into May obscure distinctive
REBOL console, since open REBOL concepts (e.g., the
blocks signal that the brackets commonly written
current expression is not around WHILE arguments are
yet complete. not "required syntax" as
with c parentheses and/or
braces.
Easy to insert/delete lines
within a multi-line block
while revising code.
C Ease of insertion/deletion Requires more lines than
as with Style B. other styles to express the
same code.
L Keeps short blocks on the Long runs of "]" at the end
same line, thus saving of multiple nesting can be
vertical layout space. difficult to count (and get
correct.
Inserting/deleting block
content can require more
editing work.
I'm interested in any other comments on the objective pros/cons
of these styles.
For the sake of experiment, I've been experimenting with a hybrid
style, which I'll call Style R. It is intended to meet the
following criteria:
* Use indentation to make nesting visible (as do B, C, and L).
* Emphasize the idea of block-as-value (in contrast with the
keywords-with-required-punctuation implication of B and C).
* Avoid hard-to-read runs of punctuation (as in L).
* As far as possible, subordinate to the other criteria, use
as few lines as possible (to get the maximum code on a page
or within a window).
Guided by these criteria, the current state of Style R would
lay out the above sample code this way:
foo: func [x [integer!] y [integer!] z [integer!]]
[ either x = 0
[ z]
[ either y = 0
[ head reverse z]
[ while [x < y]
[ y: y - x
append z "x"
]
foo y x z
] ] ]
If one wanted to be polite and include help strings, the code
could be laid out as follows:
foo: func
[ "Computes a Euclid string for numeric data"
x [integer!] "major argument"
y [integer!] "corporal argument"
z [integer!] "seed string, modified by evaluation"
][ either x = 0
[ z]
[ either y = 0
[ head reverse z]
[ while [x < y]
[ y: y - x
append z "x"
]
foo y x z
] ] ]
Objective comments (i.e., something other that "That's the
ugliest thing I've ever seen!" or "Wow! You're an artist!" ;-)
are welcome!
-jn-
--
; sub REBOL {}; sub head ($) {@_[0]}
REBOL []
# despam: func [e] [replace replace/all e ":" "." "#" "@"]
; sub despam {my ($e) = @_; $e =~ tr/:#/.@/; return "\n$e"}
print head reverse despam "moc:xedef#yleen:leoj" ;
[2/25] from: al:bri:xtra at: 5-Jan-2002 6:10
Hi, Joel.
I prefer:
Foo: func [
"Computes a Euclid string for numeric data."
X [integer!] "Major argument."
Y [integer!] "Corporal argument."
Z [integer!] "Seed string, modified by evaluation."
][
either X = 0 [
Z
][
either Y = 0 [
head reverse Z
][
while [X < Y][
Y: Y - X
append Z "x"
]
foo Y X Z
]
]
]
Why?
* Title and Upper case for important words helps emphasize that these
words are defined here.
* Leading opening square bracket "[" allows cutting and pasting into
Rebol console.
* Block contents and trailing closing square bracket "]" all indented to
same level to visually confirm nesting.
* "][" for 'either provides visual cue for alternative case for 'either
and continued blocks for functions.
* For comments: Full stops inserted to make better sentences, along with
initial capital.
Andrew Martin
ICQ: 26227169 http://valley.150m.com/
[3/25] from: petr:krenzelok:trz:cz at: 4-Jan-2002 18:38
Joel Neely wrote:
>Hi, all,
>WARNING #1: None of the code in this post is meaningful, and may
<<quoted lines omitted: 5>>
>interested in objective criteria which identify strengths and
>weaknesses of the alternatives.
Why do you think it could lead to flamewar? :-) It isn't
rebo-2-another-lang comparison after all :-)
>That said...
>I've recently been pondering source code layout. I, like many of
<<quoted lines omitted: 15>>
> ]
> ]
OK, the rest of the code is cutted-off. I think that for me, only your B
varian is acceptable, with 2 small changes
- if something can be put on one line (one-liner), don't use new line
after starting "["
- don't put starting "[" on separate line, so:
foo: func [x [integer!] y [integer!] z [integer!]][
either x = 0 [z][
either y = 0 [head reverse z][
while [x < y][
y: y - x
append z "x"
]
foo y x z
]
] ;end either x = 0 - an example of comment, good for longer
nested stuff ...
]
as for example of longer either expression, probably something like this:
either x = 0 [
head reverse z
some other stuff here
][short stuff here]
either x = 0 [
head reverse z
some other stuff here
][
another at least two
lines of code
]
>Objective comments (i.e., something other that "That's the
>ugliest thing I've ever seen!" or "Wow! You're an artist!" ;-)
>are welcome!
>
That's the ugliest thing I've ever seen and yes, you are real rebol
artist :-))
-pekr-
[4/25] from: sunandadh:aol at: 4-Jan-2002 15:09
Hi Joel,
> I'm interested in any other comments on the objective pros/cons
> of these styles.
I tend to write code in your "Style C" with two minor mods:
1. I Function headers much closer to "R-polite"
2. I tend to use comments on closing brackets, especially if they are
well-separated from their opener:
] ; if
] ; func
It makes block indentation more obvious to me, and that is the clincher for
me.
But I usually "translate" code to style B before posting to the list so that
readers can cut'n'paste into the Console.
I guess what we need is not a holy war over formatting styles but
prettyprinter.r that will take arbitrary code and reformat it in various
ways. Mold sort of does that (to Style B only) but loses the comments.
I also guess a preferred formating style depends largely on what the expected
lifecycle of the code is. I assume code is a high maintenance item, and leave
it spaced out to make modifications (in my option) easier. As an example, I
was never convinced by Carl S's "mental reduction" example in Zine/2. He
reduces a Style B snippet:
either (mode) [
data: find data "Active"
][
data: find data "Passive"
]
to the one-liner:
data: find data either mode ["Active"]["Passive"]
Now that may be absolutely necessary in some circumstances where memory is
tight. But my instinctive reaction was: "Arrghh no! What if I then need to
perform an additional according to the value of 'mode?" The original is much
clearer as to where that additional code should go.
Sunanda.
[5/25] from: carl:cybercraft at: 5-Jan-2002 12:41
On 05-Jan-02, Joel Neely wrote:
> foo: func
> [ "Computes a Euclid string for numeric data"
<<quoted lines omitted: 11>>
> foo y x z
> ] ] ]
I rather like that, in that the relationship between the opening and
closing brackets is much easier to see than with conventional styles,
it creating obvious vertical lines. It's only drawbacks I think are
three extra spaces on some lines (minor) and not being able to cut
and paste it into the Console - a major disadvantage, I think. If
it wasn't for that, it'd be tempting to switch to it. And when
there's no nesting, the code becomes very clear...
if x = 0
[ y]
either a = b
[ c]
[ d]
while [h = i]
[ j k l]
for n 1 10 1
[ print n]
quit
My current style (such as it is:) is much the sames as Petr's,
('either's blocks being on one line being fine with me, though I see
your point in only allowing it with 'while's conditional block), so
I'd write...
foo: func [
"Computes a Euclid string for numeric data"
x [integer!] "major argument"
y [integer!] "corporal argument"
z [integer!] "seed string, modified by evaluation"
][
either x = 0 [z][
either y = 0 [head reverse z][
while [x < y][
y: y - x
append z "x"
]
foo y x z
]
]
]
And that's a line longer than your somewhat more clearer version. I
try not to have more than one evaluation on a line though, unless
they're within a block. So this I'd try to avoid - (usually:)...
while [x < y][y: y - x append z "x"]
Even though it'd save three lines.
Pity about the cutting and pasting problem Joel. ):
--
Carl Read
[6/25] from: ammonjohnson:yaho:o at: 4-Jan-2002 18:14
Carl Read wrote:
>On 05-Jan-02, Joel Neely wrote:
>> foo: func
<<quoted lines omitted: 20>>
>it wasn't for that, it'd be tempting to switch to it. And when
>there's no nesting, the code becomes very clear...
I will draw the line just a little closer to the middle:
foo: func [
"Computes a Euclid string for numeric data"
x [integer!] "major argument"
y [integer!] "corporal argument"
z [integer!] "seed string, modified by evaluation"
][
either x = 0 [z][
either y = 0 [head reverse z][
while [x < y][
y: y - x
append z "x"
]
foo y x z
] ] ]
Have the brackets begin on end of the line, but stack them at the end.
This will include the readability on the end while mantaining the
ability to cut & paste! I like, & I am convinced to switch. ;-)
Enjoy!!
Ammon
[7/25] from: carl:cybercraft at: 5-Jan-2002 13:19
On 05-Jan-02, Andrew Martin wrote:
> * Title and Upper case for important words helps emphasize that
> these words are defined here.
I used to use upper and lower case to distinguish variables from
function names and the like in previous languages, (leading lowercase
for variables, leading uppercase for functions or labels), but
dropped it in REBOL, "there only being words in REBOL". Here's an
example from one of my first REBOL scripts (before I'd been pointed
towards the style-guide - all non-REBOL words I'd give the uppercase
treatment to)...
NoChange: [
LowWait: WaitAmount
if WaitAmount < WaitMax [
WaitAmount: to-integer (WaitAmount * 2)
if WaitAmount > WaitMax [WaitAmount: WaitMax]
do UpdateSpeed
]
]
And how we're supposed to write it...
no-change: [
low-wait: wait-amount
if wait-amount < wait-max [
wait-amount: to-integer (wait-amount * 2)
if wait-amount > wait-max [wait-amount: wait-max]
do update-speed
]
]
Take your pick I guess, but the "proper" way seems easier on the eye
(and the shift-key:) though its look could depend a lot on the font
you're using I guess.
--
Carl Read
[8/25] from: philb:upnaway at: 5-Jan-2002 9:12
Hi Joel,
Well for good or bad I code pretty much in style B in all the langauges I use
C, C++, Progress, Rebol.
I just like my braces or square brackets lined up !!
Everything inside the brackets indented of course, unless it fits on a single line in
which case save some space by having the close bracket on the same line.
foo: func [x [integer!] y [integer!] z [integer!]]
[
either x = 0
[z]
[
either y = 0
[head reverse z]
[
while [x < y]
[
y: y - x
append z "x"
]
foo y x z
]
]
]
of course everyone will have their own variation on one of the styles.
Cheers Phil
=== Original Message ===
Hi, all,
WARNING #1: None of the code in this post is meaningful, and may
not even be legitimate. It's only included for
the purpose of illustration.
WARNING #2: This is a controversial and sensitive subject with
some folks. I'm not trying to start a flame war, and
I have not interest in debating aesthetic opinions. I *am* very
interested in objective criteria which identify strengths and
weaknesses of the alternatives.
That said...
I've recently been pondering source code layout. I, like many of
us on the list, have been writing REBOL in a style similar to the
following, which I'll call Style B:
foo: func [x [integer!] y [integer!] z [integer!]] [
either x = 0 [
z
][
either y = 0 [
head reverse z
][
while [x < y] [
y: y - x
append z "x"
]
foo y x z
]
]
]
This style is fairly conventional for block-structured languages
(i.e. descendants of Algol, including Pascal, c, Java, Perl, etc.)
Some programmers use a variation on this style, which I'll call
Style C:
foo: func [x [integer!] y [integer!] z [integer!]]
[
either x = 0
[z]
[
either y = 0
[head reverse z]
[
while [x < y]
[
y: y - x
append z "x"
]
foo y x z
]
]
]
LISP (and Scheme) programmers often use a bracketing style which
emphasizes the indentation of actual content, and relegates the
punctuation to a minor role. This approach would give us a
different look, which I'll call Style L:
foo: func [x [integer!] y [integer!] z [integer!]]
[either x = 0
[z]
[either y = 0
[head reverse z]
[while [x < y]
[y: y - x
append z "x"]
foo y x z]]]
REBOL isn't Algol, Lisp, or c (etc...), so perhaps its style is
not subject to the constraints of those languages. Here's my
assessment of some of the strengths and weaknesses of these
styles. (Again, I'm trying to deal with measurable features
and human factors, regardless of what I personally like or
dislike!) As all of these styles use indentation of source
text to show nesting, that issue is irrelevant to a contrast.
Style Pros Cons
----- ------------------------- -------------------------
B Familiar, even to people Deeply-nested code can
used to other common require lots of lines that
programming languages. only close blocks ("]").
Can be cut-and-pasted into May obscure distinctive
REBOL console, since open REBOL concepts (e.g., the
blocks signal that the brackets commonly written
current expression is not around WHILE arguments are
yet complete. not "required syntax" as
with c parentheses and/or
braces.
Easy to insert/delete lines
within a multi-line block
while revising code.
C Ease of insertion/deletion Requires more lines than
as with Style B. other styles to express the
same code.
L Keeps short blocks on the Long runs of "]" at the end
same line, thus saving of multiple nesting can be
vertical layout space. difficult to count (and get
correct.
Inserting/deleting block
content can require more
editing work.
I'm interested in any other comments on the objective pros/cons
of these styles.
For the sake of experiment, I've been experimenting with a hybrid
style, which I'll call Style R. It is intended to meet the
following criteria:
* Use indentation to make nesting visible (as do B, C, and L).
* Emphasize the idea of block-as-value (in contrast with the
keywords-with-required-punctuation implication of B and C).
* Avoid hard-to-read runs of punctuation (as in L).
* As far as possible, subordinate to the other criteria, use
as few lines as possible (to get the maximum code on a page
or within a window).
Guided by these criteria, the current state of Style R would
lay out the above sample code this way:
foo: func [x [integer!] y [integer!] z [integer!]]
[ either x = 0
[ z]
[ either y = 0
[ head reverse z]
[ while [x < y]
[ y: y - x
append z "x"
]
foo y x z
] ] ]
If one wanted to be polite and include help strings, the code
could be laid out as follows:
foo: func
[ "Computes a Euclid string for numeric data"
x [integer!] "major argument"
y [integer!] "corporal argument"
z [integer!] "seed string, modified by evaluation"
][ either x = 0
[ z]
[ either y = 0
[ head reverse z]
[ while [x < y]
[ y: y - x
append z "x"
]
foo y x z
] ] ]
Objective comments (i.e., something other that "That's the
ugliest thing I've ever seen!" or "Wow! You're an artist!" ;-)
are welcome!
-jn-
--
; sub REBOL {}; sub head ($) {@_[0]}
REBOL []
# despam: func [e] [replace replace/all e ":" "." "#" "@"]
; sub despam {my ($e) = @_; $e =~ tr/:#/.@/; return "\n$e"}
print head reverse despam "moc:xedef#yleen:leoj" ;
[9/25] from: ammonjohnson::yahoo at: 4-Jan-2002 19:22
I guess I like the middle road. ;-))
Here's how I would code it:
No-Change: [
Low-Wait: Wait-Amount
if Wait-Amount < Wait-Max [
Wait-Amount: To-Integer (Wait-Amount * 2)
if Wait-Amount > Wait-Max [Wait-Amount: Wait-Max]
do Update-Speed
]
]
Enjoy!!
Ammon
Carl Read wrote:
[10/25] from: joel:neely:fedex at: 4-Jan-2002 19:38
Hi, Carl,
Carl Read wrote:
> ... It's only drawbacks I think are three extra spaces on
> some lines (minor) ...
>
Those are there to make the content of multi-line blocks (or
multiple consecutive blocks, where some may be multi-line)
all line up indented under the controlling expression.
> and not being able to cut and paste it into the Console -
> a major disadvantage, I think. If it wasn't for that, it'd
> be tempting to switch to it...
>
Actually, I've been cutting and pasting with it (just with
a tad of cheating ;-). I simply type into the console
do [
then paste in whatever I've cut from wherever, then type a
final
]
and press return. That bit of extra typing (which does take
more effort than just using control-C...) wraps everything in
an extra attention-span-preserving block to keep the console's
attention until the input expression is explicitly closed by
the last right bracket.
> My current style (such as it is:) is much the sames as Petr's
...
> I'd write...
> either x = 0 [z][
<<quoted lines omitted: 6>>
> ]
> ]
I've tried that myself, but it seems to break the symmetry between
the two blocks managed by the EITHER. Conceptually I "see" them as
being at the same "level" under the control of the first argument
to EITHER; therefore I prefer a typographical structure that makes
them appear "side by side". Having one of them on the same line as
EITHER and the controlling expression versus the other being
indented below seems to hide their side-by-side relationship.
I've certainly written my share of
either blahblahblah [t-option][f-option]
when all will fit on one line, however.
-jn-
--
; sub REBOL {}; sub head ($) {@_[0]}
REBOL []
# despam: func [e] [replace replace/all e ":" "." "#" "@"]
; sub despam {my ($e) = @_; $e =~ tr/:#/.@/; return "\n$e"}
print head reverse despam "moc:xedef#yleen:leoj" ;
[11/25] from: philb:upnaway at: 5-Jan-2002 9:58
Hi Joel,
using the extra do [ before pasting is a really neat trick .... it will sure come in
handy.
Seems like the console was designed by/for people who code in style A
Cheers Phil
=== Original Message ===
Hi, Carl,
Carl Read wrote:
> ... It's only drawbacks I think are three extra spaces on
> some lines (minor) ...
>
Those are there to make the content of multi-line blocks (or
multiple consecutive blocks, where some may be multi-line)
all line up indented under the controlling expression.
> and not being able to cut and paste it into the Console -
> a major disadvantage, I think. If it wasn't for that, it'd
> be tempting to switch to it...
>
Actually, I've been cutting and pasting with it (just with
a tad of cheating ;-). I simply type into the console
do [
then paste in whatever I've cut from wherever, then type a
final
]
and press return. That bit of extra typing (which does take
more effort than just using control-C...) wraps everything in
an extra attention-span-preserving block to keep the console's
attention until the input expression is explicitly closed by
the last right bracket.
> My current style (such as it is:) is much the sames as Petr's
....
> I'd write...
> either x = 0 [z][
<<quoted lines omitted: 6>>
> ]
> ]
I've tried that myself, but it seems to break the symmetry between
the two blocks managed by the EITHER. Conceptually I "see" them as
being at the same "level" under the control of the first argument
to EITHER; therefore I prefer a typographical structure that makes
them appear "side by side". Having one of them on the same line as
EITHER and the controlling expression versus the other being
indented below seems to hide their side-by-side relationship.
I've certainly written my share of
either blahblahblah [t-option][f-option]
when all will fit on one line, however.
-jn-
--
; sub REBOL {}; sub head ($) {@_[0]}
REBOL []
# despam: func [e] [replace replace/all e ":" "." "#" "@"]
; sub despam {my ($e) = @_; $e =~ tr/:#/.@/; return "\n$e"}
print head reverse despam "moc:xedef#yleen:leoj" ;
[12/25] from: joel:neely:fedex at: 4-Jan-2002 20:15
Ooops, I forgot another bit of trivia from my past!
Carl Read wrote:
> I try not to have more than one evaluation on a line though,
> unless they're within a block. So this I'd try to avoid -
> (usually:)...
>
> while [x < y][y: y - x append z "x"]
>
Ordinarily I do as well, but sometimes I cheat... I remember
from my FORTH days (FORTH also eschews any pretense at syntax)
the convention of using horizontal whitespace to break a run
of words into "phrases", which might deal with the above
something like
while [x < y] [y: y - x append z "x"]
Just another option, but not one so easily automated!
-jn-
--
; sub REBOL {}; sub head ($) {@_[0]}
REBOL []
# despam: func [e] [replace replace/all e ":" "." "#" "@"]
; sub despam {my ($e) = @_; $e =~ tr/:#/.@/; return "\n$e"}
print head reverse despam "moc:xedef#yleen:leoj" ;
[13/25] from: carl:cybercraft at: 5-Jan-2002 15:41
On 05-Jan-02, [SunandaDH--aol--com] wrote:
> I also guess a preferred formating style depends largely on what the
> expected lifecycle of the code is. I assume code is a high
<<quoted lines omitted: 13>>
> 'mode?" The original is much clearer as to where that additional
> code should go.
Well, I was convinced, and I now find the one-line version easy and
natural to read. Also, adding any additional code /is/ simple...
data: find data either mode [a: 1 "Active"][b: 2 "Passive"]
or if you wish...
data: find data either mode [
a: 1
"Active"
][
b: 2
"Passive"
]
What that example shows is the added value a functional language gives
you, another being the ease with which you can capture interim
results of an evaluation. For instance...
data: find data d: either m: mode ["Active"]["Passive"]
would result in 'm holding what's returned by 'mode and 'd holding
either "Active" or "Passive". To do that your way would require
something like this...
m: mode
either m [
d: "Active"
data: find data d
][
d: "Passive"
data: find data d
]
or perhaps more sensibly...
m: mode
either m [
d: "Active"
][
d: "Passive"
]
data: find data d
which cuts out most of the repetition, but even so, I'd still prefer
this...
m: mode
d: either m ["Active"]["Passive"]
data: find data d
and would consider it more readable. (And yes, more readable than the
one-line version, but sometimes capturing interim results within an
expression is very useful, and that was more an example of the
usefulness of a functional language than the line's readability.)
--
Carl Read
[14/25] from: joel:neely:fedex at: 4-Jan-2002 20:41
Hi, to all who wrote about upper and lower case...
I freely admit that my bias against upper-case in programs is
purely personal and subjective. I cut my programming teeth
in the days of punched cards, punched paper tape, and KSR-33s
and KSR-35s (those were the days when we used real Teletype
clatter boxes as terminals, shoe-box-sized 110-baud modems
were high tech!)
To my eye, liberal sprinkling of upper-case characters is
reminiscent of a few things (none of which are My Favorite
Things ;-)
1) Antique I/0 (cards, teleprinters, greenscreens, and line
printers -- all of which were usually upper-case only).
2) Human-Readable Documents Produced People Who Don't Know
The Difference between titles and running text. (In my
college/university teaching days, I read *LOTS* of bad
term papers and essay tests!)
3) PEOPLE (INCLUDING SPAMMERS) WHO SHOUT IN EMAIL/NEWSGROUP
POSTINGS BECAUSE THEY HAVEN'T GOT A CLUE ABOUT MANNERS.
4) Legal documents that think that LOTS OF RUNNING TEXT IN
ALL CAPS IS SOMEHOW MORE IMPORTANT AND MORE LIKELY TO
BE READ when every typographic expert I've ever read
says that all-caps text is the least readable kind.
Everyone is welcome and entitled to his/her views, but I
think of upper-case as being similar to Jalapeno peppers
and Tabasco sauce (a little goes a long way, and none at
all is better than too much! ;-)
-jn-
--
; sub REBOL {}; sub head ($) {@_[0]}
REBOL []
# despam: func [e] [replace replace/all e ":" "." "#" "@"]
; sub despam {my ($e) = @_; $e =~ tr/:#/.@/; return "\n$e"}
print head reverse despam "moc:xedef#yleen:leoj" ;
[15/25] from: carl:cybercraft at: 5-Jan-2002 17:17
On 05-Jan-02, Joel Neely wrote:
> Hi, Carl,
> Carl Read wrote:
<<quoted lines omitted: 21>>
> attention until the input expression is explicitly closed by
> the last right bracket.
Ah - yes, that'd get us by. And example code to the list and such
could include the 'do and its brackets, thus allowing, ahem,
right-Amiga-C. (: I wonder what those at RT think of your style?
They may have thought of it and rejected it for some reason. Anyone
at RT listening? Two quite different styles amongst examples could
be confusing unless most people switch over...
--
Carl Read
[16/25] from: nitsch-lists:netcologne at: 5-Jan-2002 7:02
RE: [REBOL] Re: source code layout question
Hi Joel
[joel--neely--fedex--com] wrote:
<snip>
> Actually, I've been cutting and pasting with it (just with
<<quoted lines omitted: 8>>
> attention until the input expression is explicitly closed by
> the last right bracket.
clever :) inspired me to
vv: has[string][
string: read clipboard://
print string
do string
]
protect 'vv;avoid confusion..
now clip something and type "vv" in view-console :)
[17/25] from: carl:cybercraft at: 5-Jan-2002 19:33
On 05-Jan-02, [nitsch-lists--netcologne--de] wrote:
> vv: has[string][
> string: read clipboard://
<<quoted lines omitted: 3>>
> protect 'vv;avoid confusion..
> now clip something and type "vv" in view-console :)
Very nice - will be using it. (:
--
Carl Read
[18/25] from: nitsch-lists:netcologne at: 5-Jan-2002 9:53
RE: [REBOL] Re: source code layout question
[joel--neely--fedex--com] wrote:
> Ooops, I forgot another bit of trivia from my past!
> Carl Read wrote:
<<quoted lines omitted: 12>>
> while [x < y] [y: y - x append z "x"]
> Just another option, but not one so easily automated!
automation, hmm, giving upper-case-letters some extra-spaces?
while [x < y] [ Y: y - x Append z "x"]
where is my %clean-script.r ? :)
> -jn-
>
-Volker
[19/25] from: sunandadh:aol at: 5-Jan-2002 6:09
Hi Carl,
Sunanda:
> > I also guess a preferred formating style depends largely on what the
> > expected lifecycle of the code is. I assume code is a high
> > maintenance item, and leave it spaced out to make modifications (in
> > my option) easier. As an example, I was never convinced by Carl S's
> > "mental reduction" example in Zine/2.
Carl:
> Well, I was convinced, and I now find the one-line version easy and
> natural to read. Also, adding any additional code /is/ simple...
>
> data: find data either mode [a: 1 "Active"][b: 2 "Passive"]
It's easy to think up simple changes that would make the one-liner difficult
to maintain:
If Mode is True position Data at "Active", unless Mean is 5, in which case
leave Data's position unchanged
If Mode is False position data at "Passive" unless Median is unset, in which
case also unset Data
Or
If Mode is True and Data is a series position Data at "Active"; but if Data
is an integer, set it to zero.
The problem is that the one-liner makes two assumptions: first that Data is a
series; and second that the result of manipulating it should be a change in
its position). The longer code need make neither of these assumptions.
Whether those assumptions are reasonable or not is not something we can't
tell from such an artificial example. But I do try to write code remembering
that maintaining it is much harder than writing it. So if I've been as clever
as I possibly can in distilling it down to one-liners at time of writing, my
successors (including an older me) have little chance of maintaining it.
Maybe what we need is not just a prettyprinter.r but also an optimiser.r.
That can produce runtime code which is as densely one-lined as possible while
still functionally equivalent to the original. Any takers?
Sunanda.
[20/25] from: joel:neely:fedex at: 5-Jan-2002 9:23
HI, Carl and Sunanda,
Carl Read wrote:
> On 05-Jan-02, [SunandaDH--aol--com] wrote:
>
> > I also guess a preferred formating style depends largely on
> > what the expected lifecycle of the code is.
> >
I think that's a very important point; the cost of modifying the
code (at least for the most likely modifications) is certainly
a factor in choice of coding style.
> > ... I assume code is
> > a high maintenance item, and leave it spaced out to make
<<quoted lines omitted: 15>>
> Well, I was convinced, and I now find the one-line version easy and
> natural to read.
I think now we're talking about idioms (idiomata? ;-) Every language
(at least the non-trivial ones) in my experience has ways to express
things that are not immediately obvious to the cultural outsider,
and let's be honest about the fact that programming languages induce
cultural groupings just as much as the so-called "natural languages".
There's always a trade-off between expressing something in a manner
that almost anyone from any culture could understand vs. in a manner
that is recognizable to a native. To my view, this is another kind
of optimization -- maximizing the bandwidth (and recognition) between
writer and reader, rather than maximizing speed or memory economy.
And, of course, optimizations often have the effect of making code
more brittle or non-obvious.
> Also, adding any additional code /is/ simple...
>
> data: find data either mode [a: 1 "Active"][b: 2 "Passive"]
>
A nice example of a REBOL-specific use of multiple-expression blocks!
> What that example shows is the added value a functional language gives
> you, another being the ease with which you can capture interim
> results of an evaluation. For instance...
>
> data: find data d: either m: mode ["Active"]["Passive"]
>
...
> which cuts out most of the repetition, but even so, I'd still prefer
> this...
>
> m: mode
> d: either m ["Active"]["Passive"]
> data: find data d
>
But, to be fair, I think that layout can visually chunk the phrases
in the one-liner to make the internal structure more clear:
data: find data
d: either m: mode ["Active"] ["Passive"]
One could also expose the structure (though at a cost!) by using
parens:
data: find data (d: either (m: mode) ["Active"] ["Passive"])
I know I keep coming back to the issue of programming languages as
as media of communication between humans (with the convenient
side-effect that they is executable by a computer ;-), but my
experience in software development includes a huge portion of time
spent reading code that someone else (including an earlier copy of
myself ;-) wrote. When attention is given to making the goals and
meaning of the code self-evident (and I'm *NOT* talking about the
use of comments), the subsequent work is much more efficiently
performed.
Also, I believe it was K.F. Gauss who said,
"The purpose of computation is not numbers, but insight!"
which I thoroughly believe.
-jn-
--
; sub REBOL {}; sub head ($) {@_[0]}
REBOL []
# despam: func [e] [replace replace/all e ":" "." "#" "@"]
; sub despam {my ($e) = @_; $e =~ tr/:#/.@/; return "\n$e"}
print head reverse despam "moc:xedef#yleen:leoj" ;
[21/25] from: joel:neely:fedex at: 5-Jan-2002 9:24
Hi, Volker,
OUTSTANDING! I love it when people just make a problem go away!
[nitsch-lists--netcologne--de] wrote:
> ... inspired me to
> vv: has[string][
<<quoted lines omitted: 4>>
> protect 'vv;avoid confusion..
> now clip something and type "vv" in view-console :)
--
; sub REBOL {}; sub head ($) {@_[0]}
REBOL []
# despam: func [e] [replace replace/all e ":" "." "#" "@"]
; sub despam {my ($e) = @_; $e =~ tr/:#/.@/; return "\n$e"}
print head reverse despam "moc:xedef#yleen:leoj" ;
[22/25] from: jasonic:cunliffe:verizon at: 5-Jan-2002 1:29
> now clip something and type "vv" in view-console :)
yeay that's great!
./Jason
[23/25] from: richard-boyd:worldnet:att at: 5-Jan-2002 10:31
Very interesting post. Thanx.
I prefer the Python style ... which I find much easier to read.
Thus I format at per your Style C.
I try to hide the brackets as much as possible as I find them
distracting (and annoying) ... although they do help reading code such
as posted to the newsgroup.
But for my own code, I use TextPad with a REBOL syntax addon ... and
Ctl-M to navigate code for matching brackets.
I could live with your suggestion of Style R.
As far as Styles B & C ... I immediately reformat them!
-richard-
Joel Neely wrote:
[24/25] from: carl:cybercraft at: 6-Jan-2002 17:00
On 06-Jan-02, Joel Neely wrote:
> Hi, Volker,
> OUTSTANDING! I love it when people just make a problem go away!
And I reduced it to just...
vv: does [do read clipboard://]
(:
(I didn't find the printout helful.)
Hmmm, or should it be...
vv: does
[ do read clipboard://]
This might take a while to bed in Joel. (:
> [nitsch-lists--netcologne--de] wrote:
>>
<<quoted lines omitted: 8>>
>>
>> now clip something and type "vv" in view-console :)
--
Carl Read
[25/25] from: carl:cybercraft at: 6-Jan-2002 13:34
On 05-Jan-02, [SunandaDH--aol--com] wrote:
> Hi Carl,
> Sunanda:
<<quoted lines omitted: 29>>
> one-liners at time of writing, my successors (including an older me)
> have little chance of maintaining it.
It's all a question of how readable the one-liner ends up being. I'd
say to a REBOL programmer that...
result: either whatever-1 [whatever-2][whatever-3]
is as readable as...
either whatever-1 [
result: whatever-2
][
result: whatever-3
]
and probably more readable in fact. And as long as the one-liners are
readable and hence can be converted into a five-liner with next to no
thought, you have two payoffs due to a more efficient program and
code that occupies a lot less lines.
Look at the above two example: With the one-liner your eyes only need
to scan left and right to understand it, (like a quick scan of the
horizon), while with the five-liner our eyes are jumping back and
forth vertically as well as horizontally. Humans are designed for
reading one-liners... (:
But I'm serious about the above, and the "left-right scanning" may be
why Joel's...
either whatever-1
[ result: whatever-2]
[ result: whatever-3]
seems so attractive. Having the blocks all on one line where possible
is nice.
> Maybe what we need is not just a prettyprinter.r but also an
> optimiser.r. That can produce runtime code which is as densely
> one-lined as possible while still functionally equivalent to the
> original. Any takers?
No, in that I would think it's probably impossible with REBOL. For
instance, how would you optomize 'blk to allow for a later...
change blk whatever
Your "code" from REBOL's point of view is all just data, remember.
--
Carl Read
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted