A couple of questions regarding class design

Last time I checked C did not have exceptions. Without looking at the exact locations that fact alone might attribute for quite a few of them:

File ruby/ext/openssl/ossl_ocsp.c
     5 100.00% err

File ruby/ext/openssl/ossl_pkcs12.c
     3 100.00% err

File ruby/ext/openssl/ossl_pkcs7.c
     3 100.00% err

File ruby/bignum.c
     8 72.73% bad
     1 9.09% bignum
     1 9.09% bigparse
     1 9.09% out_of_range

"goto", "break" et al aren't bad in itself like to tool is, but it is like a sharp knife which can do damage more easily when handled carelessly than an edgeless knife. Also, often a sharp knife is not the right tool either, like, when you want to fasten a screw.

I do say though that a lot of code I see (and have to change) has "break" and "continue" in there and becomes easier to read and understand once you take them out. I do have to concede that in the past of my company there was one guy who wrote exceptionally bad code.

Looking a bit further at label counts in goto.c:

File ruby/regex.c
    39 51.32% fail
     4 5.26% numeric_char
     4 5.26% invalid_escape
     4 5.26% nofinalize
     3 3.95% end_of_pattern
     3 3.95% restore_best_regs
     3 3.95% repeat
     3 3.95% normal_char
     2 2.63% too_big
     2 2.63% memory_exhausted
     2 2.63% invalid_pattern
     1 1.32% nested_meta
     1 1.32% on_failure
     1 1.32% unfetch_interval
     1 1.32% advance
     1 1.32% startpos_adjust
     1 1.32% begbuf_match
     1 1.32% range_retry

Of course, a state machine is special in a way. Like a parser, which is typically generated:

File ruby/parse.c
     6 8.70% decode_num
     6 8.70% trailing_uc
     5 7.25% retry
     4 5.80% again
     4 5.80% eof
     3 4.35% yyerrlab
     3 4.35% yynewstate
     3 4.35% error
     3 4.35% yyoverflowlab
     2 2.90% yyerrorlab
     2 2.90% yyerrlab1
     2 2.90% id_regist
     2 2.90% gvar
     2 2.90% quoted
     2 2.90% ternary
     2 2.90% yyreduce
     2 2.90% escaped
     2 2.90% yybackup
     2 2.90% yyreturn
     2 2.90% id
     2 2.90% yydefault
     1 1.45% yysetstate
     1 1.45% new_id
     1 1.45% quotation
     1 1.45% yyacceptlab
     1 1.45% yyabortlab
     1 1.45% start_num
     1 1.45% octal_number
     1 1.45% newline

If you want to do it yourself, here's the quickly hacked gotolyzer(TM):

Robert@Babelfish2 /c/TEMP
$ cat gotolyzer.rb
#!/bin/env ruby

ARGV << "." if ARGV.empty?

ARGV.each do |dir|
   Dir[dir + "/**/*.{h,c}"].each do |file|
     cnt = Hash.new 0
     File.read(file).scan(%r{\bgoto\b\s+([^\s;]+)}) do |m|
       cnt[m] += 1
     end
     unless cnt.empty?
       puts "File #{file}"
       sum = 0
       cnt.sort_by {|k,v| sum += v; -v}.each do |label, count|
         printf "%5d %5.2f%% %s\n", count, count * 100.0 / sum, label
       end
       puts
     end
   end
end

Robert@Babelfish2 /c/TEMP
$

You couldn't do that as elegantly and shortly in C. That's the kind of sacrifice Phlip mentioned.

Cheers

  robert

···

On 26.04.2008 01:29, Simon Krahnke wrote:

* Robert Klemme <shortcutter@googlemail.com> (08:32) schrieb:

On 21.04.2008 23:28, Michael W. Ryder wrote:

I chose this after reading about it in Knuth's 2nd volume. I wanted
to try to implement the binary greatest common divisor algorithm in
Ruby. It took a little effort but I was able to implement it without
any Go Tos. It is hard to go from languages that require jumping
around in the code to one that doesn't. It's a totally different mind
set.

And, does it feel better? For me it does - for Knuth apparently not. I
haven't felt the need for a goto in ages. I also rarely use continue
and break in loops. My impression is that quite a number of cases where
either is chosen can be greatly improved and actually simplified by
choosing a different loop condition. My 0.02EUR...

