Debian Developers - Python or Perl for a Debian maintainance project?

This is Interesting: Free IT Magazines  
Home > Archive > Debian Developers > February 2004 > Python or Perl for a Debian maintainance project?





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Pages:
Pages: [1] 2
Author Python or Perl for a Debian maintainance project?
Andrew Pollock

2004-02-14, 7:33 pm

Hi,

I'm firing up an Alioth project[1] to make an Enterprise grade central
management interface (ala the Red Hat Network) for Debian, and I'm wondering
whether to do it in PERL (which I know) or Python (which I do not, but
wouldn't mind a good excuse to learn).

I notice that a sizable chunk of the backend Debian housekeeping scripts are
Python scripts, but I can't seem to find a package of Debian-specific Python
classes (is this the case?). I haven't looked for something similar for Perl
modules yet.

I'd like to avoid reinventing the wheel, and I'm aiming for something that's
modular and extensible. At this stage, I'd like a PERL or Python interface
to grep-dctrl and possibly an implementation of dpkg --compare-versions

Also, does anyone know if Python has a database abstraction layer (like
PHP's ADODB)?

regards

Andrew

[1] http://demi.alioth.debian.org/

Zenaan Harkness

2004-02-14, 8:33 pm

Ruby. It's just, so nice. OO, GC, minimal syntax overhead - a proper language
but as close to a "scripting" language as you can get. SDL bindings, GNOME bindings
and 50 more libs too.

I haven't used Python, and I'm only a beginner at Ruby, but I've programmed Java
for years.

Debian related libs are perhaps a little thin though - depends what you need I
guess.

---
$ apt-cache search ruby|grep -i debian

$ apt-cache search ruby|grep -i dpkg
dpkg-ruby - ruby interface for dpkg
libdpkg-ruby1.6 - modules/classes for dpkg on ruby 1.6
libdpkg-ruby1.8 - modules/classes for dpkg on ruby 1.8

$ apt-cache search ruby|grep -i dh

---

cheers
zen


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Julian Mehnle

2004-02-14, 10:33 pm

Zenaan Harkness wrote:
> Ruby. It's just, so nice. OO, GC, minimal syntax overhead - a proper
> language but as close to a "scripting" language as you can get. SDL
> bindings, GNOME bindings and 50 more libs too.
>=20
> I haven't used Python,


You obviously haven't *really* used PERL as well. ;-) Except for the =
"minimal syntax overhead", all features you mentioned above do apply to =
Perl likewise.


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Hamish Moffatt

2004-02-14, 11:33 pm

On Sun, Feb 15, 2004 at 08:14:20PM +1100, Zenaan Harkness wrote:
> $ apt-cache search ruby|grep -i dpkg
> dpkg-ruby - ruby interface for dpkg
> libdpkg-ruby1.6 - modules/classes for dpkg on ruby 1.6
> libdpkg-ruby1.8 - modules/classes for dpkg on ruby 1.8


Not another language with versioning problems....

At least you didn't suggest Tcl.

Hamish
--
Hamish Moffatt VK3SB <hamish@debian.org> <hamish@cloud.net.au>


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Zenaan Harkness

2004-02-14, 11:33 pm

On Sun, 2004-02-15 at 23:11, Hamish Moffatt wrote:
> On Sun, Feb 15, 2004 at 08:14:20PM +1100, Zenaan Harkness wrote:
>
> Not another language with versioning problems....


I don't actually know enough yet to comment/ respond to this.

> At least you didn't suggest Tcl.


To fill in the blanks in my ignorant mind, which language(s) out
there have not had versioning problems?


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Thomas Viehmann

2004-02-15, 12:33 am

Hi,

Andrew Pollock wrote:
> I notice that a sizable chunk of the backend Debian housekeeping scripts are
> Python scripts, but I can't seem to find a package of Debian-specific Python
> classes (is this the case?). I haven't looked for something similar for Perl
> modules yet.

There's the (terminally ill documented last time I looked [1])
python-apt, if you're looking for parsing package files and such stuff.

> Also, does anyone know if Python has a database abstraction layer (like
> PHP's ADODB)?

Python has the db-sig interface. The only call that wasn't standardized
too well [2] was connect for actually connecting to a database.

I personally would recommend python, but I'm not one of those "all
scripting languages but my favorite are garbage" people. [3]

Kind regards

Thomas

1. I offered a version of my silly little dependency browser written in
python to the last who asked.
2. Again, last time I looked.
3. But hey, Python is the only language suggested in this thread that
has a decent name.
--
Thomas Viehmann, <http://beamnet.de/tv/>

Ricardo Javier Cardenes Medina

2004-02-15, 2:33 am

On Sun, Feb 15, 2004 at 06:12:24PM +1000, Andrew Pollock wrote:

> Also, does anyone know if Python has a database abstraction layer (like
> PHP's ADODB)?


DB-API, but that's low level compared to ADODB.

http://www.python.org/peps/pep-0249.html

There are many DB-API 2.0 compliant interfaces (to MySQL, PgSQL, etc) on
our archive.


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Matthias Urlichs

2004-02-15, 7:33 am

Hi, Andrew Pollock wrote:

> I'm firing up an Alioth project[1] to make an Enterprise grade central
> management interface (ala the Red Hat Network) for Debian, and I'm
> wondering whether to do it in PERL (which I know) or Python (which I do
> not, but wouldn't mind a good excuse to learn).


FWIW, and at the risk of starting a my-scripting-language-is-better-
-than-yours argument:

Python.

My main reason for this statement, entirely subjective but based on
personal experience:

Every error whatsoever throws an exception. That's far better from a
quality POV than to check the error return of _every_single_statement_,
because (a) nobody actually programs that way, and (b) if you actually do
program that way your code will be twice as long and ten times as
unreadable.

Check out [1]ESR's experience, it pretty much matches mine.

YMMV, and all that.

[1] http://www.linuxjournal.com/article.php?sid=3882

--
Matthias Urlichs


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Stephane Bortzmeyer

2004-02-15, 7:34 am

On Sun, Feb 15, 2004 at 09:43:23PM +0100,
Matthias Urlichs <smurf@smurf.noris.de> wrote
a message of 29 lines which said:

> FWIW, and at the risk of starting a my-scripting-language-is-better-
> -than-yours argument:
>
> Python.

....
> Every error whatsoever throws an exception.


I love Python (partly because of that very same reason) *but* the
choice of a programming language, for a practical task (not an
academic assignment) should not only depend on intrinsic
characteristics of the language but also on other things:

* the abundance of high-quality (tested, documented and used in the
real world) libraries for various tasks (Perl and the CPAN are clear
winners in that respect).

* the abundance of programmers, articles and books, to help other
people to maintain the work (Perl wins here also).

I do not suggest an official Debian Policy for Debian System
Administration Scripts (too much opportunity for flamewars) but, if
you want an advice, I feel like the criteria above are often ignored
when choosing a programming language.


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Zenaan Harkness

2004-02-15, 7:34 am

On Sun, 2004-02-15 at 22:45, Julian Mehnle wrote:
> Zenaan Harkness wrote:
>
> You obviously haven't *really* used PERL as well. ;-) Except for the
> "minimal syntax overhead", all features you mentioned above do apply
> to PERL likewise.


You are correct.

Here is someone's comparison from the discuss@lists.userlinux.com list,
which might be useful for people:


From:
Alexander
Neundorf
<neundorf@kde.org>
Reply-To:
discuss@lists.userlinux.com, neundorf@kde.org
To:
discuss@lists.userlinux.com
Subject:
Re:
[Discuss]
[Fwd: ruby]
Date:
Sun, 15 Feb
2004
20:06:10
+0100

On Sunday 15 February 2004 16:49, David MacQuigg wrote:
> At 04:57 PM 2/15/2004 +1100, Zen wrote:
In[color=blue]
....[color=blue]
with[color=blue]
language,[color=blue]
something[color=blue]
>
> Have you tried www.python.org Two hours and I was hooked !! I

switched
> from Java about a year ago, and never looked back. I don't know about
> Ruby, but Python is far more popular ( outside of Japan ),


At first I tried perl, it was horrible. Then I tried Python, it was ok.
Still
the OO syntax seemed a bit strange to me, as well as some other
syntactic
things.
Then I tried Ruby and currently I think I found the cleanest language
there
is. Nice and clean and much better documented than Python (at least what
I
found).

So, I recommend trying Ruby for everybody who likes Python :-)

Bye
Alex


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Domenico Andreoli

2004-02-15, 9:34 am

On Sun, Feb 15, 2004 at 09:57:11PM +0100, Stephane Bortzmeyer wrote:
> I love Python (partly because of that very same reason) *but* the
> choice of a programming language, for a practical task (not an
> academic assignment) should not only depend on intrinsic
> characteristics of the language but also on other things:
>
> * the abundance of high-quality (tested, documented and used in the
> real world) libraries for various tasks (Perl and the CPAN are clear
> winners in that respect).
>

about abundance CPAN clearly wins. but if you talk about high-quality
IMHO the winner is not as clear as you are selling...


-----[ Domenico Andreoli, aka cavok
--[ http://filibusta.crema.unimi.it/~cavok/gpgkey.asc
---[ 3A0F 2F80 F79C 678A 8936 4FEE 0677 9033 A20E BC50


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Julian Mehnle

2004-02-15, 10:33 am

Zenaan Harkness wrote:
> Here is someone's comparison from the discuss@lists.userlinux.com list,
> which might be useful for people:


Alexander Neundorf <neundorf@kde.org> wrote:
> At first I tried perl, it was horrible.


Oh, my. What kind of statement is that? As it is written by Alexander,
this is totally unfounded. It's nothing but an opinion, and I guess
Alexander isn't even a respected authority with regard to the pros and
cons of programming languages, is he? Zenaan, why did you think
statements like this might be useful to anybody?


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Julian Mehnle

2004-02-15, 11:33 am

Matthias Urlichs wrote:
> Python.
>=20
> My main reason for this statement, entirely subjective but based on
> personal experience:=20
>=20
> Every error whatsoever throws an exception. That's far better from a
> quality POV than to check the error return of =

_every_single_statement_,
> because (a) nobody actually programs that way, and (b) if you actually
> do program that way your code will be twice as long and ten times as
> unreadable.=20


That's true, but there's no reason not to use exceptions in Perl. =
They're even built-in, although you eccentrically (or shall I say, =
exceptionally) raise them with `die`, and catch them with `eval {}` -- =
and yes, that *is* efficient. As syntactic sugar, you may want to use =
the CPAN module "Error", though.

> Check out [1]ESR's experience, it pretty much matches mine.
> [1] http://www.linuxjournal.com/article.php?sid=3D3882


In his article, Eric asks the question "what has [Python] got that PERL =
does not?". But essentially, he only criticizes Perl's syntax =
("readability") and absent compactness ("there's more than one way to do =
it"), and even that is debatable.


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Andrew Suffield

2004-02-16, 12:33 am

On Sun, Feb 15, 2004 at 11:48:39PM +1100, Zenaan Harkness wrote:
> On Sun, 2004-02-15 at 23:11, Hamish Moffatt wrote:
>
> I don't actually know enough yet to comment/ respond to this.
>
>
> To fill in the blanks in my ignorant mind, which language(s) out
> there have not had versioning problems?


C

--
.''`. ** Debian GNU/Linux ** | Andrew Suffield
: :' : http://www.debian.org/ |
`. `' |
`- -><- |

Andrew Suffield

2004-02-16, 12:33 am

On Sun, Feb 15, 2004 at 09:43:23PM +0100, Matthias Urlichs wrote:
> Every error whatsoever throws an exception. That's far better from a
> quality POV than to check the error return of _every_single_statement_,
> because (a) nobody actually programs that way, and (b) if you actually do
> program that way your code will be twice as long and ten times as
> unreadable.


However, it results in code that throws exceptions to the user rather
than useful error messages, which is amateurish. The user should never
see an exception unless there is a bug in your code; errors from the
system should be handled properly. This *does* make your code twice as
long, but it will not make it any less readable if you do it
right. Failing to do it is like failing to test your code before
releasing it, or trusting data read from the network - it is not
something that has any place in a serious program.

"Python makes it easier to write bad code" is a pretty lousy argument.

--
.''`. ** Debian GNU/Linux ** | Andrew Suffield
: :' : http://www.debian.org/ |
`. `' |
`- -><- |

Julian Mehnle

2004-02-16, 12:33 am

Andrew Suffield wrote:
> On Sun, Feb 15, 2004 at 09:43:23PM +0100, Matthias Urlichs wrote:
>=20
> However, it results in code that throws exceptions to the user rather
> than useful error messages, which is amateurish. The user should never
> see an exception unless there is a bug in your code; errors from the
> system should be handled properly. This *does* make your code twice as
> long, but it will not make it any less readable if you do it
> right. Failing to do it is like failing to test your code before
> releasing it, or trusting data read from the network - it is not
> something that has any place in a serious program.


That's an invalid conclusion. In every language that supports =
exceptions, you can very well have a global exception handler that =
catches any uncaught exceptions and presents them to the user in a nice =
way.


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Lars Wirzenius

2004-02-16, 1:33 am

I'm assuming this is a serious discussion.

ma, 2004-02-16 kello 15:41, Andrew Suffield kirjoitti:
> On Sun, Feb 15, 2004 at 11:48:39PM +1100, Zenaan Harkness wrote:
>
> C


We've had K&R C from 1978, various somewhat incompatible dialects in the
1980's (near/far being one of the smaller differences), the ANSI
standard from 1989 (adopted reformatted, but otherwise unchanged by ISO
in 1990), a normative addendum in 1995 (I think), and a new standard in
1999. Along the way, various vendors have made extensions to the
language (longer integer data types, inline, C++ comments, etc), as well
as occasionally being mutually incompatible. Pretty much every
implementation has extended the library, often in ways that are in
violation of the standard (adding new functions to standard-specified
headers).

As a result, we got autoconf.

I would not say that C has not had versioning problems.

On the other hand, the 1989 version of the C standard has been a great
stabilizing influence for fifteen years now. If you follow it strictly,
you can be quite confident that things will work. With only a little bit
of effort, you can do quite a lot and not have to ever have to deal with
autotools (assuming a semistandard Unix environment with cc and make).
Most programmer's don't do that, associating configure script length
with other lengths, but that's not an inherent problem with the
language.

On the whole, C has fewer versioning problems than the popular scripting
languages (Python, Perl, Tcl). I don't know PERL and Tcl, but as far as
Python is concerned, to the best of my knowledge the major reason we
have several Python release versions in a Debian release is that
extensions to the Python interpreter (e.g., bindings to various C
libraries such as GTK+) need to be compiled for each release series
(2.1, 2.2, 2.3) separately.

The Python language has changed and if you have a program written for
Python 2.3 that uses new language or library features, it won't work
with Python 2.2. If you avoid those, you don't have a problem. With very
few exceptions, a program written for Python 2.1 or 2.2 will work for
2.3, just like a C program written for the 1989 version of the standard
will work for the 1999 version. The exceptions tend to be in obscure
corners of the language, which you should avoid lurking in anyway. If a
newer version of Python breaks a Python application, it can often be
treated as a bug, in Python or in the application, and the situation
often can be rectified by fixing the bug. We had this with Mailman just
recently.

(We may also have a problem in how we package Python for Debian, but
that is a Debian problem, not inherent in Python.)

On a more philosophical note, most programming languages in active use
keeps changing and we need to adapt to that. Of course, mature languages
such as C, AWK, Perl5, or Common Lisp, probably don't change so often
that it matters in the daily life of maintaining Debian. New languages
change more often: they gather new users, with new needs, and need to
accomodate. This change process is quite acceptable and if it means we
need to have several implemenations of a particular language, so be it.
It would, of course, be preferable not to have to have them.

--
http://liw.iki.fi/liw/log/


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Will Newton

2004-02-16, 1:34 am

On Monday 16 Feb 2004 1:47 pm, Andrew Suffield wrote:

> However, it results in code that throws exceptions to the user rather
> than useful error messages, which is amateurish. The user should never
> see an exception unless there is a bug in your code; errors from the
> system should be handled properly. This *does* make your code twice as
> long, but it will not make it any less readable if you do it
> right. Failing to do it is like failing to test your code before
> releasing it, or trusting data read from the network - it is not
> something that has any place in a serious program.
>
> "Python makes it easier to write bad code" is a pretty lousy argument.


Exceptions are a valuable programming tool, and I think your criticisms are
largely unfounded. Exceptions allow you to rid yourself of the overhead of
checking for NULLs etc inside your main logic and move the error handling
code (which is rarely part of your algorithm - checking for failed allocs in
a sort algorithm for example) out of the main code.

In Python you have:

try:
# do some stuff
except Exception, e:
# do specific cleanup
finally:
# do cleanup

In C you have:

void shoe()
{
/* Do some complicated stuff */
if (foo == NULL)
goto cleanup;
/* Continue complicated stuff */
if (bar == 3)
goto cleanup;

cleanup:
/* Cleanup */
}

It's just another way of writing the same thing.

Personally I would not use a language that did not support exceptions for any
large scale project[1].

[1] I'm sure you can come up with examples to counter this, but they are
exceptions (get it?) rather than the rule.


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
John Goerzen

2004-02-16, 2:38 am

On Sun, Feb 15, 2004 at 06:12:24PM +1000, Andrew Pollock wrote:
> whether to do it in PERL (which I know) or Python (which I do not, but
> wouldn't mind a good excuse to learn).


I have just been looking at languages over the weekend myself.

My opinion of PERL is that it is probably the best choice for small
tasks, single-task things that are parser-heavy, etc. It scales poorly,
though, to the point where I would say that code maintainability has an
exponential decay when plotted against code size :-)

I use Python a lot. There are some Debian-specific Python classes out
there (specifically regarding interfaces to apt and debconf), though (at
least in the case of apt) they are poorly documented.

Perl and Python both have quite sizable libraries of add-on modules.
When I was looking at places to go from PERL 3 or 4 years ago, that is
the reason I chose Python instead of another language like Ruby.
Python's *standard* library is more featureful than the entire set of
add-on modules for some languages, yet is quite lean.

Take a look at www.python.org/doc/current, then hit the Global Module
Index to see what is available. There are yet more modules out there
that are not part of the standard; grep-dctrl for Python in Debian will
be instructive. www.twistedmatrix.com has one of the most interesting.

Despite the fact that I think other languages like Haskell (and perhaps
Ruby) are still more clean than Python (which is already quite nice),
the benefit of not having to reinvent the wheel is still a huge win for
Python.

Perl and Java both have large libraries as well -- perhaps even larger
than Python. However, I have only once found Python to be lacking in
some feature I wanted -- it's builtin imaplib totally sucks -- and the
wins of more rapid development and easier maintainability keep me in
Python. (Plus Twisted has a much nicer IMAP implementation <g> )

> Also, does anyone know if Python has a database abstraction layer (like
> PHP's ADODB)?


Yes, it is known as DB-API 2.0. Read about it at
http://www.python.org/topics/database/.

It reminds me a lot of Perl's DBI. It does not have quite the power of
JDBC, and has one bug I consider to be severe (failing to completely
standardize replacable arguments in repeated queries), but overall is
nice.

-- John


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Steve Langasek

2004-02-16, 3:33 am

On Mon, Feb 16, 2004 at 04:14:43PM +0200, Lars Wirzenius wrote:

> On the whole, C has fewer versioning problems than the popular scripting
> languages (Python, Perl, Tcl). I don't know PERL and Tcl, but as far as
> Python is concerned, to the best of my knowledge the major reason we
> have several Python release versions in a Debian release is that
> extensions to the Python interpreter (e.g., bindings to various C
> libraries such as GTK+) need to be compiled for each release series
> (2.1, 2.2, 2.3) separately.


$ du -sh /usr/lib/perl/5.8.2/
11M /usr/lib/perl/5.8.2
$ du -sh /usr/lib/perl5/
2.7M /usr/lib/perl5
$

Same deal with PERL -- PERL transitions just happen to be managed better
in Debian than Python transitions, which stands to reason since we have
more practice at PERL transitions (and it causes more problems when
things go wrong).

Probably the Python licensing snafu of a couple years back also
contributed to the mindset of trying to support multiple
binary-incompatible Python versions concurrently, whether or not the
language itself justified such parallelism.

Regardless of the reasons, it would definitely be nice to see python
transitions handled more smoothly in the future. This probably requires
amending the Debian Python policy.

--
Steve Langasek
postmodern programmer

Andrew Suffield

2004-02-17, 3:34 am

On Mon, Feb 16, 2004 at 03:06:33PM +0000, Will Newton wrote:
> On Monday 16 Feb 2004 1:47 pm, Andrew Suffield wrote:
>
>
> Exceptions are a valuable programming tool, and I think your criticisms are
> largely unfounded.


My criticisms were of using exceptions to avoid handling errors, which
was the proposed "advantage". If you're going to handle the errors,
then there's no difference between using exceptions or not.

> In C you have:
>
> void shoe()
> {
> /* Do some complicated stuff */
> if (foo == NULL)
> goto cleanup;
> /* Continue complicated stuff */
> if (bar == 3)
> goto cleanup;
>
> cleanup:
> /* Cleanup */
> }


Good grief, that's *terrible* C. Don't do things like that. The
problem here is not a lack of exceptions, it's just bad code. As
usual.

Here's how you should do that:

static bool
check_foo(struct foo *foo)
{
if (sucks(foo->bar))
return false;
if (sucks(foo->baz))
return false;

return true;
}

static bool
process_foo(struct foo *foo)
{
if (!check_foo(foo))
{
/* report and die */
}

/* process it */
}

(Most uses of goto should be replaced with function calls; the rest
should be replaced with block-structure statements)

Highly maintainable (more so than with scattered exceptions, because
everything to do a given task is located in one place), and
considerably more efficient. You can add an error return message from
check_foo() to provide more informative error messages, or split it up
into a sequence of checking functions if some processing is needed in
between.

Exceptions should only be used for exceptional circumstances, and even
then think twice. The single thing for which they are useful is to
throw an error a long way to an unknown handler, which may or may not
understand the error. This is not often useful - library APIs are the
most notable case. Using exceptions in any other circumstances is
usually a really bad idea.

--
.''`. ** Debian GNU/Linux ** | Andrew Suffield
: :' : http://www.debian.org/ |
`. `' |
`- -><- |

Andrew Suffield

2004-02-17, 4:34 am

On Mon, Feb 16, 2004 at 03:03:10PM +0100, Julian Mehnle wrote:
> Andrew Suffield wrote:
>


> That's an invalid conclusion. In every language that supports
> exceptions, you can very well have a global exception handler that
> catches any uncaught exceptions and presents them to the user in a
> nice way.


No you can't. I'd be mildly interested in seeing a handler that could
handle any exception and generate a suitable error message that was
not of infinite length (because it can't be done).

Note that you have to do this for exceptions you receive from things
you call.

Here's a suitably contrived example that can't be simulated in the way
you describe:

if (open $foo, $bar)
{
/* do stuff */
return 1;
}
die "Failed to open $bar: $!" unless $! == ENOENT;

if (open $foo, $baz)
{
/* do stuff */
return 1;
}
die "Failed to open $baz: $!" unless $! == ENOENT;

print STDERR "Neither $bar nor $baz were found\n";
return 1;

Here the "special" (common) case of two non-existant files has been
handled differently to generate an informative error.

--
.''`. ** Debian GNU/Linux ** | Andrew Suffield
: :' : http://www.debian.org/ |
`. `' |
`- -><- |

Will Newton

2004-02-17, 6:33 am

On Tuesday 17 Feb 2004 4:58 pm, Andrew Suffield wrote:

>
> Good grief, that's *terrible* C. Don't do things like that. The
> problem here is not a lack of exceptions, it's just bad code. As
> usual.


As usual? OK.

That is an often used convention, used by many substantial pieces of C code
that you are running on your system right now. Admittedly it is much more
often used in system level situations than application code. It can be argued
that much C is *terrible*. That's why it's C.

> Here's how you should do that:


<snip>

> static bool
> process_foo(struct foo *foo)
> {
> if (!check_foo(foo))
> {
> /* report and die */
> }
>
> /* process it */
> }
>
> (Most uses of goto should be replaced with function calls; the rest
> should be replaced with block-structure statements)


Unfortunately this doesn't necessarily work if you need to do work
(allocations, side effects) in between checking foo and bar.

> Exceptions should only be used for exceptional circumstances, and even
> then think twice. The single thing for which they are useful is to
> throw an error a long way to an unknown handler, which may or may not
> understand the error. This is not often useful - library APIs are the
> most notable case. Using exceptions in any other circumstances is
> usually a really bad idea.


I beg to differ.


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Kenneth Pronovici

2004-02-17, 6:33 am

On Tue, Feb 17, 2004 at 07:21:00PM +0000, Will Newton wrote:
> On Tuesday 17 Feb 2004 4:58 pm, Andrew Suffield wrote:
>
>
> As usual? OK.
>
> That is an often used convention, used by many substantial pieces of C code
> that you are running on your system right now. Admittedly it is much more
> often used in system level situations than application code.


In fact, K&R even recommends this approach when cleanup is required, so
it's not as if there isn't precedent:

This organization is handy if the error-handling code is non-trivial,
and if errors can occur in several places. [1]

I've seen this approach used to great advantage in several fairly large
(500,000+ line) pieces of Oracle-based software. We standardized on a
common structure for each function (at least, each function of a certain
complexity), including a return status variable and an EXIT_FUNC tag
that was always immediately after all normal program functionality and
immediately before all cleanup. Whenever we ran into a "fatal" error,
we logged a message, set the return status appropriately and then jumped
to EXIT_FUNC.

This gave us an obvious place to free memory, clean up database
connections, roll back or commit transactions, etc., etc. It was good
that all cleanup was done exactly the same way (no duplication, no
omissions). It was also good that all of the functions had a similar
structure, which helped minimize the learning curve for a code-base this
large.

Yes, you can argue that if error-handling gets really complicated, you
might be better off moving some of that code to smaller functions which
each have their own, less-complicated error-handling. However,
sometimes you still need one good place to do consistent cleanup, and
this approach seems to work as well as any I've seen.

KEN

[1] Section 3.8 "Goto and Labels", page 65 in my 1988 edition.

--
Kenneth J. Pronovici <pronovic@debian.org>

Oliver Kurth

2004-02-17, 7:34 am

On Tue, 2004-02-17 at 17:58, Andrew Suffield wrote:
> On Mon, Feb 16, 2004 at 03:06:33PM +0000, Will Newton wrote:
[color=blue]
>
> Good grief, that's *terrible* C. Don't do things like that. The
> problem here is not a lack of exceptions, it's just bad code. As
> usual.


This practice is used very exensively in the linux kernel code, and in
most cases it is very convenient, and easy to read. As long as you use
gotos just for exceptions, it is okay. In all other cases I agree, it is
a big fat DON'T.

Greetings,
Oliver


Andrew Suffield

2004-02-17, 4:33 pm

On Tue, Feb 17, 2004 at 07:21:00PM +0000, Will Newton wrote:
> On Tuesday 17 Feb 2004 4:58 pm, Andrew Suffield wrote:
>
>
> As usual? OK.
>
> That is an often used convention, used by many substantial pieces of C code
> that you are running on your system right now. Admittedly it is much more
> often used in system level situations than application code. It can be argued
> that much C is *terrible*. That's why it's C.


Your point is that there is a lot of bad C code around? Yes, that's
certainly true, but it's not an excuse for writing more bad C.

>
> <snip>
>
>
> Unfortunately this doesn't necessarily work if you need to do work
> (allocations, side effects) in between checking foo and bar.


It does if you do it right. I don't exactly write this sort of code
infrequently; it's quite easy to structure your code in a manner that
works neatly and effectively.

--
.''`. ** Debian GNU/Linux ** | Andrew Suffield
: :' : http://www.debian.org/ |
`. `' |
`- -><- |

Andrew Suffield

2004-02-17, 4:33 pm

On Tue, Feb 17, 2004 at 01:54:53PM -0600, Kenneth Pronovici wrote:
> On Tue, Feb 17, 2004 at 07:21:00PM +0000, Will Newton wrote:
>
> In fact, K&R even recommends this approach when cleanup is required, so
> it's not as if there isn't precedent:
>
> This organization is handy if the error-handling code is non-trivial,
> and if errors can occur in several places. [1]


K&R is a veritable tome of bad advice. It really should be avoided;
it's horribly outdated. Optimising compilers have obsoleted most of
it (at the time when it was written, function calls weren't cheap).

--
.''`. ** Debian GNU/Linux ** | Andrew Suffield
: :' : http://www.debian.org/ |
`. `' |
`- -><- |

Andrew Suffield

2004-02-17, 4:33 pm

On Tue, Feb 17, 2004 at 09:18:15PM +0100, Oliver Kurth wrote:
> On Tue, 2004-02-17 at 17:58, Andrew Suffield wrote:
>
>
> This practice is used very exensively in the linux kernel code, and in
> most cases it is very convenient, and easy to read. As long as you use
> gotos just for exceptions, it is okay. In all other cases I agree, it is
> a big fat DON'T.


This is delusional. It's quite unnecessary here and makes the code
messier; that was the point of my previous mail, where I sketched out
one alternative approach. It's the sort of thing done by somebody who
has exceptions on the brain, rather than just thinking about what the
code should be doing.

--
.''`. ** Debian GNU/Linux ** | Andrew Suffield
: :' : http://www.debian.org/ |
`. `' |
`- -><- |

Steve McIntyre

2004-02-17, 8:33 pm

In article <20040218051341.GB1791@suffields.me.uk> you write:
>
>K&R is a veritable tome of bad advice. It really should be avoided;
>it's horribly outdated. Optimising compilers have obsoleted most of
>it (at the time when it was written, function calls weren't cheap).


<sigh> Most of K&R is still completely relevant, and IMO it's still
far and away the best C reference. How well your compiler optimises
does not affect that in the slightest.

--
Steve McIntyre, Cambridge, UK. steve@einval.com
"It's actually quite entertaining to watch ag129 prop his foot up on
the desk so he can get a better aim." [ seen in ucam.chat ]


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Joey Hess

2004-02-18, 6:33 am

Andrew Suffield wrote:
> However, it results in code that throws exceptions to the user rather
> than useful error messages, which is amateurish. The user should never
> see an exception unless there is a bug in your code; errors from the
> system should be handled properly. This *does* make your code twice as
> long, but it will not make it any less readable if you do it
> right. Failing to do it is like failing to test your code before
> releasing it, or trusting data read from the network - it is not
> something that has any place in a serious program.


You tempt me to file a bug on any Python program that throws me an
exception, much as I do on any C program that segfaults.

It would be a lot of bug reports though. :-/ Including some on code
written by other participants of this thread.

PS, I wholly agree with you.

--
see shy jo

Nathanael Nerode

2004-02-18, 8:34 am

Zenaan Harkness wrote:
>

to which Andrew Suffield wrote:
>C


Are you referring to K&R C, C89, or C99? :-)

Actually, Bourne shell has had no versioning problems. Writing in portable
Bourne shell is sometimes an adventure in obscurity, however (the absence of
subroutines particularly hurts), so I can't really recommend it.

Frankly, a language without versioning problems is a tired old semi-obsolete
language. You need to look for a balance between endless incompatible
changes and availability of reasonable features. PERL does pretty well on
that point.

(As others have pointed out many times, it's easy to write incomprehensible,
unmaintainable PERL code. So -- remember to not do that. ;-) The same
caution applies if you choose C! )


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Isaac To

2004-02-18, 1:33 pm

>>>>> "Andrew" == Andrew Suffield <asuffield@debian.org> writes:

Andrew> It does if you do it right. I don't exactly write this sort of
Andrew> code infrequently; it's quite easy to structure your code in a
Andrew> manner that works neatly and effectively.

Perhaps you want to enlighten the kernel developers. A typical kernel
function, say sys_getpgid, is implemented (in 2.4.24 kernel) like this:

asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
{
struct task_struct * p;
int err = -EINVAL;

if (!pid)
pid = current->pid;
if (!pgid)
pgid = pid;
if (pgid < 0)
return -EINVAL;

/* From this point forward we keep holding onto the tasklist lock
* so that our parent does not change from under us. -DaveM
*/
read_lock(&tasklist_lock);

err = -ESRCH;
p = find_task_by_pid(pid);
if (!p)
goto out;

if (p->p_pptr == current || p->p_opptr == current) {
err = -EPERM;
if (p->session != current->session)
goto out;
err = -EACCES;
if (p->did_exec)
goto out;
} else if (p != current)
goto out;
err = -EPERM;
if (p->leader)
goto out;
if (pgid != pid) {
struct task_struct * tmp;
for_each_task (tmp) {
if (tmp->pgrp == pgid &&
tmp->session == current->session)
goto ok_pgid;
}
goto out;
}

ok_pgid:
p->pgrp = pgid;
err = 0;
out:
/* All paths lead to here, thus we are safe. -DaveM */
read_unlock(&tasklist_lock);
return err;
}

It is *full* of goto. Those who are used to writing application code will
find it is all too tempted to simply "return" at the point of error, and
learn bitterly that the lock they are holding is not unlocked, leaving them
a dead kernel. It is possible to write something like this

...
if (something with error)
return do_unlock_and_return(&tasklist_lock, err);
...

but it is more difficult to make sure that you unlock everything (originally
you just have to make sure that there is no "return" statement after
locking, now you have to make sure there is no "return" statement which is
not guarded by the function after locking); and it generate more code which
is mostly unused (the function is going to be inlined into the function
given its small size). And its one more function, which means more
difficult to maintain.

For me, if "goto" is used in a disciplined way, one shouldn't be afraid to
use them, especially if it simplify your code.

Regards,
Isaac.


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Nano Nano

2004-02-18, 2:33 pm

On Thu, Feb 19, 2004 at 10:42:56AM +0800, Isaac To wrote:
> For me, if "goto" is used in a disciplined way, one shouldn't be afraid to
> use them, especially if it simplify your code.


I developped a technique for application-level programming:

LOCK* lock = get_lock ();
int ok = (lock != NULL);
if (ok)
ok = foo ();
if (ok)
ok = bar ();
if (LOCK != NULL)
release (lock);
return ok;

Instead of:

LOCK* lock = get_lock ();
if (lock == NULL)
goto FAIL;
if (!foo ())
goto FAIL;
if (!bar ())
goto FAIL;
return 1;
FAIL:
if (NULL != foo)
release (lock);
return 0;

I prefer the former: the gotos are if (ok)'s instead.
I just like the "not jumping" aspect: as the routine grows in complexity
(as it shouldn't, but it does), the depth-one, linear flow is easier for
me to grok.


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Ben Burton

2004-02-18, 2:33 pm


This is one of the things I do like about C++:

{
Lock lock(resource); // constructor does the locking,
// destructor does the unlocking

if (! lock.ok())
return false;
if (! foo())
return false;
if (! bar())
return false;
return true;
}

And the unlocking happens automatically whenever the lock goes out of
scope.

b.


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Alexandre

2004-02-18, 7:33 pm

On Thu, Feb 19, 2004 at 10:42:56AM +0800, Isaac To wrote:

> It is *full* of goto. Those who are used to writing application code will
> find it is all too tempted to simply "return" at the point of error, and
> learn bitterly that the lock they are holding is not unlocked, leaving them
> a dead kernel. It is possible to write something like this


I had sworn I wouldn't join this thread... <sigh>

This cas is handled very cleanly by python's try...finally construct,
which take care of calling the cleanup code in *all* cases, even the
one you'd have forgotten.

The exception mechanism in any language is not about displaying a
traceback to the user (and Joey, please do file bugs against any package
which does so, in the same way you'd file bugs against programs dumping
cores), it is about separating the normal flow of event from the error
flow, and enabling corrective actions to take place where it makes sense
to put them.

--
Alexandre Fayolle LOGILAB, Paris (France).
http://www.logilab.com http://www.logilab.fr http://www.logilab.org


Isaac To

2004-02-18, 8:33 pm

>>>>> "Alexandre" == Alexandre <Alexandre.Fayolle@logilab.fr> writes:

Alexandre> On Thu, Feb 19, 2004 at 10:42:56AM +0800, Isaac To wrote:[color=blue]

Alexandre> I had sworn I wouldn't join this thread... <sigh>

Alexandre> This cas is handled very cleanly by python's try...finally
Alexandre> construct, which take care of calling the cleanup code in
Alexandre> *all* cases, even the one you'd have forgotten.

I'm aware of them, although Python or Java's "try-finally" is not as clean
as C++'s "allocation is initialization", or C#'s "using" construct. On the
other hand, they are not available to C, so goto is the escape. Of course
one must do it in a disciplined way: putting goto in every place of your
code will kill you very quickly when reading your own code again. But goto
is really not as horrible as it sounds, especially for those people who
avoid them just because their structured programming teacher teach them that
way.

Regards,
Isaac.


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Lars Wirzenius

2004-02-18, 8:33 pm

to, 2004-02-19 kello 11:06, Alexandre kirjoitti:
> The exception mechanism in any language is not about displaying a
> traceback to the user (and Joey, please do file bugs against any package
> which does so, in the same way you'd file bugs against programs dumping
> cores)


I concur, even if I have such a program in Debian myself. I'll go and
fix it as soon as I have a moment to spare, however.

--
http://liw.iki.fi/liw/log/


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Isaac To

2004-02-18, 8:33 pm

>>>>> "Nano" == Nano Nano <40208.nospam@comcast.net> writes:

Nano> On Thu, Feb 19, 2004 at 10:42:56AM +0800, Isaac To wrote:[color=blue]

Nano> I developped a technique for application-level programming:

Nano> LOCK* lock = get_lock (); int ok = (lock != NULL); if (ok) ok =
Nano> foo (); if (ok) ok = bar (); if (LOCK != NULL) release (lock);
Nano> return ok;

Nano> Instead of:

Nano> LOCK* lock = get_lock (); if (lock == NULL) goto FAIL; if (!foo
Nano> ()) goto FAIL; if (!bar ()) goto FAIL; return 1; FAIL: if (NULL !=
Nano> foo) release (lock); return 0;

Nano> I prefer the former: the gotos are if (ok)'s instead. I just like
Nano> the "not jumping" aspect: as the routine grows in complexity (as
Nano> it shouldn't, but it does), the depth-one, linear flow is easier
Nano> for me to grok.

Sorry that I have to express my disagreement. A goto towards the end of a
function, especially when the label name clearly indicates that, is
straight-forward to read. To somebody who get used to that sort of code,
"goto out" would says directly that "I'm going out of this function, except
that I have something to clean up. Apart from that, ignore this case." The
"if (ok)" construct is much more complicated, and the effect depends on the
composite effects of all the if statements. So the "if something goto
label" construct has a linear complexity, the complexity coming from the
position where you place the label. The "if (ok) next_statement" has
exponential complexity, the complexity coming from which statement you place
an "if (ok)" and which you don't. I, for all purpose, would write a goto
instead.

Regards,
Isaac.


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Nano Nano

2004-02-18, 9:33 pm

On Thu, Feb 19, 2004 at 05:58:56PM +0800, Isaac To wrote:
> Sorry that I have to express my disagreement. A goto towards the end of a
> function, especially when the label name clearly indicates that, is
> straight-forward to read. To somebody who get used to that sort of code,
> "goto out" would says directly that "I'm going out of this function, except
> that I have something to clean up. Apart from that, ignore this case." The
> "if (ok)" construct is much more complicated, and the effect depends on the
> composite effects of all the if statements. So the "if something goto
> label" construct has a linear complexity, the complexity coming from the
> position where you place the label. The "if (ok) next_statement" has
> exponential complexity, the complexity coming from which statement you place
> an "if (ok)" and which you don't. I, for all purpose, would write a goto
> instead.


I'll reply once on list, if everybody yells I'll take it off list.

I'm left-handed, right-brained: visual thinker (maybe you are too), but
I feel the opposite way you do for the same reasons!

My eye has to skip over GOTOs or it has to skip over IFs. Same diff.

The if version is plodding and stupid, like me. It is complex but only
first order complexity (an asymptote). Do one stupid dumb thing over
and over again. The GOTO version is elegant and clever. I tend to
screw clever things up.

My brain can see the pattern of the IF version and say, okay, here,
semantically I want to know the state of the compound operation (ok),
and here I want to know the state of the resource (the lock).

I'm dumb and stupid like the IF version. I'm basically a really smart
monkey. I'll rob my grandmother if you just tell me honestly that's
what you want me to do, without reservations. I'm a 21st century
plumber.

Although I can get into the other way too. All I know is I've written
arbitrarily complex code of the IF type because in my head
dumb-but-plodding is complex like the integers; but clever is complex
like the continuum. I'm stupid.


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Matthias Urlichs

2004-02-19, 2:34 am

Hi, Andrew Suffield wrote:

> My criticisms were of using exceptions to avoid handling errors, which was
> the proposed "advantage".


Actually, I didn't say that at all. On the contrary, exceptions are there
to _handle_ errors.

The advantage of exceptions IMHO is that you can handle errors _once_, at
the point where it's convenient to do so / they are shown to the user
/ whatever makes sense for your application, instead of being forced to
add explicit error-checking code to every single line that could
conceivably throw an error.

Plus, even if you handle the error, you can still get an exact backtrace
to the place where it occurred, so you can store it / package it in a bug
email / whatever.

Plus, you can wrap critical code in cleanup handlers without changing any
of the rest of your error handling logic. Example:

....
f=create_a_file(name)
try:
do_something_insanely_complicated(f)
except:
os.unlink(f)
raise

What this does is fairly obvious. What's more, this is a fairly standard
Python idiom which quickly becomes second nature (IMHO).

Now try the same thing in Perl.

--
Matthias Urlichs


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Matthias Urlichs

2004-02-19, 3:34 am

Hi, Andrew Suffield wrote:

> This is delusional. It's quite unnecessary here and makes the code
> messier; that was the point of my previous mail, where I sketched out one
> alternative approach.


You are using different units to measure "mess". Linus Torvalds, AFAIR,
uses line length, function length, and indentation levels. Those say that
your example is far messier.

The point is that the more succinctly you can express your ideas in code,
the less work it is to understand it (unless you're obfuscating, but we're
not talking about that).

Error checking naturally splits into two parts, (a) check for it and (b)
handle it. Python's exceptions mean that there is NO code at all which
does (a) because that's the interpreter's job, therefore your code becomes
easier to understand. (b) is not affected; there's no practical difference
between Python

try: do_something()
except: handle_error()
else: do_when_ok()

and C (or PERL or ...)

if (!(err=do_something()))
handle_error(err)
else do_when_ok()

except that in Python you can use multi-line statements which do something
instead of calling a function, which sometimes (not always) increases
readability.

IMHO, and all that.
--
Matthais Urlichs


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Matthias Urlichs

2004-02-19, 3:34 am

Hi, Julian Mehnle wrote:

> That's true, but there's no reason not to use exceptions in Perl. They're
> even built-in, although you eccentrically (or shall I say, exceptionally)
> raise them with `die`, and catch them with `eval {}` -- and yes, that *is*
> efficient. As syntactic sugar, you may want to use the CPAN module
> "Error", though.


I thought so once, too. The problem is that this is not a standard Perl
idiom, therefore it's not all that well tested, and lots of little niggly
difficult-to-reproduce bugs (reference counting, error reporting, et al.),
still lurk in the corners when you do any kind of non-local exit.

And yes, I have PERL bugs open about that.

NB, a second problem is that eval{} catches everything. Usually,
that's not what you want to do.

--
Matthias Urlichs


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Joey Hess

2004-02-19, 4:34 am

Matthias Urlichs wrote:
> f=create_a_file(name)
> try:
> do_something_insanely_complicated(f)
> except:
> os.unlink(f)
> raise
>
> What this does is fairly obvious. What's more, this is a fairly standard
> Python idiom which quickly becomes second nature (IMHO).
>
> Now try the same thing in Perl.


$f=create_a_file($name);
eval {
do_something_insanely_complicated($f);
};
if ($@) {
unlink $name;
die $@;
}

Of course this is rare, since PERL code that is ill-behaved enough to
throw an exception is rare, so it's more standard PERL idiom to write:

do_something_insanely_complicated(create
_a_file($name)) or unlink($name);

--
see shy jo

Chad Walstrom

2004-02-19, 4:34 am

On Thu, Feb 19, 2004 at 12:10:18PM -0500, Joey Hess wrote:
>
> $f=create_a_file($name);
> eval {
> do_something_insanely_complicated($f);
> };
> if ($@) {
> unlink $name;
> die $@;
> }


<rant>
ACK! What's with all the $@ stuff?! This is my biggest pet peeve with
Perl. Syntactic sugar. Perhaps to a PERL programmer, this makes sense.
Because I have a background in shell programming, I interpret "$@" to
mean "arguments $1...$N". Obviously wrong.

[Looks up PERL syntactic sugar reference manualorama 'perldoc perlcheat']

"$@ eval error"

Ick. Almost as bad as $_.
</rant>

> Of course this is rare, since PERL code that is ill-behaved enough to
> throw an exception is rare, so it's more standard PERL idiom to write:
>
> do_something_insanely_complicated(create
_a_file($name)) or unlink($name);


OK. This makes sense. No syntactic sugar involved. Clean, precise.
If all PERL were like this, I'd be much happier using it.

--
Chad Walstrom <chewie@wookimus.net> http://www.wookimus.net/
assert(expired(knowledge)); /* core dump */

Don Armstrong

2004-02-19, 4:34 am

On Thu, 19 Feb 2004, Matthias Urlichs wrote:
> a second problem is that eval{} catches everything. Usually, that's
> not what you want to do.


That's (sometimes) why the

eval { ... };
die $@ if $@ !~ //;

or similar construct comes into play. Moreover, most of the errors
where the code shouldn't die are related to various forms of use
strict; which can be turned off using the appropriate pragma. [But
discussing exception handling in PERL is much easier if there's a
specific example in mind.]


Don Armstrong

--
Build a fire for a man, an he'll be warm for a day. Set a man on
fire, and he'll be warm for the rest of his life. -- Jules Bean

http://www.donarmstrong.com
http://rzlab.ucr.edu


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Matt Zimmerman

2004-02-19, 4:34 am

On Thu, Feb 19, 2004 at 12:10:18PM -0500, Joey Hess wrote:

> Matthias Urlichs wrote:
>
> $f=create_a_file($name);
> eval {
> do_something_insanely_complicated($f);
> };
> if ($@) {
> unlink $name;
> die $@;
> }


The principal difference being that $@ is a string, while the exception
raised in Matthias' is a real exception. This means that various error
conditions can be handled programmatically, rather than aborting with an
error message.

--
- mdz


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Joey Hess

2004-02-19, 5:34 am

Matt Zimmerman wrote:
> The principal difference being that $@ is a string, while the exception
> raised in Matthias' is a real exception. This means that various error
> conditions can be handled programmatically, rather than aborting with an
> error message.


$@ can be an exception object if you want it to be. perldoc -f die

--
see shy jo

Colin Watson

2004-02-19, 5:34 am

On Thu, Feb 19, 2004 at 11:25:29AM -0600, Chad Walstrom wrote:
> On Thu, Feb 19, 2004 at 12:10:18PM -0500, Joey Hess wrote:
>
> <rant>
> ACK! What's with all the $@ stuff?! This is my biggest pet peeve with
> Perl. Syntactic sugar.


use English;
do_stuff_with_this_instead($EVAL_ERROR);


--
Colin Watson [cjwatson@flatline.org.uk]


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Matt Zimmerman

2004-02-19, 5:34 am

On Thu, Feb 19, 2004 at 01:21:23PM -0500, Joey Hess wrote:

> Matt Zimmerman wrote:
>
> $@ can be an exception object if you want it to be.


I found exactly zero occurrences of this practice in the standard Perl
library and all modules I have installed on my system, and perlvar(1) says
it is a string, so I imagine this techinque is not very popular. Have you
ever used it? Standardized error handling is a lot less interesting if the
"standard" is limited to code that you write yourself.

> perldoc -f die


<shields eyes>

If LIST is empty and $@ already contains a value (typically
from a previous eval) that value is reused after appending
"\t...propagated". This is useful for propagating exceptions:

eval { ... };
die unless $@ =~ /Expected exception/;


--
- mdz


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Will Newton

2004-02-19, 5:34 am

On Thursday 19 Feb 2004 6:24 pm, Colin Watson wrote:

> use English;
> do_stuff_with_this_instead($EVAL_ERROR);


Then try working on a project with another developer who doesn't use English
and get the worst of both worlds.

It would be funnier if I didn't do it for a living...


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Joey Hess

2004-02-19, 5:34 am

Matt Zimmerman wrote:
> I found exactly zero occurrences of this practice in the standard Perl
> library and all modules I have installed on my system, and perlvar(1) says
> it is a string, so I imagine this techinque is not very popular. Have you
> ever used it? Standardized error handling is a lot less interesting if the
> "standard" is limited to code that you write yourself.


Yes, mooix's error handling throws Mooix::Error objects around, these
generate appropriate stack traces in appropriate contexts, etc. This is
the only system (and it's a very large and complex system) in which I
have ever felt the need to use exceptions in perl.

Anything that depends on liberror-perl will likely throw object based
exceptions too.

--
see shy jo

Andrew Suffield

2004-02-19, 6:34 am

On Thu, Feb 19, 2004 at 05:26:18PM +0100, Matthias Urlichs wrote:
> Hi, Julian Mehnle wrote:
>
>
> I thought so once, too.


> The problem is that this is not a standard Perl
> idiom,


That's very wrong.

> therefore it's not all that well tested, and lots of little niggly
> difficult-to-reproduce bugs (reference counting, error reporting, et al.),
> still lurk in the corners when you do any kind of non-local exit.


That's frequently unrelated (exit would have the same problems). There
are some subtle issues with global destruction still in 5.8.

> And yes, I have PERL bugs open about that.


Can't see any.

> NB, a second problem is that eval{} catches everything. Usually,
> that's not what you want to do.


Which is why you have Error and Exception::Class.

--
.''`. ** Debian GNU/Linux ** | Andrew Suffield
: :' : http://www.debian.org/ |
`. `' |
`- -><- |

Andrew Suffield

2004-02-19, 7:34 am

On Thu, Feb 19, 2004 at 10:42:56AM +0800, Isaac To wrote:
>
> Andrew> It does if you do it right. I don't exactly write this sort of
> Andrew> code infrequently; it's quite easy to structure your code in a
> Andrew> manner that works neatly and effectively.
>
> Perhaps you want to enlighten the kernel developers.


Not particularly. I am very unlikely to ever work on that code.

> A typical kernel
> function, say sys_getpgid, is implemented (in 2.4.24 kernel) like this:
>
> asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
> {
> struct task_struct * p;
> int err = -EINVAL;
>
> if (!pid)
> pid = current->pid;
> if (!pgid)
> pgid = pid;
> if (pgid < 0)
> return -EINVAL;
>
> /* From this point forward we keep holding onto the tasklist lock
> * so that our parent does not change from under us. -DaveM
> */
> read_lock(&tasklist_lock);
>
> err = -ESRCH;
> p = find_task_by_pid(pid);
> if (!p)
> goto out;
>
> if (p->p_pptr == current || p->p_opptr == current) {
> err = -EPERM;
> if (p->session != current->session)
> goto out;
> err = -EACCES;
> if (p->did_exec)
> goto out;
> } else if (p != current)
> goto out;
> err = -EPERM;
> if (p->leader)
> goto out;
> if (pgid != pid) {
> struct task_struct * tmp;
> for_each_task (tmp) {
> if (tmp->pgrp == pgid &&
> tmp->session == current->session)
> goto ok_pgid;
> }
> goto out;
> }
>
> ok_pgid:
> p->pgrp = pgid;
> err = 0;
> out:
> /* All paths lead to here, thus we are safe. -DaveM */
> read_unlock(&tasklist_lock);
> return err;
> }


And here's how I'd do it (just fixing this one issue; I wouldn't have
written the rest like this anyway - I'd have used some comments, for
starters):

static long
do_setpgid(pid_t pid, pid_t pgid)
{
struct task_struct * p;

p = find_task_by_pid(pid);
if (!p)
return -ESRCH;

if (p->p_pptr == current || p->p_opptr == current) {
if (p->session != current->session)
return -EPERM;
if (p->did_exec)
return -EACCES;
} else if (p != current)
return -ESRCH;

if (p->leader)
return -EPERM;

if (pgid != pid) {
struct task_struct * tmp;
for_each_task (tmp) {
if (tmp->pgrp == pgid &&
tmp->session == current->session)
{
p->pgrp = pgid;
return 0;
}
}
return -EPERM;
}
}

asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
{
long ret;

if (!pid)
pid = current->pid;
if (!pgid)
pgid = pid;
if (pgid < 0)
return -EINVAL;

read_lock(&tasklist_lock);

ret = do_setpgid(pid, pgid);

read_unlock(&tasklist_lock);
return ret;
}

(The idiom here is: check input, acquire resources, process, release
resources, and split those out into other functions as needed - strict
two-phase locking, which avoids deadlocks into the bargain)

No gotos, no need to worry about the current value of err, and
significant code is cleanly separated from locking and argument
checking. And both functions are rather easier to read (if a function
is too big to fit entirely on screen at once, you probably need to
split it up - the exception is when it's caused by huge comments).

Most problems in computer science are solved by adding another layer
of abstraction.

> For me, if "goto" is used in a disciplined way, one shouldn't be afraid to
> use them, especially if it simplify your code.


It never simplifies code. That's been the whole point for the past
Eris-knows-how-many years. Any time that you think you've found a use
of goto that makes the code simpler, there's another way to write it
without goto that would be simpler still. Example above.

--
.''`. ** Debian GNU/Linux ** | Andrew Suffield
: :' : http://www.debian.org/ |
`. `' |
`- -><- |

Andrew Suffield

2004-02-19, 7:34 am

On Thu, Feb 19, 2004 at 05:17:27PM +0100, Matthias Urlichs wrote:
> Hi, Andrew Suffield wrote:
>
>
> You are using different units to measure "mess". Linus Torvalds, AFAIR,
> uses line length, function length, and indentation levels. Those say that
> your example is far messier.


No I'm not, and no they don't. My example has shorter functions
(because it's split into several), and no more indentation or line
length.

Learn to count.

> The point is that the more succinctly you can express your ideas in code,
> the less work it is to understand it (unless you're obfuscating, but we're
> not talking about that).


Yes, that's precisely the point.

--
.''`. ** Debian GNU/Linux ** | Andrew Suffield
: :' : http://www.debian.org/ |
`. `' |
`- -><- |

Andrew Suffield

2004-02-19, 7:34 am

On Thu, Feb 19, 2004 at 10:53:31AM -0800, Matt Zimmerman wrote:
> On Thu, Feb 19, 2004 at 01:21:23PM -0500, Joey Hess wrote:
>
>
> I found exactly zero occurrences of this practice in the standard Perl
> library and all modules I have installed on my system, and perlvar(1) says
> it is a string, so I imagine this techinque is not very popular. Have you
> ever used it? Standardized error handling is a lot less interesting if the
> "standard" is limited to code that you write yourself.


Look at the Error and Exception::Class modules.

It's rare because in perl, you *very* rarely need anything as complex
as a full exception. Most of the time you don't need exceptions at all
- return values are quite adequete (because (a) you can return any
arbitrarily complicated object, and (b) you have undef for error
conditions).

It's not that the tools aren't well developed, it's that they aren't
needed most of the time.

--
.''`. ** Debian GNU/Linux ** | Andrew Suffield
: :' : http://www.debian.org/ |
`. `' |
`- -><- |

Andrew Suffield

2004-02-19, 7:34 am

On Thu, Feb 19, 2004 at 11:25:29AM -0600, Chad Walstrom wrote:
[color=blue]
> If all PERL were like this, I'd be much happier using it.


All well-written PERL is like this. If it's not clean and precise then
it's bad perl. The fact that there is a lot of bad PERL around does
not affect this.

It is not difficult to write PERL like this, but it does require that
the programmer suppresses the urge to be a retard.

--
.''`. ** Debian GNU/Linux ** | Andrew Suffield
: :' : http://www.debian.org/ |
`. `' |
`- -><- |

Matt Zimmerman

2004-02-19, 7:34 am

On Thu, Feb 19, 2004 at 08:20:33PM +0000, Andrew Suffield wrote:

> It's rare because in perl, you *very* rarely need anything as complex
> as a full exception. Most of the time you don't need exceptions at all
> - return values are quite adequete (because (a) you can return any
> arbitrarily complicated object, and (b) you have undef for error
> conditions).


There's nothing magic about PERL that makes it such that you don't need more
featureful error handling. Those features are not unique to PERL by a wide
margin; in fact they are quite widespread.

--
- mdz


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Andrew Suffield

2004-02-19, 7:34 am

On Thu, Feb 19, 2004 at 05:00:31PM +0100, Matthias Urlichs wrote:
> Hi, Andrew Suffield wrote:
>
>
> Actually, I didn't say that at all. On the contrary, exceptions are there
> to _handle_ errors.


What you said was that it made the code shorter. I stipulate that, if
you handle the errors, it does no such thing.

Well-written code without using exceptions should be slightly shorter
than well-written code using exceptions. If you find that this is not
the case, then your code without exceptions is not good enough. (The
tradeoff of exceptions is worthwhile in the scenario I described
earlier - throwing errors to an unknown location that may or may not
understand how to handle them, such as across a library API).

The only way to get shorter is to not handle the errors - which is the
norm in python.

<snip>

> Now try the same thing in Perl.


All the time. There's at least three entirely distinct approaches in
perl (which one is appropriate depends on what you're doing), unlike
python which attempts to force every scenario into one form. Otherwise
there's no difference. Getting PERL to use the Python syntax is not
hard (but getting "close enough" is trivial, and the rest of the way
isn't worth the effort).

--
.''`. ** Debian GNU/Linux ** | Andrew Suffield
: :' : http://www.debian.org/ |
`. `' |
`- -><- |

Andrew Suffield

2004-02-19, 7:34 am

On Thu, Feb 19, 2004 at 12:31:22PM -0800, Matt Zimmerman wrote:
> On Thu, Feb 19, 2004 at 08:20:33PM +0000, Andrew Suffield wrote:
>
>
> There's nothing magic about PERL that makes it such that you don't need more
> featureful error handling. Those features are not unique to PERL by a wide
> margin; in fact they are quite widespread.


C/C++. Languages with both of these features do indeed not normally
have any need for exceptions.

--
.''`. ** Debian GNU/Linux ** | Andrew Suffield
: :' : http://www.debian.org/ |
`. `' |
`- -><- |

Matt Zimmerman

2004-02-19, 7:34 am

On Thu, Feb 19, 2004 at 08:35:05PM +0000, Andrew Suffield wrote:

> The only way to get shorter is to not handle the errors - which is the
> norm in python.


This is a weak argument against exceptions (and/or python) for the same
reasons that "this bit of PERL is a mess" is a weak argument against Perl.

--
- mdz


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Matt Zimmerman

2004-02-19, 7:34 am

On Thu, Feb 19, 2004 at 08:36:51PM +0000, Andrew Suffield wrote:

> On Thu, Feb 19, 2004 at 12:31:22PM -0800, Matt Zimmerman wrote:
>
> C/C++. Languages with both of these features do indeed not normally have
> any need for exceptions.


What about them? C doesn't really have (a), and doesn't have exceptions
either. C++ has both, and also has exceptions.

--
- mdz


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Andrew Suffield

2004-02-19, 7:34 am

On Thu, Feb 19, 2004 at 12:40:19PM -0800, Matt Zimmerman wrote:
> On Thu, Feb 19, 2004 at 08:35:05PM +0000, Andrew Suffield wrote:
>
>
> This is a weak argument against exceptions (and/or python) for the same
> reasons that "this bit of PERL is a mess" is a weak argument against Perl.


It's not an argument against exceptions. Check the context.

--
.''`. ** Debian GNU/Linux ** | Andrew Suffield
: :' : http://www.debian.org/ |
`. `' |
`- -><- |

Bart Schuller

2004-02-19, 7:34 am

On Thu, Feb 19, 2004 at 01:21:23PM -0500, Joey Hess wrote:
> Matt Zimmerman wrote:
>
> $@ can be an exception object if you want it to be. perldoc -f die


And see liberror-perl for a module which adds all the try, catch,
finally syntactic sugar and the root of an exception hierarchy.


Now that I'm posting anyway, I might as well react to the rest of the
thread...

Perl is a full-blown language, with a rich history and culture. Yes, you
can learn a subset pretty quick if you know shell, C, or awk.
It can also be very maintainable, object-oriented and all. That doesn't
magically happen though. PERL doesn't transform a (cgi) scripter into an
OO architect all by itself.

Learning the language also means accepting the seemingly weird symbols
like $_, $@ and <=>. I can still remember wondering what the hell the
repeating repetition and the squigly mean in C++'s

Myclass::Myclass() {}
Myclass::~Myclass() {}

but I accept them. You don't have to like it, you can just use another
language. But don't accuse the language of being unreadable or
unmaintainable just because you don't want to learn it.

Getting back to the OP's problem, what language to pick for a new
project:
Look a the communities surrounding the languages. www.perlmonks.org is
particularly helpful in the PERL world. Browse search.cpan.org to see
what libraries are available. Witness the extremely good support you get
from the perl5-porters mailinglist when you manage to find a bug in perl
itself.

But by all means: try them out. You're lucky to be able to choose
without prejudice.

--
Bart.


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Matt Zimmerman

2004-02-19, 7:34 am

On Thu, Feb 19, 2004 at 08:48:24PM +0000, Andrew Suffield wrote:

> On Thu, Feb 19, 2004 at 12:40:19PM -0800, Matt Zimmerman wrote:
>
> It's not an argument against exceptions. Check the context.


Context:

> Exceptions should only be used for exceptional circumstances, and even
> then think twice. The single thing for which they are useful is [...]
> This is not often useful - library APIs are the most notable case. Using
> exceptions in any other circumstances is usually a really bad idea.


Message-id: <20040217165810.GA3932@suffields.me.uk>

In summary, "Using exceptions is usually a really bad idea except in this
one circumstance, which is not often useful."

Fine, granted. You're arguing against USING exceptions, not their mere
existence.

<rolls eyes>

--
- mdz


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Philip Brown

2004-02-19, 8:34 am

On Thu, Feb 19, 2004 at 10:42:56AM +0800, Isaac To wrote:
> ...
> Perhaps you want to enlighten the kernel developers. A typical kernel
> function, say sys_getpgid, is implemented (in 2.4.24 kernel) like this:
>
> asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
> {
> ....
>
> /* From this point forward we keep holding onto the tasklist lock
> * so that our parent does not change from under us. -DaveM
> */
> read_lock(&tasklist_lock);
>
> err = -ESRCH;
> p = find_task_by_pid(pid);
> if (!p)
> goto out;
>
> if (p->p_pptr == current || p->p_opptr == current) {
> err = -EPERM;
> if (p->session != current->session)
> goto out;
>...
> out:
> /* All paths lead to here, thus we are safe. -DaveM */
> read_unlock(&tasklist_lock);
> return err;
> }





An alternative method in C, if you dont want to write a new function,
is to fake one in-line, using a one-shot while loop.
No goto required. Just an indent level.
Which has a nice side effect of very clearly demarking,
"Hey, something special is going on here"
(ie: I'm HOLDING A LOCK)



asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
{
int err=0;

....

read_lock(&tasklist_lock);
do {
p = find_task_by_pid(pid);
if (!p){
err=-ESRCH;
break;
}
if (p->session != current->session){
err = -EPERM;
break;
}

... /* do stuff... */

} while (0); /* allow for early termination */

read_unlock(&tasklist_lock);
return err;
}


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Will Newton

2004-02-19, 8:34 am

On Thursday 19 Feb 2004 8:22 pm, Andrew Suffield wrote:

> All well-written PERL is like this. If it's not clean and precise then
> it's bad perl. The fact that there is a lot of bad PERL around does
> not affect this.


In my experience it is not so much that there is bad Perl, which there is, but
that PERL doesn't seem to scale to large teams. The "there's more than one
way to do it" idea hurts in big teams, you have to pick one way and stick to
it, or you get a hairball of conflicting styles. This is a problem with any
language, but Perl's idiosyncratic and extremely flexible syntax seems to
exascerbate the problem.

Are there any projects out there with ~200,000 lines of PERL and 8-10
full-time developers that aren't a total train wreck? (I know of one at least
that is)

> It is not difficult to write PERL like this, but it does require that
> the programmer suppresses the urge to be a retard.


One man's retard is another man's genius.


--
To UNSUBSCRIBE, email to debian-devel-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
Julian Mehnle

2004-02-19, 8:34 am

Matthias Urlichs wrote:
> Julian Mehnle wrote:
to[color=blue]
>=20
> I thought so once, too. The problem is that this is not a standard =

Perl
> idiom,


This has already been answered, so I won't go into that any more.

> therefore it's not all that well tested,


What makes you think so?

> and lots of little niggly difficult-to-reproduce bugs (reference
> counting, error reporting, et al.), still lurk in the corners when you
> do any kind of non-local exit.


Aside from the fact that I have never had any problems with "eval { =
die() }" (nor heard of any), your statements begs for the question: So, =
if Python's exception handling were having a bug, you would immediately =
recommend against using it?

> NB, a second problem is that eval{} catches everything. Usually,
> that's not what you want to do.


If you don't want to handle a certain exception, just re-raise it. You =
may also want to have a look at the "Error" module (i.e. the =
liberror-perl package). But others already pointed that out, too.


--
To UNS