POV-Ray : Newsgroups : povray.off-topic : GOTO Server Time
12 Oct 2026 22:43:47 EDT (-0400)
  GOTO (Message 1 to 36 of 36)  
From: Orchid XP v8
Subject: GOTO
Date: 15 Oct 2010 17:52:23
Message: <4cb8cd17$1@news.povray.org>
Oh wow. 42 years later, it still exists:

http://www.cs.utexas.edu/users/EWD/ewd02xx/EWD215.PDF

"Go to considered harmful."

Well there we are. I have to say, not the most convincing description of 
the problem I've ever seen.

I also note, with some interest, what looks suspiciously like Haskell 
syntax, in a letter typed 42 years ago. Obviously it's not after 
Haskell, but rather whatever mathematical formalism Haskell borrowed the 
notation from. Still, interesting none the less...)

-- 
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*


Post a reply to this message

From: Darren New
Subject: Re: GOTO
Date: 15 Oct 2010 18:05:14
Message: <4cb8d01a$1@news.povray.org>
Orchid XP v8 wrote:
> Oh wow. 42 years later, it still exists:
> 
> http://www.cs.utexas.edu/users/EWD/ewd02xx/EWD215.PDF
> 
> "Go to considered harmful."

I must say, I love how steampunk he sounds.

> Well there we are. I have to say, not the most convincing description of 
> the problem I've ever seen.

It's the difference between programming and computer science, is all. Plus, 
you probably grew up after things like while statements and if statements 
with actual bodies were common. Where do you think that came from? :-)

> I also note, with some interest, what looks suspiciously like Haskell 
> syntax, in a letter typed 42 years ago. Obviously it's not after 
> Haskell, but rather whatever mathematical formalism Haskell borrowed the 
> notation from. Still, interesting none the less...)

Did you look at that link I posted about the semantics of programming 
langauges?

-- 
Darren New, San Diego CA, USA (PST)
   Serving Suggestion:
     "Don't serve this any more. It's awful."


Post a reply to this message

From: andrel
Subject: Re: GOTO
Date: 15 Oct 2010 18:42:00
Message: <4CB8D8B7.3070404@gmail.com>
On 15-10-2010 23:52, Orchid XP v8 wrote:
> Oh wow. 42 years later, it still exists:
>
> http://www.cs.utexas.edu/users/EWD/ewd02xx/EWD215.PDF
>
> "Go to considered harmful."

also not the last paragraph in
http://www.cs.utexas.edu/users/EWD/transcriptions/EWD13xx/EWD1308.html


> Well there we are. I have to say, not the most convincing description of
> the problem I've ever seen.

That may be because you know what happened next *and* were not living at 
that time. Sort of like blaming Darwin that he failed to acknowledge the 
ribosome as evidence for evolution.

> I also note, with some interest, what looks suspiciously like Haskell
> syntax, in a letter typed 42 years ago. Obviously it's not after
> Haskell, but rather whatever mathematical formalism Haskell borrowed the
> notation from. Still, interesting none the less...)

What syntax specifically?

I think (but I was not yet part of the scene then) that people were 
looking for good notation. They knew that programming and mathematics 
had a lot in common. Yet things that were obvious in von Neumann 
machines (assignments and control flow statements in particular) did not 
have a direct counterpart in maths.
A problem that is not entirely solved even today. Haskell and other 
languages try to deal with it by restriction to a a paradigm that is 
closer to math than the imperative way of thinking. The downside of that 
is that problems that are easier solved in another paradigm become more 
complicated. Perhaps there are also people working on extending maths to 
include time-dependent behaviour.
Fact is that we as humans solve problems using a lot of techniques. 
Choosing whatever seems appropriate at the time. That is why I think a 
good programmer needs to be familiar with at least three or four 
different languages.


Post a reply to this message

From: Darren New
Subject: Re: GOTO
Date: 15 Oct 2010 18:53:56
Message: <4cb8db84$1@news.povray.org>
andrel wrote:
> at least three or four different languages.

Noting that C, C++, C#, Java, and Pascal are all "the same language" for 
these purposes. ;-)

-- 
Darren New, San Diego CA, USA (PST)
   Serving Suggestion:
     "Don't serve this any more. It's awful."


Post a reply to this message

From: nemesis
Subject: Re: GOTO
Date: 15 Oct 2010 22:55:01
Message: <web.4cb913268a3e2d77a197654e0@news.povray.org>
Orchid XP v8 <voi### [at] devnull> wrote:
> Oh wow. 42 years later, it still exists:
>
> http://www.cs.utexas.edu/users/EWD/ewd02xx/EWD215.PDF
>
> "Go to considered harmful."

a classic!  I'm glad you've been interested in the evolution of programming
formalisms -- and all by yourself!  Next on, the lambda papers! ;)

> I also note, with some interest, what looks suspiciously like Haskell
> syntax, in a letter typed 42 years ago. Obviously it's not after
> Haskell, but rather whatever mathematical formalism Haskell borrowed the
> notation from. Still, interesting none the less...)

bwahahahaha

you must be talking about `conditional expressions as introduced by J.McCarthy
("B1 -> E1, B2 -> E2,....., Bn -> En")'... although it looks like currying
haskell notation, it's actually what it's told:  John McCarthy's conditional
expressions for Lisp!

(cond
  ((null? ls) 0)
  ((zero? (car ls)) 0)
  (#t (/ n (car ls))))

cond was blowderized and adapted to all other programming languages in the
simplified form if-then-else... even Lisp provides it as well as cond!


Post a reply to this message

From: nemesis
Subject: Re: GOTO
Date: 15 Oct 2010 23:05:01
Message: <web.4cb915318a3e2d77a197654e0@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> andrel wrote:
> > at least three or four different languages.
>
> Noting that C, C++, C#, Java, and Pascal are all "the same language" for
> these purposes. ;-)

they are all Algol.


Post a reply to this message

From: nemesis
Subject: Re: GOTO
Date: 15 Oct 2010 23:05:01
Message: <web.4cb915f08a3e2d77a197654e0@news.povray.org>
"nemesis" <nam### [at] gmailcom> wrote:
> Orchid XP v8 <voi### [at] devnull> wrote:
> > Oh wow. 42 years later, it still exists:
> >
> > http://www.cs.utexas.edu/users/EWD/ewd02xx/EWD215.PDF
> >
> > "Go to considered harmful."
>
> a classic!  I'm glad you've been interested in the evolution of programming
> formalisms -- and all by yourself!  Next on, the lambda papers! ;)
>
> > I also note, with some interest, what looks suspiciously like Haskell
> > syntax, in a letter typed 42 years ago. Obviously it's not after
> > Haskell, but rather whatever mathematical formalism Haskell borrowed the
> > notation from. Still, interesting none the less...)
>
> bwahahahaha
>
> you must be talking about `conditional expressions as introduced by J.McCarthy
> ("B1 -> E1, B2 -> E2,....., Bn -> En")'... although it looks like currying
> haskell notation, it's actually what it's told:  John McCarthy's conditional
> expressions for Lisp!
>
> (cond
>   ((null? ls) 0)
>   ((zero? (car ls)) 0)
>   (#t (/ n (car ls))))
>
> cond was blowderized and adapted to all other programming languages in the
> simplified form if-then-else... even Lisp provides it as well as cond!

in other words:  "I am your father!" :D


Post a reply to this message

From: Warp
Subject: Re: GOTO
Date: 16 Oct 2010 04:11:10
Message: <4cb95e1e@news.povray.org>
Orchid XP v8 <voi### [at] devnull> wrote:
> "Go to considered harmful."

  Some people go to (pun semi-intended) extremes with the structured
programming paradigm and have the firm stance that anything even resembling
'goto' should be avoided, such as 'break', 'continue' and early returns
(iow. the only 'return' that a function can have is at the end of the
function, nowhere else). Likewise no "fall-through" in switch-case blocks
in languages like C (although this has less to do with goto-like statements
and more to do with structured programming).

  Sometimes this principle is good and leads in a natural way to imperative
code that is cleaner, simpler and easier to read. Othertimes, however, it
leads to the contrary. My favorite example is this (C++-like code, but the
same could be written in any imperative language supporting early returns):

Value* MyClass::searchForValue(const Value& value)
{
    for(size_t x = 0; x < mValues.size(); ++x)
        for(size_t y = 0; y < mValues[x].size(); ++y)
            for(size_t z = 0; z < mValues[x][y].size(); ++z)
                if(mValues[x][y][z] == value)
                    return &mValues[x][y][z];
    return 0;
}

  If you want to avoid the early return in that function, you have to
jump through quite many hoops, all of which make the code more complicated,
without making it any more readable.

  As a personal preference, I also prefer writing code like this:

int someFunction(param1, param2, param3)
{
    if(param1_is_not_ok) return error_code1;

    some_code; // code needed to see if param2 is ok
    if(param2_is_not_ok) return error_code2;

    more_code; // needed to see if param3 is ok
    if(param3_is_not_ok) return error_code3;

    significant_amount_of_code;
    return ok_code;
}

  Even though it could perfectly well be written without the early returns:

int someFunction(param1, param2, param3)
{
    int retval = ok_code;

    if(param1_is_not_ok) retval = error_code1;
    else
    {
        some_code; // code needed to see if param2 is ok
        if(param2_is_not_ok) retval = error_code2;
        else
        {
            more_code; // needed to see if param3 is ok
            if(param3_is_not_ok) retval = error_code3;
            else
            {
                significant_amount_of_code;
            }
        }
    }
    return retval;
}

  The more such error situations there could be, the more indentation the
code would require which is not only inconvenient but also IMO makes the
code less readable. (After all, in my preferred form all the error checking
is nicely at the same indentation level, rather than each subsequent check
being indented more than the previous.)

-- 
                                                          - Warp


Post a reply to this message

From: Orchid XP v8
Subject: Re: GOTO
Date: 16 Oct 2010 07:40:14
Message: <4cb98f1e$1@news.povray.org>
>> "Go to considered harmful."
>
> I must say, I love how steampunk he sounds.

With a name like "Edsger W. Dijkstra", I'm guessing English isn't his 
first language.

>> Well there we are. I have to say, not the most convincing description
>> of the problem I've ever seen.
>
> It's the difference between programming and computer science, is all.
> Plus, you probably grew up after things like while statements and if
> statements with actual bodies were common. Where do you think that came
> from? :-)

I don't pretend to know much about history. It just seems fairly 
self-evident that having formally organised stuff makes it easier to 
comprehend than unorganised stuff. Hell, if you said that phrase to 
somebody who knows nothing about computers, they'd probably agree with you.

> Did you look at that link I posted about the semantics of programming
> langauges?

When?

-- 
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*


Post a reply to this message

From: Darren New
Subject: Re: GOTO
Date: 16 Oct 2010 13:07:31
Message: <4cb9dbd3$1@news.povray.org>
Orchid XP v8 wrote:
>>> "Go to considered harmful."
>>
>> I must say, I love how steampunk he sounds.
> 
> With a name like "Edsger W. Dijkstra", I'm guessing English isn't his 
> first language.

Yes, I had considered that as well. He still gives a lovely victorian 
wording to high-tech building-automated-machinery, hence my observation.

> I don't pretend to know much about history. It just seems fairly 
> self-evident that having formally organised stuff makes it easier to 
> comprehend than unorganised stuff. 

Dijkstra is one of the few who figured out what "formally organized" means 
for imperative computer programs. He's the one who figured out how you can 
look at a program and say "this one will be easy to understand because it is 
well organized, and that one will be difficult because it is not well 
organized."  Indeed, "formally organized" is what he's defining in that paper.

>> Did you look at that link I posted about the semantics of programming
>> langauges?
> 
> When?

Probably a couple weeks back. Let me see if I can find it again.

Ah. There. 
http://web.archive.org/web/20040410154109/cs.wwc.edu/~aabyan/PLBook/HTML/Semantics.html


-- 
Darren New, San Diego CA, USA (PST)
   Serving Suggestion:
     "Don't serve this any more. It's awful."


Post a reply to this message

From: Darren New
Subject: Re: GOTO
Date: 16 Oct 2010 13:23:00
Message: <4cb9df74$1@news.povray.org>
Warp wrote:

There's really one primary problem with early returns, and that's handling 
things that ought be handled before the function returns, like deallocating 
memory, closing files, logging, etc.  In a decent language like C++, there's 
invisible bits of code stuck into your object code before each return (or, 
alternately, the compiler rewrites the return statement to be a goto to the 
end of the function). Without that, it requires somewhat more code to return 
early *and* clean up, to the point where skipping over blocks with flags 
might be more clear and maintainable than duplicating clean-up code. 
Especially if you want to DRY on the cleanup code.

Someone way back proved you could turn *any* control flow into structured 
flow, with enough booleans and repeated code. That doesn't mean it's a good 
idea.

And of course, this is all local to a fairly small function. Think about a 
program with significant amounts of control flow using setjmp/longjmp, or 
where gotos can go to any label anywhere in a program, and you get the idea 
of what Dr D was arguing against.

It turns out that what's really formally the problem is more the labels than 
the gotos. The problem is if you look at the preconditions of the label, 
it's an amalgamation of all the postconditions of every goto that goes to 
that label. You can't look at the line before the label and the line after 
the label and know *anything* about any of the variables or program state 
when you reach the line after the label, unless you hunt down and analyze 
every goto as well.

 > Likewise no "fall-through" in switch-case blocks in languages like C

I like how C# handles this.  Each branch has to end with either a break or a 
goto X, where X is one of the labels of the switch. So you can rearrange the 
order of the branches, insert branches in the middle, etc, and not break 
anything. And you can't accidentally fall through to the next case and bring 
down the entire east coast telecommunication infrastructure. ;-)

>   The more such error situations there could be, the more indentation the
> code would require which is not only inconvenient but also IMO makes the
> code less readable.

I find another way of doing this also works. My own invention:

bool worked = true;
if (worked) worked = try_thing_one();
if (worked) { reset_flobulator(); worked = query_flobulator(); }
if (worked) worked = yidda < 27;
clean_up_temps();
return worked;

and so on. Each block of work can be rearranged, nothing runs and it falls 
out very quickly on failure, everything inline, everything's indented only 
one, yet it's pretty easy to follow what's going on. And of course if you 
want specific error codes, that works just as easily.

-- 
Darren New, San Diego CA, USA (PST)
   Serving Suggestion:
     "Don't serve this any more. It's awful."


Post a reply to this message

From: Darren New
Subject: Re: GOTO
Date: 16 Oct 2010 13:24:00
Message: <4cb9dfb0$1@news.povray.org>
nemesis wrote:
> Darren New <dne### [at] sanrrcom> wrote:
>> andrel wrote:
>>> at least three or four different languages.
>> Noting that C, C++, C#, Java, and Pascal are all "the same language" for
>> these purposes. ;-)
> 
> they are all Algol.

Basically, yes.  Altho I'd say OO, and maybe some of the stuff in Ada are 
things you should know about algol-like languages.

You should also learn APL, LISP, Prolog, Erlang, Eiffel, and some machine code.

-- 
Darren New, San Diego CA, USA (PST)
   Serving Suggestion:
     "Don't serve this any more. It's awful."


Post a reply to this message

From: nemesis
Subject: Re: GOTO
Date: 16 Oct 2010 13:40:06
Message: <web.4cb9e2ad8a3e2d77a197654e0@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> nemesis wrote:
> > Darren New <dne### [at] sanrrcom> wrote:
> >> andrel wrote:
> >>> at least three or four different languages.
> >> Noting that C, C++, C#, Java, and Pascal are all "the same language" for
> >> these purposes. ;-)
> >
> > they are all Algol.
>
> Basically, yes.  Altho I'd say OO, and maybe some of the stuff in Ada are
> things you should know about algol-like languages.
>
> You should also learn APL, LISP, Prolog, Erlang, Eiffel, and some machine code.

I'd put Perl and Haskell into the mix too.


Post a reply to this message

From: Darren New
Subject: Re: GOTO
Date: 16 Oct 2010 13:49:49
Message: <4cb9e5bd@news.povray.org>
nemesis wrote:
> Darren New <dne### [at] sanrrcom> wrote:
>> nemesis wrote:
>>> Darren New <dne### [at] sanrrcom> wrote:
>>>> andrel wrote:
>>>>> at least three or four different languages.
>>>> Noting that C, C++, C#, Java, and Pascal are all "the same language" for
>>>> these purposes. ;-)
>>> they are all Algol.
>> Basically, yes.  Altho I'd say OO, and maybe some of the stuff in Ada are
>> things you should know about algol-like languages.
>>
>> You should also learn APL, LISP, Prolog, Erlang, Eiffel, and some machine code.
> 
> I'd put Perl and Haskell into the mix too.

Yeah, I was trying to remember some of the others. Something perl-like, 
certanily (python, Perl, bash, Tcl, etc).  FORTH.  Haskell or some other 
very functional language, for sure.

The thing about APL, LISP, FORTH, and Tcl is they're all simple enough that 
once you have a few under your belt, you can learn them well enough to 
understand the principles rather easily, even if it's not obvious the best 
way to write large programs.  Of course, writing large programs is where 
having the alternate paradigms can shine (or collapse), so that might not be 
a recommendation there.

-- 
Darren New, San Diego CA, USA (PST)
   Serving Suggestion:
     "Don't serve this any more. It's awful."


Post a reply to this message

From: Patrick Elliott
Subject: Re: GOTO
Date: 16 Oct 2010 14:08:05
Message: <4cb9ea05$1@news.povray.org>
On 10/15/2010 7:51 PM, nemesis wrote:
> Orchid XP v8<voi### [at] devnull>  wrote:
>> Oh wow. 42 years later, it still exists:
>>
>> http://www.cs.utexas.edu/users/EWD/ewd02xx/EWD215.PDF
>>
>> "Go to considered harmful."
>
> a classic!  I'm glad you've been interested in the evolution of programming
> formalisms -- and all by yourself!  Next on, the lambda papers! ;)
>
>> I also note, with some interest, what looks suspiciously like Haskell
>> syntax, in a letter typed 42 years ago. Obviously it's not after
>> Haskell, but rather whatever mathematical formalism Haskell borrowed the
>> notation from. Still, interesting none the less...)
>
> bwahahahaha
>
> you must be talking about `conditional expressions as introduced by J.McCarthy
> ("B1 ->  E1, B2 ->  E2,....., Bn ->  En")'... although it looks like currying
> haskell notation, it's actually what it's told:  John McCarthy's conditional
> expressions for Lisp!
>
> (cond
>    ((null? ls) 0)
>    ((zero? (car ls)) 0)
>    (#t (/ n (car ls))))
>
> cond was blowderized and adapted to all other programming languages in the
> simplified form if-then-else... even Lisp provides it as well as cond!
>
>
Snort.. While the above is slightly annoying (though only due to the 
fact that I prefer a syntax which is marginally clearer, if only just.., 
claiming that if-then-else is simpler is just flat wrong. Lot of extra 
typing to get you where you are going, when something closer to the 
original, like one languages 'switch' statement makes a lot more sense. 
But, it only gets worse when some joker does what was done in a few 
versions of basic (Apple Basic being one of them), and lost the else, or 
denied use of more than one else, by disallowing 'else if', etc.

Definitely times when I seriously *hate* if-then-else, even if the 
result is, theoretically, the same.

-- 
void main () {
   If Schrödingers_cat is alive or version > 98 {
     if version = "Vista" {
       call slow_by_half();
       call DRM_everything();
     }
     call functional_code();
   }
   else
     call crash_windows();
}

<A HREF='http://www.daz3d.com/index.php?refid=16130551'>Get 3D Models, 
3D Content, and 3D Software at DAZ3D!</A>


Post a reply to this message

From: Warp
Subject: Re: GOTO
Date: 16 Oct 2010 14:22:18
Message: <4cb9ed59@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> There's really one primary problem with early returns, and that's handling 
> things that ought be handled before the function returns, like deallocating 
> memory, closing files, logging, etc.  In a decent language like C++, there's 
> invisible bits of code stuck into your object code before each return (or, 
> alternately, the compiler rewrites the return statement to be a goto to the 
> end of the function). Without that, it requires somewhat more code to return 
> early *and* clean up, to the point where skipping over blocks with flags 
> might be more clear and maintainable than duplicating clean-up code. 
> Especially if you want to DRY on the cleanup code.

  Maybe the fact that C++ basically removed the need for manual cleanup of
resources (if you use its constructs properly) made it much safer and
cleaner to use early returns. Early returns would indeed be a hazard in C,
where there's no automatic scope-based cleanup mechanism.

  It's not just memory. It's anything that needs to be released after use,
such as for example file handles. In C++ it's completely safe to do things
like:

void foo()
{
    std::ifstram is("file.txt");
    do_something;
    if(error) return;
    do_something_else;
    if(another_error) return;
    do_more;
}

  There's no need to clean up 'is' (ie. close the file handle) because it
will clean up itself when its scope ends. This is not possible in C (where
you always have to manually make sure it gets closed when the function is
exited).

  (This is actually important because in C++ the function might be exited
at surprising places, even without explicit early returns, namely if
something throws an exception. The above code is exception-safe because
the file will be closed even if anything inside the function unexpectedly
throws.)

  If you see something like this in C++:

void foo()
{
    FILE* infile = std::fopen("file.txt", "r");

then you should immediately see "DANGER! DANGER!", because whatever follows
that will *not* be exception-safe (well, not unless the very next line is
'try').

-- 
                                                          - Warp


Post a reply to this message

From: andrel
Subject: Re: GOTO
Date: 16 Oct 2010 15:30:18
Message: <4CB9FD4B.8010105@gmail.com>
On 16-10-2010 4:51, nemesis wrote:
> Orchid XP v8<voi### [at] devnull>  wrote:
>> Oh wow. 42 years later, it still exists:
>>
>> http://www.cs.utexas.edu/users/EWD/ewd02xx/EWD215.PDF
>>
>> "Go to considered harmful."
>
> a classic!  I'm glad you've been interested in the evolution of programming
> formalisms -- and all by yourself!  Next on, the lambda papers! ;)
>
>> I also note, with some interest, what looks suspiciously like Haskell
>> syntax, in a letter typed 42 years ago. Obviously it's not after
>> Haskell, but rather whatever mathematical formalism Haskell borrowed the
>> notation from. Still, interesting none the less...)
>
> bwahahahaha
>
> you must be talking about `conditional expressions as introduced by J.McCarthy
> ("B1 ->  E1, B2 ->  E2,....., Bn ->  En")'... although it looks like currying
> haskell notation, it's actually what it's told:  John McCarthy's conditional
> expressions for Lisp!
>
> (cond
>    ((null? ls) 0)
>    ((zero? (car ls)) 0)
>    (#t (/ n (car ls))))
>
> cond was blowderized and adapted to all other programming languages in the
> simplified form if-then-else... even Lisp provides it as well as cond!

Dijkstra's guarded commands does not have a if-then-else, I know it is a 
rather obscure language, but not in this context.

I find the if-then-else case interesting because it shows so clearly 
that there was a trade off between having a language that has some 
relation to maths and one that is understandable for below average IQ 
humans*. Dijstra's version, the McCarthy version he mentions here and 
the LISP version all are homologues of the disjuction. If-then-else is 
more like human reasoning using a decision tree. I am not surprised that 
the latter is the more common now, but I don't think I am happy with it.

*) there is also that if-then-else is more close to the conditional jump 
of most processors at the machine level, but mentioning that might spoil 
my point.


Post a reply to this message

From: Warp
Subject: Re: GOTO
Date: 16 Oct 2010 15:58:01
Message: <4cba03c8@news.povray.org>
Warp <war### [at] tagpovrayorg> wrote:
>   If you see something like this in C++:

> void foo()
> {
>     FILE* infile = std::fopen("file.txt", "r");

> then you should immediately see "DANGER! DANGER!", because whatever follows
> that will *not* be exception-safe (well, not unless the very next line is
> 'try').

  By the way, I honestly wonder what's the "proper" way of doing that
in Java, given that Java has exceptions and no scope-bound lifetime of
objects. Do you always have to follow file handle creation with a 'try'
block to guard against exceptions? Or is there some other trick to make
such code exception-safe?

  (I understand that in C# this is handled with a 'using' block, which
automatically and immediately disposes of objects when the block is
exited. Is that the proper way of making file handles exception-safe
there?)

-- 
                                                          - Warp


Post a reply to this message

From: Darren New
Subject: Re: GOTO
Date: 16 Oct 2010 16:41:53
Message: <4cba0e11$1@news.povray.org>
Patrick Elliott wrote:
> But, it only gets worse when some joker does what was done in a few 
> versions of basic 

Roll back to when BASIC actually was edited line by line, with line numbers 
and all that, and the only form of the IF statement was

300 IF Z < W THEN 500 ELSE 800



-- 
Darren New, San Diego CA, USA (PST)
   Serving Suggestion:
     "Don't serve this any more. It's awful."


Post a reply to this message

From: Darren New
Subject: Re: GOTO
Date: 16 Oct 2010 16:52:13
Message: <4cba107d$1@news.povray.org>
Warp wrote:
>   Maybe the fact that C++ basically removed the need for manual cleanup of
> resources (if you use its constructs properly) made it much safer and
> cleaner to use early returns.

Exactly the point I'm making. In C++, "return" doesn't mean return from the 
function any more. It means basically "branch to all the clean-up code for 
anything allocated in any of the scopes I'm nested in." :-)

>   If you see something like this in C++:

Yep. Rather than "checked and unchecked exceptions", I think Java (and C#) 
would have been better off issuing warnings or errors for potential leaks of 
disposable items.

If you have a file handle in C#, you're supposed to put it inside a "using" 
so it gets closed if you exit the scope.

using (FileHandle handle = File.Open(...))
{
    handle.read(); handle.write(); ...
}

Any time you exit the block after you've created the file handle, it'll get 
cleaned up (in the sense that the Dispose call will be made).  Kind of 
poor-man's C++ destructors.  If they were going to do that, they should have 
put in some mechanism to keep you from accidentally making a handle (or 
anything else that inherits Disposable) without clearly disposing it.

Sing# does something much like this by basically making it so that kind of 
object can't get assigned to more than one variable at once (i.e., you can't 
have two pointers/references to the same value), and it tracks and enforces 
this at compile time. So "File.Open" would declare it returns a new file 
handle, "File.Close" would declare it consumes the handle, and everything in 
between would be unable to overwrite it or copy it or whatever (outside of, 
of course, passing it to subroutines, etc).

The destructor semantics is one of the things I think C++ really did get 
just right.  It's really all the C compatibility that makes it awkward, I find.

-- 
Darren New, San Diego CA, USA (PST)
   Serving Suggestion:
     "Don't serve this any more. It's awful."


Post a reply to this message

From: Darren New
Subject: Re: GOTO
Date: 16 Oct 2010 16:58:22
Message: <4cba11ee@news.povray.org>
Warp wrote:
>   By the way, I honestly wonder what's the "proper" way of doing that
> in Java, given that Java has exceptions and no scope-bound lifetime of
> objects. 

try {
handle = open(...);
} finally {
if (handle != null) handle.close();
}

Even uglier because you obviously have to declare the handle outside the 
block, check to see if the assignment worked, etc.

 > Do you always have to follow file handle creation with a 'try'
> block to guard against exceptions? Or is there some other trick to make
> such code exception-safe?

try/finally is what you use for making code exception safe.

>   (I understand that in C# this is handled with a 'using' block, which
> automatically and immediately disposes of objects when the block is
> exited. Is that the proper way of making file handles exception-safe
> there?)

Yep. You're basically supposed to put anything with a "Dispose" method 
inside a using block. (Well, unless you're assigning it to something more 
global, etc.)  More elegant than Java, but certainly not elegant, especially 
since it's not always obvious what classes have a Dispose method without 
reading the documentation, so it's easy to miss something if you're working 
with a new library.

-- 
Darren New, San Diego CA, USA (PST)
   Serving Suggestion:
     "Don't serve this any more. It's awful."


Post a reply to this message

From: Darren New
Subject: Re: GOTO
Date: 16 Oct 2010 17:00:11
Message: <4cba125b$1@news.povray.org>
Darren New wrote:
> and everything in between would be unable to overwrite it or 
> copy it or whatever (outside of, of course, passing it to subroutines, 
> etc).

Well, not quite. I mean, there are a lot of rules making it usable, but 
they're the obvious rules. (You can overwrite the value with a newly 
allocated value if you dispose of the old value in the same routine, etc.)

-- 
Darren New, San Diego CA, USA (PST)
   Serving Suggestion:
     "Don't serve this any more. It's awful."


Post a reply to this message

From: nemesis
Subject: Re: GOTO
Date: 16 Oct 2010 18:50:00
Message: <web.4cba2b4d8a3e2d77a197654e0@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> Yeah, I was trying to remember some of the others. Something perl-like,
> certanily (python, Perl, bash, Tcl, etc).

python, perl and tcl are very unlike each other despite the scripting moniker.
While I dig python better for the crystal-crisp syntax and iteration constructs,
perl is much more formidable as far as plain linguistic flexibility goes... it
truly is a marvel to behold in all of its C, shell, Lisp, forth summarizing of
ideas goes...


Post a reply to this message

From: Darren New
Subject: Re: GOTO
Date: 16 Oct 2010 19:48:10
Message: <4cba39ba@news.povray.org>
nemesis wrote:
> Darren New <dne### [at] sanrrcom> wrote:
>> Yeah, I was trying to remember some of the others. Something perl-like,
>> certanily (python, Perl, bash, Tcl, etc).
> 
> python, perl and tcl are very unlike each other despite the scripting moniker.

Fairly so, yes. But the concepts of a "scripting language" (i.e., the 
primary data structure being a hashtable, the idea that "evaluating a 
definition" is pretty much what creates code rather than strictly 
compilation, the baroque scoping rules, etc) is what's more important than 
the fact that (for example) regex is a literal in Perl and not in the others.

> truly is a marvel to behold in all of its C, shell, Lisp, forth summarizing of
> ideas goes...

Errr, Perl has something to do with FORTH?  You'll have to clarify that one, 
because, like, it really doesn't, as far as I can tell.


-- 
Darren New, San Diego CA, USA (PST)
   Serving Suggestion:
     "Don't serve this any more. It's awful."


Post a reply to this message

From: nemesis
Subject: Re: GOTO
Date: 17 Oct 2010 07:00:01
Message: <web.4cbad67a8a3e2d77a197654e0@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> nemesis wrote:
> > Darren New <dne### [at] sanrrcom> wrote:
> >> Yeah, I was trying to remember some of the others. Something perl-like,
> >> certanily (python, Perl, bash, Tcl, etc).
> >
> > python, perl and tcl are very unlike each other despite the scripting moniker.
>
> Fairly so, yes. But the concepts of a "scripting language" (i.e., the
> primary data structure being a hashtable, the idea that "evaluating a
> definition" is pretty much what creates code rather than strictly
> compilation, the baroque scoping rules, etc) is what's more important than
> the fact that (for example) regex is a literal in Perl and not in the others.

regex is a literal in ruby too.  I also like perl scoping with my and our. :)

> > truly is a marvel to behold in all of its C, shell, Lisp, forth summarizing of
> > ideas goes...
>
> Errr, Perl has something to do with FORTH?  You'll have to clarify that one,
> because, like, it really doesn't, as far as I can tell.

like forth, it doesn't need to operate on named arguments, which is taken then
to be the first in the "stack"... :)


Post a reply to this message

From: Warp
Subject: Re: GOTO
Date: 17 Oct 2010 08:57:35
Message: <4cbaf2bf@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> The destructor semantics is one of the things I think C++ really did get 
> just right.

  The proper name for that mechanism would be "RAII" (which might be
somewhat of a misnomer, as it doesn't fully express what it means).

  (In principle RAII is not incompatible with garbage collection, so
conceivably you could have both in the same language.)

  According to wikipedia, C++ is not the only language using RAII, and
mentions Ada as another one. I didn't know that.

-- 
                                                          - Warp


Post a reply to this message

From: Darren New
Subject: Re: GOTO
Date: 17 Oct 2010 13:00:00
Message: <4cbb2b90@news.povray.org>
nemesis wrote:
> like forth, it doesn't need to operate on named arguments, which is taken then
> to be the first in the "stack"... :)

Uh, OK. That's, like, the absolute least important bit of FORTH there, but 
OK. :-)  I think that's more shell syntax than FORTH syntax, really.

-- 
Darren New, San Diego CA, USA (PST)
   Serving Suggestion:
     "Don't serve this any more. It's awful."


Post a reply to this message

From: Darren New
Subject: Re: GOTO
Date: 17 Oct 2010 13:26:03
Message: <4cbb31ab$1@news.povray.org>
Warp wrote:
> Darren New <dne### [at] sanrrcom> wrote:
>> The destructor semantics is one of the things I think C++ really did get 
>> just right.
> 
>   The proper name for that mechanism would be "RAII" (which might be
> somewhat of a misnomer, as it doesn't fully express what it means).

I think the two are separate, but "RAII" is the best (maybe even "intended") 
way to use the C++ destructor semantics. Certainly the semantics don't 
change if you screw up your RAII. :-)

>   (In principle RAII is not incompatible with garbage collection, so
> conceivably you could have both in the same language.)

Indeed. Especially if you use something like reference counting and deal 
with circular references specially or something. Unfortunately, the fastest 
garbage collectors are the ones that never touch the garbage, so it's hard 
to do this well without having basically a separate heap for objects with 
non-memory destructors, which I think is what we'll eventually start seeing 
in some of these run-time implementations, if we don't start seeing GC-smart 
operating systems first.  (And I'd even count Erlang in that latter 
categorization, since all interaction outside the Erlang semantics goes thru 
a "port" kind of construct rather than a function call kind of construct.)

>   According to wikipedia, C++ is not the only language using RAII, and
> mentions Ada as another one. I didn't know that.

I think that's ... stretching it a bit. Sounds like Ada folks trying to 
convince C++ folks they should switch or something. :-)

Ada is very non-orthogonal in its data structures (even more so than C++). 
Objects are basically declared as "records with a vtable" or so, and if your 
data type isn't a type of record (in the Pascal/Algol sense of the word, or 
what C would call a struct), then you don't get to make it an object.

Ah. They're called "controlled types."

http://www.adaic.org/docs/95style/html/sec_9/9-2-3.html

Basically, an object type that inherits from Ada.Finalization.Controlled. 
Inheriting from that type gives you three methods: Initialize, Finalize and 
Adjust. Finalize is like the destructor, and Adjust is sort of like a 
copy/assignment constructor, only more limited. (When you assign to a 
controlled type, it copies all the hardware bits, then invokes Adjust on the 
copy. You don't get to change what you assigned *from*, because that would 
be confusing. Use a procedure with two in/out arguments for that. :-)

However, this only applies to objects derived from Controlled. It doesn't 
work with strings, arrays, any of the built-in collections, files, tasks, 
loadable packages, pointers, etc etc etc. Ada is really pretty 
non-orthogonal in that sense. You can't mix and match. (Yes, that sucks. :-)

I.e., much like you can't have constructors and destructors on pointers or 
integers in C++, except even for some very complicated types in Ada.

Note that any type can be declared "limited" too, which basically means the 
assignment operator is private. A record that can do inheritance (i.e., that 
has a vtable) is called a "tagged type". In case you get interested and read 
some of the following pages. :-)  Note that "class type X" means "X and all 
its descendants" as opposed to "type X" which means just type X. Declaring a 
procedure with an argument that is a class type is how you get run-time 
dynamic inheritance-based dispatch as opposed to overloading.  The "with 
private" declaration is like declaring something "struct xyz;" in C or C++. 
A "protected" type is basically a monitor in the multitasking definition of 
the word.

Blah'goop is a way of getting the goop property or type out of the blah 
variable or type. So myarray'length, or mytaggedtype'parent, or 
localvariable'address (&localvariable) or something like that.

Ada has some very unusual yet precise terminology. It's fun to read a 
sentence talking about a controlled atomic volatile protected limited class 
type and have an idea of what that means. ;-)

-- 
Darren New, San Diego CA, USA (PST)
   Serving Suggestion:
     "Don't serve this any more. It's awful."


Post a reply to this message

From: Warp
Subject: Re: GOTO
Date: 17 Oct 2010 14:34:37
Message: <4cbb41bd@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> >   (In principle RAII is not incompatible with garbage collection, so
> > conceivably you could have both in the same language.)

> Indeed. Especially if you use something like reference counting and deal 
> with circular references specially or something.

  What I meant is that, for example in C++, it's possible to have value
semantics for objects as well as reference (well, pointer) semantics for
objects, and these can be kept pretty much separate. Then you can have
RAII (iow. scope-based lifetime) semantics on the objects and GC on the
references. There are, in fact, GC engines for C++ which work like this
(basically, anything you allocate dynamically with 'new' can be GC'd,
while anything you allocate without it uses regular RAII semantics).

  On a different note, one example where I think the RAII mechanism is
better than the Java-style GC mechanism is that RAII allows you to
implement copy-on-write semantics (ie. "lazy copying") for objects.
In other words, if you have some object with potentially lots of data,
and you want to use copy semantics for it (ie. if you assign the object
to another, the latter gets a copy of the data rather than sharing the
data), copy-on-write makes the copying lazily, only if needed (ie. only
if one of the copies tries to modify the data).

  For instance, assume that std::string used copy-on-write (which it does
in some implementations). If you write this:

    std::vector<std::string> strings(1000, "hello there");

you will have a vector of 1000 strings, each one with the value "hello
there". However, the actual "hello there" data is shared among all the
strings and hence stored in memory only once (which may become a significant
saving if it would be kilobytes or megabytes of data instead of just 11
characters). However, if you now do something like:

    strings[250] += ", world";

only the 251st string in the vector will be converted to "hello there, world"
rather than all of them. The rest of the string will still share that one
and same data, and only the 251st string will now have its own copy of the
data, with more data appended.

  What happened there is that the 251st string made a deep-copy of the data
before modifying it, thus preventing any of the other strings from changing.

  Of course if you now modify it again:

    strings[250] += "!";

it will *not* perform a needless deep-copy of the data because the current
data is not shared. In other words, it will deep-copy the data only when
needed.

  And most importantly, it will do that completely transparently. You can't
see that from the outside. From the outside std::string simply has copy
semantics and that's it. You could compile the program with a different
implementation of std::string which does not use CoW, and it would still
work the same (except, obviously, now consuming more memory).

  Of course CoW requires reference counting of the data (or, more precisely,
it needs a way to tell if the data is being shared or not). I don't know
how you would do that in Java (transparently, or at all).

  This is possible transparently in C++ because of RAII: When objects are
created, copied, assigned and destroyed, you can specify what happens.
This allows you to keep a reference count on the data handled by the class.

  (And note that I'm not saying there aren't advantages with a GC system
like the one in Java, including efficiency benefits in some situations.)

-- 
                                                          - Warp


Post a reply to this message

From: Darren New
Subject: Re: GOTO
Date: 17 Oct 2010 15:10:12
Message: <4cbb4a14$1@news.povray.org>
Warp wrote:
> Darren New <dne### [at] sanrrcom> wrote:
>> Indeed. Especially if you use something like reference counting and deal 
>> with circular references specially or something.
> 
>   What I meant is that,

Oh, I see. Yes, I guess that would work. Probably an excellent way to do it, 
especially if you store enough info about things that you can do compacting 
collections.

>   On a different note, one example where I think the RAII mechanism is
> better than the Java-style GC mechanism is that RAII allows you to
> implement copy-on-write semantics (ie. "lazy copying") for objects.

I understand what you're saying, but this is a bad example for Java because 
that's exactly how it would work in Java, because strings are immutable, so 
your "+=" returns a brand new string. :-)  That's why Java has a 
StringBuilder as well as a String.

>   Of course CoW requires reference counting of the data (or, more precisely,
> it needs a way to tell if the data is being shared or not). I don't know
> how you would do that in Java (transparently, or at all).

Very difficult in Java to think of a way, offhand. I don't think you can 
overload pure assignment in C#, so I don't think you could do the same sort 
of thing there easily either.

>   This is possible transparently in C++ because of RAII: When objects are
> created, copied, assigned and destroyed, you can specify what happens.

I think it's more because you can overload the assignment operator, not the 
RAII as such. Maybe you count that as part of RAII.

-- 
Darren New, San Diego CA, USA (PST)
   Serving Suggestion:
     "Don't serve this any more. It's awful."


Post a reply to this message

From: Warp
Subject: Re: GOTO
Date: 17 Oct 2010 15:39:16
Message: <4cbb50e4@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> >   On a different note, one example where I think the RAII mechanism is
> > better than the Java-style GC mechanism is that RAII allows you to
> > implement copy-on-write semantics (ie. "lazy copying") for objects.

> I understand what you're saying, but this is a bad example for Java because 
> that's exactly how it would work in Java, because strings are immutable, so 
> your "+=" returns a brand new string. :-)  That's why Java has a 
> StringBuilder as well as a String.

  The problem is that it will make a copy of the string data every time
it's modified, which is inefficient.

  For example, assume that instead of appending something to the string
you want to modify one of the characters, such as:

    strings[250][0] = 'H';

  If the string data is not shared, this is very efficient to do because
it can be done in-place, without any kind of data copying. Imagine the
string containing 10 megabytes of data, and you wanting to modify just
the first character.

