POV-Ray : Newsgroups : povray.off-topic : GOTO Server Time
3 Sep 2024 21:13:54 EDT (-0400)
  GOTO (Message 11 to 20 of 36)  
<<< Previous 10 Messages Goto Latest 10 Messages Next 10 Messages >>>
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 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

<<< Previous 10 Messages Goto Latest 10 Messages Next 10 Messages >>>

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