Tell that Matz & Co.

,----[ ruby-1.9$ grep -c goto *.c | grep -v 0 ]

Robert Dober wrote:

Robert Klemme wrote:

Coming from a background in computers from the 70's when the language was
much closer to the metal I never had any problems with Go To or Jump. In
assembler there is no way to not use Jumps for loops or conditional
processing. Fortran and Basic were much the same way. I believe Knuth's
original works were from this era and of course a lot of his code is in the
MIX assembler.

Very true, but as I have mentioned one has to be disciplined.

I can see the reason to eliminate jumping around in code when possible but
think they can sometimes make a program easier to read. I find it easier to
read a program that says "If error goto ERROR" over trying to figure out
where a Break command goes.

Then maybe your methods are too complex, what about refactoring :wink:
Honestly I try to avoid methods with more than 10-12 LOC (I do not
succeed all the time) but up to 20LOC might be acceptable.
You really *should* be able to see where the break goes.

Most of my programming is for business use. A lot of the time the user will make an entry and depending on what they enter the program will continue or jump to a totally different area. While it may be possible to do with a couple of different entries to eliminate the jumps I don't think it makes the code any more readable, and after that it is almost impossible. I did manage something like this in C using a case statement to determine what function to call next but Business Basic does not have this ability.

···

On Tue, Apr 22, 2008 at 9:15 PM, Michael W. Ryder > <_mwryder@worldnet.att.net> wrote:

This all said, Knuth's MIX code is for sure easier to read than one of
my early Ruby methods :(.

Cheers
Robert

If you want to read up on the matter, Wikipedia has quite an exhaustive

coverage:

Structured programming - Wikipedia

Kind regards

   robert

Robert Klemme wrote:

Robert Klemme wrote:

I chose this after reading about it in Knuth's 2nd volume. I wanted to try to implement the binary greatest common divisor algorithm in Ruby. It took a little effort but I was able to implement it without any Go Tos. It is hard to go from languages that require jumping around in the code to one that doesn't. It's a totally different mind set.

And, does it feel better? For me it does - for Knuth apparently not. I haven't felt the need for a goto in ages. I also rarely use continue and break in loops. My impression is that quite a number of cases where either is chosen can be greatly improved and actually simplified by choosing a different loop condition. My 0.02EUR...

Coming from a background in computers from the 70's when the language was much closer to the metal I never had any problems with Go To or Jump.

Well, you had to use what you got, didn't you? I believe the reasons Basic et al had GOTO was historic as you said: programming languages did not have evolved very far from the basis (machine code or assembler if you will).

But later people detected deficiencies of this approach and tried to come up with better solutions. I would not want to miss structured programming and exceptions.

In assembler there is no way to not use Jumps for loops or conditional processing. Fortran and Basic were much the same way. I believe Knuth's original works were from this era and of course a lot of his code is in the MIX assembler.
I can see the reason to eliminate jumping around in code when possible but think they can sometimes make a program easier to read. I find it easier to read a program that says "If error goto ERROR" over trying to figure out where a Break command goes.

Well, for error handling there is a different mechanism in modern languages: exceptions. :slight_smile:

One thing I haven't figured out is returning from an exception to the calling location. In Business Basic I can set a location that the program will go to when an untrapped error occurs. From there I can handle the error and return back to the program.
I can also do the same if the Escape key is pressed, or I can go to a new location and continue. This comes in real handy when an operator is finished with data entry they just press the Escape key to save the changes and continue.

···

On 22.04.2008 21:12, Michael W. Ryder wrote:

On 21.04.2008 23:28, Michael W. Ryder wrote:

Kind regards

    robert

Well without the code I cannot really help but somehow I have the
feeling that send might be your friend here!

R.

···

On Tue, Apr 22, 2008 at 10:55 PM, Michael W. Ryder <_mwryder@worldnet.att.net> wrote:

Robert Dober wrote:

> On Tue, Apr 22, 2008 at 9:15 PM, Michael W. Ryder > > <_mwryder@worldnet.att.net> wrote:
>
> > Robert Klemme wrote:
> >
>
>
> > Coming from a background in computers from the 70's when the language
was
> > much closer to the metal I never had any problems with Go To or Jump.
In
> > assembler there is no way to not use Jumps for loops or conditional
> > processing. Fortran and Basic were much the same way. I believe
Knuth's
> > original works were from this era and of course a lot of his code is in
the
> > MIX assembler.
> >
> Very true, but as I have mentioned one has to be disciplined.
>
> > I can see the reason to eliminate jumping around in code when possible
but
> > think they can sometimes make a program easier to read. I find it
easier to
> > read a program that says "If error goto ERROR" over trying to figure out
> > where a Break command goes.
> >
> Then maybe your methods are too complex, what about refactoring :wink:
> Honestly I try to avoid methods with more than 10-12 LOC (I do not
> succeed all the time) but up to 20LOC might be acceptable.
> You really *should* be able to see where the break goes.
>
>

Most of my programming is for business use. A lot of the time the user
will make an entry and depending on what they enter the program will
continue or jump to a totally different area. While it may be possible to
do with a couple of different entries to eliminate the jumps I don't think
it makes the code any more readable, and after that it is almost impossible.
I did manage something like this in C using a case statement to determine
what function to call next but Business Basic does not have this ability.

--
http://ruby-smalltalk.blogspot.com/

---
Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein

That would be "retry":

irb(main):009:0> def test(x) raise "#{x} is too low" if x < 5 end
=> nil
irb(main):010:0> i = 0
=> 0
irb(main):011:0> begin; puts i; test i; rescue Exception => e; puts e;
i+=1; retry; end
0
0 is too low
1
1 is too low
2
2 is too low
3
3 is too low
4
4 is too low
5
=> nil
irb(main):012:0>

Kind regards

robert

···

2008/4/23, Michael W. Ryder <_mwryder@worldnet.att.net>:

One thing I haven't figured out is returning from an exception to the
calling location. In Business Basic I can set a location that the program
will go to when an untrapped error occurs. From there I can handle the
error and return back to the program.
I can also do the same if the Escape key is pressed, or I can go to a new
location and continue. This comes in real handy when an operator is
finished with data entry they just press the Escape key to save the changes
and continue.

--
use.inject do |as, often| as.you_can - without end

Now Michael just needs to integrate the Ruby interpreter into his Business Basic engine. :slight_smile:

Cheers

  robert

···

On 23.04.2008 00:44, Robert Dober wrote:

On Tue, Apr 22, 2008 at 10:55 PM, Michael W. Ryder > <_mwryder@worldnet.att.net> wrote:

Most of my programming is for business use. A lot of the time the user
will make an entry and depending on what they enter the program will
continue or jump to a totally different area. While it may be possible to
do with a couple of different entries to eliminate the jumps I don't think
it makes the code any more readable, and after that it is almost impossible.
I did manage something like this in C using a case statement to determine
what function to call next but Business Basic does not have this ability.

Well without the code I cannot really help but somehow I have the
feeling that send might be your friend here!

Have you given up hope for him already :wink: ?
R.

···

On Wed, Apr 23, 2008 at 8:05 AM, Robert Klemme <shortcutter@googlemail.com> wrote:

Now Michael just needs to integrate the Ruby interpreter into his Business
Basic engine. :slight_smile:

--
http://ruby-smalltalk.blogspot.com/

---
Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein

Robert Klemme wrote:

Most of my programming is for business use. A lot of the time the user
will make an entry and depending on what they enter the program will
continue or jump to a totally different area. While it may be possible to
do with a couple of different entries to eliminate the jumps I don't think
it makes the code any more readable, and after that it is almost impossible.
I did manage something like this in C using a case statement to determine
what function to call next but Business Basic does not have this ability.

Well without the code I cannot really help but somehow I have the
feeling that send might be your friend here!

Now Michael just needs to integrate the Ruby interpreter into his Business Basic engine. :slight_smile:

Funny you should mention that. One of the things I am working on is Ruby equivalents to the Business Basic commands. Obviously some of it is not going to be possible, like the built in file and screen handling, and will require integration with other tools. From this I can try to convert some 20+ years of programs to Ruby and get some of the benefits of the language.

···

On 23.04.2008 00:44, Robert Dober wrote:

On Tue, Apr 22, 2008 at 10:55 PM, Michael W. Ryder >> <_mwryder@worldnet.att.net> wrote:

Cheers

    robert

Hey, I didn't say he can't do it. :slight_smile:

robert

···

2008/4/23, Robert Dober <robert.dober@gmail.com>:

On Wed, Apr 23, 2008 at 8:05 AM, Robert Klemme > <shortcutter@googlemail.com> wrote:
>
> Now Michael just needs to integrate the Ruby interpreter into his Business
> Basic engine. :slight_smile:

Have you given up hope for him already :wink: ?

--
use.inject do |as, often| as.you_can - without end

Just to be clear, I meant to join Ruby, not that he could not program,
hopefully that was not misunderstood :open_mouth:
R.

···

On Wed, Apr 23, 2008 at 11:47 AM, Robert Klemme <shortcutter@googlemail.com> wrote:

2008/4/23, Robert Dober <robert.dober@gmail.com>:

> On Wed, Apr 23, 2008 at 8:05 AM, Robert Klemme > > <shortcutter@googlemail.com> wrote:
> >
> > Now Michael just needs to integrate the Ruby interpreter into his Business
> > Basic engine. :slight_smile:
>
> Have you given up hope for him already :wink: ?

Hey, I didn't say he can't do it. :slight_smile:

Oh no, not at all - at least here. :slight_smile:

"Great Roberts think alike."
*cough, cough*

Now off to CL watching...

robert

···

2008/4/23, Robert Dober <robert.dober@gmail.com>:

On Wed, Apr 23, 2008 at 11:47 AM, Robert Klemme > > <shortcutter@googlemail.com> wrote:
> 2008/4/23, Robert Dober <robert.dober@gmail.com>:
>
> > On Wed, Apr 23, 2008 at 8:05 AM, Robert Klemme > > > <shortcutter@googlemail.com> wrote:
> > >
> > > Now Michael just needs to integrate the Ruby interpreter into his Business
> > > Basic engine. :slight_smile:
> >
> > Have you given up hope for him already :wink: ?
>
> Hey, I didn't say he can't do it. :slight_smile:

Just to be clear, I meant to join Ruby, not that he could not program,
hopefully that was not misunderstood :open_mouth:

--
use.inject do |as, often| as.you_can - without end

Common Lisp that is I hope :wink:
R.

···

On Wed, Apr 23, 2008 at 7:29 PM, Robert Klemme <shortcutter@googlemail.com> wrote:

Now off to CL watching...

--
http://ruby-smalltalk.blogspot.com/

---
Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein

Of course, with 22 actors and one controller. A complex application with a load of observers. It's real time application: the whole processing has to complete within 90 minutes (plus some slack for special cases). Unfortunately they did not get rid of punch cards yet and to make matters worse they have two different kinds of these cards. That's also the reason why sometimes there are drop outs and not all processors continue processing until the end. Bugs creep into every program - even if it's written in Lisp and uses a friendly green screen.

:slight_smile:

  robert

···

On 23.04.2008 19:48, Robert Dober wrote:

On Wed, Apr 23, 2008 at 7:29 PM, Robert Klemme > <shortcutter@googlemail.com> wrote:

Now off to CL watching...

Common Lisp that is I hope :wink:

Well in our match of wit (very modest as I am) I declare you the winner.
Robert vs. Robert 1 - 0
Cheers
Robert (what else)

···

On Thu, Apr 24, 2008 at 11:05 PM, Robert Klemme <shortcutter@googlemail.com> wrote:

On 23.04.2008 19:48, Robert Dober wrote:

--
http://ruby-smalltalk.blogspot.com/

---
Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein

Well in our match of wit (very modest as I am) I declare you the winner.
Robert vs. Robert 1 - 0

That's just an intermediate result - wait for the 2nd half. I am sure you have some tricks left. Thank you for the inspiration!

Cheers
Robert (what else)

Did I just talk to myself? Oh, I need a break...

Have a great weekend - weather will be fine!

  robert

···

On 25.04.2008 09:03, Robert Dober wrote:

On Thu, Apr 24, 2008 at 11:05 PM, Robert Klemme > <shortcutter@googlemail.com> wrote:

On 23.04.2008 19:48, Robert Dober wrote: