Re: Lisp version of a C'ism

From: Kaz Kylheku (kaz_at_ashi.footprints.net)
Date: 08/17/04


Date: 17 Aug 2004 11:19:57 -0700

Pascal Bourguignon <spam@mouse-potato.com> wrote in message news:<87hdr28i6s.fsf@thalassa.informatimago.com>...
> M Jared Finder <hpalace@hpalace.com> writes:
>
> > Hello CLL! I have recently decided to start learning Lisp so I would
> > have more programming language experience then just C and C++. As
> > practice, I am working problem sets from my C school text, "Pointers
> > on C", but because of the fundamental differences between C and Lisp,
> > I find myself stuck on problem 1.3, which is as follows:
> >
> > Write a program that reads characters from stdin and writes them to
> > stdout. Also calculate a checksum by summing the input and ignoring
> > overflow.
>
> By the way, I don't see what this has to do with pointers???
>
> #include <stdio.h>
> int main(void){
> int sum=0;
> int ch;
> while(EOF!=(ch=getchar())){
> printf("%c",ch);
> sum+=ch;
> }
> printf("sum=%d\n",sum%256);
> return(0);
> }

This may be nice code for a newbie textbook on C programming, but it
doesn't actually solve any real-world problem, like meeting the
requirements for a *portable* checksumming utility: one that you could
for instance compile for Linux or Windows and use it to show that
files correctly transferred from one system to the other have the same
checksum.

I already mentioned the various issues in my other article in this
thread, but here is one more specific to the above code. It's a
nitpick, in that it won't happen except on some rare C programming
platforms.

On some embedded platforms, the type int is one byte wide. That is to
say, sizeof (int) is 1. Bytes are 32 bits wide. If you use getchar()
to read from a binary stream, you get values in the range 0 to
UCHAR_MAX, converted to type int. The value EOF is negative, so it
normally does not interfere in this range. However, if sizeof (int) is
1, then the range 0 to UCHAR_MAX doesn't fit into that type. This
means that some legal byte values are mapped to negative quantities,
and one of those negative quantities will have the same value as EOF.

So, to be maximally portable, you can't just check for EOF and assume
the data has ended. Rather, whenever your loop encounters EOF, it must
check the state of the stream to see whether there is an end-of-file
or error indication.

C is great for writing useless little textbook examples that are good
for selling the language to junior programmers, but when you are doing
actual engineering with real-world requirements, particularly ones
that include any kind of cross-platform portability, nothing is easy
any longer.

When we compare it to Lisp, we find that all the high level stuff is
easier in Lisp, and *correctly done* low-level stuff is *no harder*.

Where C shines is when you abuse the language, screw portability and
basically treat the compiler as an assembler. You write some code that
is undefined by ANSI, pass it through the compiler and verify that you
got the nice machine code you were looking for. Then when you upgrade
the compiler---or even invoke the same one in a different
configuration---you go through the same verification to check that
your undefined code still produces, by dumb luck, the right machine
code. When such an undefined hack, by dumb luck, produces working
code on two platforms, C is hailed as a ``portable assembler'',
usually accompanied by a round of denouncements of everything else
that produces inferior machine code.



Relevant Pages

  • Re: Typecast clarification
    ... char* you can dereference but not convert automatically. ... a value of type int*. ... concerned about portability). ... programming been made so seemingly simple that semi-intelligent semi- ...
    (comp.lang.c)
  • Re: LISPPA
    ... > memory resources. ... do in Common Lisp with code that runs about as fast. ... >> comparing Lisp with languages like C, Pascal and Basic, ... If by "visual programming" you mean the sort of ...
    (comp.lang.lisp)
  • Re: How Common Lisp sucks
    ... I could list some web servers written in Common Lisp. ... If a programming infrastructure fails ... underpinning than the p* languages. ...
    (comp.lang.lisp)
  • Re: Portability: Harmony between PC and microcontroller
    ... int is the natural integer type for the system. ... You are, perhaps unintentionally, paraphrasing the standard in a way ... One of the things that you might not realize is that the C programming ... In the real world, most embedded systems have more complex jobs to do, ...
    (comp.lang.c)
  • Re: LISPPA
    ... >> memory resources. ... > do in Common Lisp with code that runs about as fast. ... in "weaks languages": iteration instead of recursion and "local" ... I'm programming in Pascal since 1990 year, ...
    (comp.lang.lisp)