From: ········@gmail.com
Subject: Checksum (noob)
Date: 
Message-ID: <1167257581.843619.258790@73g2000cwn.googlegroups.com>
After a 10 year hiatus, I've begun experimenting with Lisp again.
Among other things, I've written a typical 8-bit modulo arithmetic
checksum routine, which would look like this in C++:

std::accumulate(lst.begin(), lst.end(),
                0, std::minus<unsigned char>());

Lisp version:

(defun checksum (lst)
  (logand (- 0 (apply '+ lst)) #xff))

I like it.  However, I'm wondering if it's appropriate to be paranoid
about a user passing invalid parameters to such a function (lists of
lists, integers, etc.) and causing havoc at runtime.

I've been looking over Graham's book, and he stresses the importance of
indentation.  Traditionally, I've shunned emacs, since it seems to get
*all* default behavior wrong, in every situation, and I don't have the
willpower to maintain a configuration.  But I thought I would give it
another try, since it seems to have been designed specifically for
Lisp.  Alas, it gets the indentation wrong, or at least it's different
than what Graham suggests (for example, in "if" expressions, it indents
the "then" differently than the "else").  Is there a configuration
parameter that I can use to fix it?
  (setq indent-lisp-correctly t)  ; wouldn't that be nice

I also noticed that gcl will accept a dotted list as a parameter to
checksum, but clisp will not.  What's the correct behavior?

Aaron

From: Zach Beane
Subject: Re: Checksum (noob)
Date: 
Message-ID: <m3zm9954n1.fsf@unnamed.xach.com>
·········@gmail.com" <········@gmail.com> writes:

> Lisp version:
> 
> (defun checksum (lst)
>   (logand (- 0 (apply '+ lst)) #xff))
> 
> I like it.  However, I'm wondering if it's appropriate to be paranoid
> about a user passing invalid parameters to such a function (lists of
> lists, integers, etc.) and causing havoc at runtime.

Document the proper parameters. If people violate the specification,
they rightly land in the debugger. 

Also, "lst" is a bad name for a parameter that is a list. "list" would
be better, if no more suitable name is appropriate.

http://www.cs.northwestern.edu/academics/courses/325/readings/graham/graham-notes.html
has some examples of other things from ANSI Common Lisp to avoid.

> I've been looking over Graham's book, and he stresses the importance of
> indentation.  Traditionally, I've shunned emacs, since it seems to get
> *all* default behavior wrong, in every situation, ...

Not true.

> Alas, it gets the indentation wrong, or at least it's different
> than what Graham suggests (for example, in "if" expressions, it indents
> the "then" differently than the "else").  Is there a configuration
> parameter that I can use to fix it?

(setq lisp-indent-function 'common-lisp-indent-function) is a quick
way. You can make it more specific to CL buffers, but if you don't
edit a lot of elisp, you don't have to worry much about it. Google
should give you some examples with which to work.

> I also noticed that gcl will accept a dotted list as a parameter to
> checksum, but clisp will not.  What's the correct behavior?

I don't see where in the hyperspec that a proper list is required, but
I didn't look especially hard.

Zach
From: Neil Cerutti
Subject: Re: Checksum (noob)
Date: 
Message-ID: <slrnepo0on.1lk.horpner@FIAD06.norwich.edu>
On 2006-12-28, Damien Kick <·····@earthlink.net> wrote:
> Zach Beane wrote:
>> ·········@gmail.com" <········@gmail.com> writes:
>>> I've been looking over Graham's book, and he stresses the
>>> importance of indentation.  Traditionally, I've shunned
>>> emacs, since it seems to get *all* default behavior wrong, in
>>> every situation, ...
>> 
>> Not true.
>
> Maybe it's just because I already drank the Koolaid, having
> been an Emacs user for a few years now, but I don't quite
> understand this attitude towards Emacs from beginners.  I
> started using vi in college and I absolutely fail to see how
> any of that program could be considered to be intuitive.
> Seriously, take any random person off the street and sit them
> down in front of a window with vi having been started.  Who in
> their right mind is going to think, "obviously, I must hit 'i'
> before I begin typing."  Emacs at least gets this part right.
> Emacs haters also seem to not be able to stand all of the key
> chords but must of the common functions have menu driven
> controls, too.  

Neither editor is at all friendly to newbies.

For example, in Emacs the excellent help system feels clunky and
awful until you've internalized a few window-manipulation
commands (M-C-v, C-x 1, C-x 0, C-x o).

After over a decade with Vim I still sometimes get stuck in ex
mode. ;)

> I don't see how Emacs is any worse off than many of the other
> modern menu driven text editors in this respect.  However, I do
> think that the customization menus are confusing.  I always
> have a hard time finding which submenu has the option in which
> I'm interested.  I personally never use the mouse when using
> Emacs.  I just have never seen why using modifiers keys is seen
> as such a problem for some people.

The toughest thing for me in Emacs is learning the new lingo. But
that would be a problem with any powerful, configurable editor.
Now that I've got a couple dozen commands under my belt and some
simple customization done, I feel very productive with my
LispBox.

-- 
Neil Cerutti
From: Bill Atkins
Subject: Re: Checksum (noob)
Date: 
Message-ID: <m21wmlueta.fsf@bertrand.local>
·········@gmail.com" <········@gmail.com> writes:

> After a 10 year hiatus, I've begun experimenting with Lisp again.
> Among other things, I've written a typical 8-bit modulo arithmetic
> checksum routine, which would look like this in C++:
>
> std::accumulate(lst.begin(), lst.end(),
>                 0, std::minus<unsigned char>());
>
> Lisp version:
>
> (defun checksum (lst)
>   (logand (- 0 (apply '+ lst)) #xff))
>
> I like it.  However, I'm wondering if it's appropriate to be paranoid
> about a user passing invalid parameters to such a function (lists of
> lists, integers, etc.) and causing havoc at runtime.

There shouldn't be any havoc - if the caller passes anything but a
list of numbers, a condition will be signaled.  If you are using SLIME
(or any other Lisp environment), you'll get a special interface to
deal with conditions when they arise.

Generally, the approach taken in dynamically-typed languages is to
make type-checking implicit in your code and your documentation,
i.e. if someone breaks CHECKSUM's contract and passes an LST
containing invalid data, the + call becomes invalid and an error will
be signalled at runtime.  If the input to checksum is coming from an
external source (like a network connection or typed user input), it
might be worthwhile to check the types yourself so you can present a
more meaningful error message.  Otherwise, any type-checking you might
do in CHECKSUM itself would be superfluous, since + checks types on
its own.

Does the following code do what you want:

(defun checksum (list)
  (mod (reduce #'+ list) 256))
   
?

(The REDUCE and APPLY calls are nearly equivalent, except that the
list passed to APPLY can't be longer than CALL-ARGUMENTS-LIMIT; REDUCE
doesn't suffer from this limitation.)

In general, code that deals with low-level bit representations is not
in the Lisp spirit, at least IMO.

> I've been looking over Graham's book, and he stresses the importance of
> indentation.  Traditionally, I've shunned emacs, since it seems to get
> *all* default behavior wrong, in every situation, and I don't have the
> willpower to maintain a configuration.  But I thought I would give it
> another try, since it seems to have been designed specifically for
> Lisp.  Alas, it gets the indentation wrong, or at least it's different
> than what Graham suggests (for example, in "if" expressions, it indents
> the "then" differently than the "else").  Is there a configuration
> parameter that I can use to fix it?
>   (setq indent-lisp-correctly t)  ; wouldn't that be nice

(setq lisp-indent-function 'common-lisp-indent-function)

HTH,
Bill
From: Peter Scott
Subject: Re: Checksum (noob)
Date: 
Message-ID: <1167265994.917699.36080@f1g2000cwa.googlegroups.com>
Bill Atkins wrote:
> Does the following code do what you want:
>
> (defun checksum (list)
>   (mod (reduce #'+ list) 256))

If you're going to use this code to find checksums of larger files by
adding them up byte by byte modulo 256, that could be disastrous. You
would add up all the bytes and *then* pass the gigantic bignum result
to MOD.

Here's a function which avoids the problem in your (clearer) code:

(defun checksum (list)
  (reduce #'(lambda (a b) (mod (+ a b) 256)) list))

And if you want to make it orders of magnitude faster by limiting it to
byte-sized integers:

(defun checksum (list)  ; Just for fun
  (declare (optimize (speed 3) (safety 0) (debug 1)))
  (let ((accum 0))
    (declare (type (integer 0 255) accum))
    (loop for x of-type (integer 0 255) in list
	 do (setf accum (mod (+ accum x) 256)))
    accum))

This loop-and-accumulator approach doesn't look nearly as pretty, but
it's probably closer to what you'd use in actual applications for doing
large checksums on files. If you want to find a checksum of a 300 MB
file, you don't want to read the whole thing into memory in the form of
a linked list and pass it to a checksum function; you want to read it
in a few kilobytes at a time in buffers and update your checksum for
every new chunk of the file that you read in. Again, just for fun,
here's the fastest code I could make to compute the checksum of a file:

(defun checksum-file (pathname)
  (declare (optimize (speed 3) (safety 0) (debug 1)))
  (with-open-file (file pathname :element-type '(unsigned-byte 8))
    (let ((buffer (make-array '(2048) :element-type '(unsigned-byte
8)))
	  (accum 0))
      (declare (type (simple-array (unsigned-byte 8) (2048)) buffer)
	       (type (unsigned-byte 8) accum))
      (loop for bytes-read = (read-sequence buffer file)
	 while (< 0 bytes-read)
	 do (loop for i below bytes-read
	       do (setf accum (mod (+ accum (aref buffer i)) 256))))
      accum)))

This runs several orders of magnitude faster than the naive code would.

-Peter