> >   This is possible transparently in C++ because of RAII: When objects are
> > created, copied, assigned and destroyed, you can specify what happens.

> I think it's more because you can overload the assignment operator, not the 
> RAII as such. Maybe you count that as part of RAII.

  Well, construction (including copy construction) and destruction are
integral parts of CoW, because without them you wouldn't be able to
perform reference counting (and this is exactly one of the aspects of
RAII: resource acquisition and release).

-- 
                                                          - Warp


Post a reply to this message

From: Darren New
Subject: Re: GOTO
Date: 17 Oct 2010 16:30:50
Message: <4cbb5cfa@news.povray.org>
Warp wrote:
>   The problem is that it will make a copy of the string data every time
> it's modified, which is inefficient.

Yes. I understand that. I'm just saying that when you do this discussion, 
don't discuss it using strings if Java is your target language. Java strings 
are immutable. Discuss it using arrays of bytes, or something like that.

>   If the string data is not shared, this is very efficient to do because
> it can be done in-place, without any kind of data copying. Imagine the
> string containing 10 megabytes of data, and you wanting to modify just
> the first character.

Yeah. You *can* do that sort of thing in Java. You just have to do it the 
same way you do it in C: manually and error-prone. :-)

>   Well, construction (including copy construction) and destruction are
> integral parts of CoW, because without them you wouldn't be able to
> perform reference counting (and this is exactly one of the aspects of
> RAII: resource acquisition and release).

OK. I just wasn't sure whether the assignment operator and such was 
considered part of the support for RAII, but in retrospect, I guess it 
wouldn't make sense for it not to be.

-- 
Darren New, San Diego CA, USA (PST)
   Serving Suggestion:
     "Don't serve this any more. It's awful."


Post a reply to this message

From: Warp
Subject: Re: GOTO
Date: 17 Oct 2010 17:44:00
Message: <4cbb6e20@news.povray.org>
Darren New <dne### [at] sanrrcom> wrote:
> I understand what you're saying, but this is a bad example for Java because 
> that's exactly how it would work in Java, because strings are immutable, so 
> your "+=" returns a brand new string. :-)  That's why Java has a 
> StringBuilder as well as a String.

  Maybe this is a much better example, and one which is actually closer to
an actual, realistic situation:

    // An array of 100 unit matrices of size 1000x1000:
    std::vector<Matrix> matrices(100, Matrix(1000, 1000));

  The 'matrices' vector will contain 100 unit matrices. Since these matrices
are really large (1 million elements each), but they are all identical,
there's a very clear memory saving advantage if they all share the same
data (as will be the case if the 'Matrix' class uses copy-on-write). This
is especially so if it's expected that not all of them will ever be modified.

  Of course if you modify one of them, eg:

    matrices[25] *= 2;

you want only the 26th matrix to be modified, rather than all of them.
(Hence it needs to perform a deep-copy before the modification, but only
if its data is being currently shared. If it's not being currently shared,
as may be the case if you modify it again after the above, deep-copying
should not be performed because it would be horribly inefficient.)

-- 
                                                          - Warp


Post a reply to this message

From: Invisible
Subject: Re: GOTO
Date: 18 Oct 2010 04:09:44
Message: <4cbc00c8$1@news.povray.org>
On 16/10/2010 04:03 AM, nemesis wrote:

> in other words:  "I am your father!" :D

NOOOOOOOOO!!! >_<


Post a reply to this message

From: Invisible
Subject: Re: GOTO
Date: 18 Oct 2010 04:23:15
Message: <4cbc03f3@news.povray.org>
>> I also note, with some interest, what looks suspiciously like Haskell
>> syntax, in a letter typed 42 years ago. Obviously it's not after
>> Haskell, but rather whatever mathematical formalism Haskell borrowed the
>> notation from. Still, interesting none the less...)
>
> What syntax specifically?

case [i] of (A1, A2 ... An)

It's almost valid Haskell as it stands. The next line down has

(B1 -> E1, B2 -> E2 ... Bn -> En)

which is also strikingly similar.

> I think (but I was not yet part of the scene then) that people were
> looking for good notation. They knew that programming and mathematics
> had a lot in common. Yet things that were obvious in von Neumann
> machines (assignments and control flow statements in particular) did not
> have a direct counterpart in maths.

I think it's more that mathematics is capable of expressing 
transformations far more complex than what the hardware can actually 
implement. Computer hardware is, more or less, restricted to mutating 
individual hardware registers one at a time. Which, if you think about 
it, is a very slow way to make large-scale changes. Mathematics has a 
lot of language for describing complex transformations, and is much less 
focused on how to (say) multiply two matrices one floating-point value 
at a time.

> A problem that is not entirely solved even today. Haskell and other
> languages try to deal with it by restriction to a a paradigm that is
> closer to math than the imperative way of thinking. The downside of that
> is that problems that are easier solved in another paradigm become more
> complicated. Perhaps there are also people working on extending maths to
> include time-dependent behaviour.

I think that "maths" has "included time-dependent behaviour" since at 
least when Sir Isaac Newton formulated his Laws of Motion. :-P

> Fact is that we as humans solve problems using a lot of techniques.
> Choosing whatever seems appropriate at the time. That is why I think a
> good programmer needs to be familiar with at least three or four
> different languages.

Well, I'd say I've tried more than most...


Post a reply to this message

From: andrel
Subject: Re: GOTO
Date: 19 Oct 2010 18:10:47
Message: <4CBE176A.3030002@gmail.com>
On 18-10-2010 10:23, Invisible wrote:

>> A problem that is not entirely solved even today. Haskell and other
>> languages try to deal with it by restriction to a a paradigm that is
>> closer to math than the imperative way of thinking. The downside of that
>> is that problems that are easier solved in another paradigm become more
>> complicated. Perhaps there are also people working on extending maths to
>> include time-dependent behaviour.
>
> I think that "maths" has "included time-dependent behaviour" since at
> least when Sir Isaac Newton formulated his Laws of Motion. :-P

No, but you knew that.


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.