RE: goto considered essential
- Posted by Lynn Kilroy <leks_transportation at hotmail.com> Jan 21, 2006
- 462 views
Wasn't there an exit thingabobbers I saw mentioned somewhere? I thought it would be neat to use, because it doesn't exist in QBasic, and I had to setup escape sequences that would abort my loops by resetting variables and stuff. Really messy and unclear. Exit looked like a great alternative. Love & Friendship & Blessed Be! Lynn Erika Kilroy Vincent wrote: > > > posted by: Vincent <darkvincentdude at yahoo.com> > > Tom Dailey wrote: > > > > > > Consider the following program fragment, which copies one text file into > > another text file: > > > > sequence cmd_args > > sequence cmd_line_words > > sequence input_file_name > > integer input_file_nr > > object line > > sequence output_file_name > > integer output_file_nr > > > > cmd_line_words = command_line ( ) > > if length ( cmd_line_words ) != 4 then > > Printf ( "Exactly two arguments expected -- %d supplied.\n", > > { length ( cmd_line_words ) - 2 } ) > > else > > cmd_args = cmd_line_words [ 3..4 ] > > input_file_name = cmd_args [ 1 ] > > input_file_nr = open ( input_file_name, "r" ) > > if input_file_nr = -1 then > > Printf ( "Can't open input file %s.\n", > > { input_file_name } ) > > else > > output_file_name = cmd_args [ 2 ] > > output_file_nr = open ( output_file_name, "w" ) > > if output_file_nr = -1 then > > Printf ( "Can't open output file %s.\n", > > { output_file_name } ) > > else > > while 1 do > > line = gets ( input_file_nr ) > > if atom ( line ) then > > exit > > end if > > puts ( output_file_nr, line ) > > end while > > Printf ( "%s copied to %s.\n", > > { input_file_name, output_file_name } ) > > end if > > end if > > end if > > > > Without a goto statement, or something like it, we have the creeping > > margin > > problem. In production code, with many error checks in the main logic, > > this > > can make code very hard to understand. With a goto, we have > > > > cmd_line_words = command_line ( ) > > if length ( cmd_line_words ) != 4 then > > goto arg_count_is_wrong > > end if > > cmd_args = cmd_line_words [ 3..4 ] > > input_file_name = cmd_args [ 1 ] > > input_file_nr = open ( input_file_name, "r" ) > > if input_file_nr = -1 then > > goto cant_open_input_file > > end if > > output_file_name = cmd_args [ 2 ] > > output_file_nr = open ( output_file_name, "w" ) > > if output_file_nr = -1 then > > goto cant_open_output_file > > end if > > while 1 do > > line = gets ( input_file_nr ) > > if atom ( line ) then > > exit > > end if > > puts ( output_file_nr, line ) > > end while > > Printf ( "%s copied to %s.\n", > > { input_file_name, output_file_name } ) > > goto halt > > > > arg_count_is_wrong: > > Printf ( "Exactly two arguments expected -- %d supplied.\n", > > { length ( cmd_line_words ) - 2 } ) > > goto halt > > cant_open_input_file: > > Printf ( "Can't open input file %s.\n", { input_file_name } ) > > goto halt > > cant_open_output_file: > > Printf ( "Can't open output file %s.\n", { output_file_name } ) > > goto halt > > halt: > > > > Here, the main (non-error) logic is much more apparent. But what, you > > ask, > > is then to prevent evil programmers from generating spaghetti code? > > Well, > > nothing. So perhaps a more constrained construct would be better. In > > the > > spirit of Ada exceptions, we might try something like this: > > > > -- > > -- Function/procedure body or main program starts here. > > -- > > cmd_line_words = command_line ( ) > > exception arg_count_is_wrong if length ( cmd_line_words ) != 4 > > cmd_args = cmd_line_words [ 3..4 ] > > input_file_name = cmd_args [ 1 ] > > input_file_nr = open ( input_file_name, "r" ) > > exception cant_open_input_file if input_file_nr = -1 > > output_file_name = cmd_args [ 2 ] > > output_file_nr = open ( output_file_name, "w" ) > > exception cant_open_output_file if output_file_nr = -1 > > while 1 do > > line = gets ( input_file_nr ) > > exit if atom ( line ) > > puts ( output_file_nr, line ) > > end while > > Printf ( "%s has been copied to %s.\n", > > { input_file_name, output_file_name } ) <snip>