Subject: Re: MD5 in LISP and abstraction inversions
From: Erik Naggum <erik@naggum.net>
Date: Fri, 02 Nov 2001 00:43:19 GMT
Newsgroups: comp.lang.lisp
Message-ID: <3213650592348094@naggum.net>

* Francois-Rene Rideau <fare+NOSPAM@tunes.org>
| Ok. Do you (or someone else in this newsgroup) have some MD5 code
| that you (they) are willing to publish without any licensing issues?

  No.  Part of the reason I do not publish my code anymore is that there
  are too many incompetents and assholes out there that I specifically do
  _not_ want to get access to my work if they do not compensate me for it.
  After all, you are whining and complaining and posting a bunch of crap
  because you are unwilling to do the work on your own, so giving _you_
  this code without any licensing terms seems like a really bad idea.

| You seem to be looking for things to argue over.

  Wrong.  For some people who think it is their birthright to be imprecise
  and sloppy and disrespectful, being taken seriously and expected to be
  precise is sometimes extremely provocative.  You seem to be one of those.

| [Skipped ad-hominem attacks]

  Well, gee, your own are apparently OK, while you have a problem with
  mine.  That kind of double standard _really_ annoys me.  If you do not
  want what you call ad hominem attacks (but you are still imprecise --
  look it up), simply avoid them yourself -- if _you_ cannot do this or do
  now _want_ to do it, shut the fuck up about what anyone else does, OK?

| I suppose I could have also written a FFI to C for CMUCL or CLISP, but I
| didn't feel like doing both of it, and wanted my code to run on both, as
| well as on Genera, ThinLisp, etc.

  So design a common FFI framework!  I have designed and implemented one
  for my own needs, but I find the number of disgusting losers who would
  benefit from it if I published my code to be too high.  Sharing should be
  rewarding, not felt as a loss.  I choose to withhold what I do from the
  public because of the number of assholes who would never respect my
  rights as an owner, but fortunately, they are honest enough to scream
  bloody murder if someone wants them to sign a license agreement.
  Withholding from the general public is in fact the _only_ option an
  author has in these days of "open source" and "free software".  I find
  that many of the problems people have are in fact solved in an hour or
  two, but I have great fun solving problems for their own sake (and anyone
  who enjoys mathematics knows what I mean), but the fun that used to be
  found in seeing somebody else use my code vanished years ago with the
  agressiveness of the demands of the consumers of open source and free
  software -- there used to be a sense of gratitude and respect towards
  those who solved your problems for you and gave you code, but this is
  replaced by lazy fucks who demand that others solve their problems for
  them and get pissed off if somebody else refuse to give them their work
  for free.  This gives me solid reason to believe that certain problems
  are problems only to incompetents and it also gives me a good way to
  determine if certain "problems" are posted by trolls who do not really
  want a solution to them.  There are lots of people on the Net who only
  want to get sympathy for their plight, not actually solve their problems.
  That kind of whining wimps tick me off, and if I can help one of them
  lose their job or fail an exam by not answering their stupid requests for
  somebody else's work, that is good!

| In other words, I purported to support the (maybe illusive) idea that
| there is a usable portable Common LISP language.

  There is, and you have not been betrayed because you need to do some hard
  work to get something you want.  In fact, that sense of betrayal you feel
  is that same irrational attitude problem that comes from believing in a
  "perfection" that somebody else owes to you.

| >   You really need to clue in that MD5 does not operate on characters.

| Who said it did?

  You did, when you complained about the character concept.

| Still, it operates on streams that I also have to interpret as
| characters, in a different context (notably so as to use, e.g. WRITE,
| FORMAT, and all those text processing libraries).

  Well, considering that I have actually done precisely the same thing and
  did not have _any_ or your problems, what does that tell me about you?
  Sometimes, the only problem _is_ the person, but you do not believe me,
  and _stupidly_ think everything is an ad hominem attack.  Clue in, dude,
  an ad hominem attack is an attack on the arguments via the person, it is
  _not_ an attack on the person for something that person does wrong.
  Arguing tha you cannot trust someone because he has a bad credit record
  is ad hominem, sending his unpaid bills to a collection agency is not.
  Using the fact that somebody has been caught with a Swiss Army pocket
  knife in Oslo against them in a debate over efficienty Java is ad
  hominem, arguing that it was not particularly nice to lie to the police
  about the reason he carried it so he would not get into serious trouble
  is not.  But because you are not very precise, you will probably not
  understand this difference.  So I do not argue that you cannot be trusted
  or your arguments suck because you are not very precise or pay much
  attention to detail -- I simply point out that you are imprecise and do
  not pay much attention to detail, and then I expect you to _fix_ that,
  but since you are that stupid antagonistic, imprecise dude who seems to
  think that "you seem to be looking for things to argue over" is a much
  better approach to the criticism, you will not quite grasp what you are
  being told in any case.  That kind of arrogance is something that those
  who suffer from it will exhibit in many ways, and the belief that their
  code is perfect (or any flaws somebody else's fault) goes with it.

| CL forces me to do double buffering (actually, treble, or more), which
| sucks because of coding nightmares even more than for the slowness.

  No, the language does _not_ force you to do that, damnit.  Your very own
  incompetence and extremely annoying _arrogance_ forces you to do that.
  Just be smarter.  Think more, whine less, work better.

| >   That some languages have no idea what a character is, but treat it
| >   like a small integer is really not something you can blame either MD5
| >   or Common Lisp for.
| I actually don't blame languages that treat characters as small integers.

  Huh?  Nobody said you did, either.  Do you argue against straw men, now?

| I do blame CL for providing an implementation-dependent notion of
| character that is both too low-level to portably do any interesting thing
| with it, and too high-level to allow for portable interaction with
| standard low-level protocols.

  I think you need to explain your understanding of the character type,
  because this sounds like the rantings of an incredibly incompetent person
  who has not paid a lot of attention to detail in his life.  The _fact_ is
  that the implementation-dependent aspects of the character are precisely
  those that manifest itself in the coding and representation which you
  want to get access to directly.  How you can fail to understand this is
  truly amazing.  I wonder when you were satisfied with your bogus belief
  in "character flaw" as a good explanation for your problems.  (If you
  pardon the pun -- I simply could not resist. :)
  
| That's why I was talking about double, treble, whatever, buffering, which
| is overhead in programming time as well as in running time and space, and
| qualifying that as "clumsy, inefficient, not portable, and
| underspecified".

  That is how you would implement them.  Your implementation is only partly
  a consequence of the language, and only a small part, because you have
  contributed a lot more than the language has.  I get really annoyed by
  people who think that their algorithm and implementation is perfect and
  if it does not work the way they want, it is somebody else's fault.  You
  are obviously that kind of person, and there is a serious flaw with your
  thinking that you need to fix before you are willing and able to listen
  to counter-arguments.  As long as you protect your notion of perfect
  implementation, you will never get anywhere.

| Sure I can. (Well, someone else seems to be doing that for CMUCL).
| However, so it would be no more portable CL, and so that it remains
| "ported CL", I'd have to do it on each of the implementations I use
| (although most of it could hopefully be done in portable CL).

  Yes, it seems that you are one of those perennially dissatisfied people
  who do not understand that the _only_ way you can arrive at portable
  _interfaces_ to some common functionality is to write non-portable,
  implementation-dependent code that implements them efficiently in a
  particular Common Lisp system.  In fact, I am frankly _stunned_ by the
  lack of insight among people who want _both_ portable interfaces _and_
  portable implementations of such interfaces.  That is simply not how
  things work.  Common Lisp itself is a prime example: It is a supremely
  portable language, yet requires massively implementation-dependent code
  to implement correctly.  Actually, it seems that it takes a particular
  willingness to think things through that many people lack to figure out
  that what comes out elegant and beautiful at the other end of a long
  production line has been through a very _dirty_ process.  Like, do you
  think the factory that makes office furniture is as clean as the offices
  their furniture is sold to, or that writing an elegant poem about love
  and happiness did not require the usual incredible amount of pain that
  getting a poem "right" requires?  No, creating something beautiful takes
  a lot of ugly, painful work.  If you are not up to that, you really have
  no business _demanding_ that other people do it for you, or complaining
  that they have or do not.  It is that demanding attitude that makes me
  _not_ want to give people like you an easy way out of your problems.

| >   but for MD5, just break the 32-bit integers in half and operate on 16-bit
| >   values, instead.
| Yes, I have thought about this. However, I began with 32-bit because it
| was more natural, and hoped CMUCL could do well with it. It could do better.
| I was happy enough with the implementation so as to decide to publish it
| before to optimize it, if I ever do it (but then instead of writing ugly
| implementation-specific LISP - some of my friends call that "bugware" -
| I'd rather write efficient assembly and FFI code, and/or develop
| a special-purpose subLISP compiler that would do that for me).

  Well, if you have friends like that, no wonder you have problems choosing
  good engineering practices.  Using implementation-specific things to
  implement a common/standard interface to some functionality is not wrong,
  it is in fact right, and a very good way to move forward and _get_ that
  functionality, but if people do not want the functionality because they
  cannot get it their perfect way, which it seems that the several Lisp
  communities suffer from to a frighteningly high degree, they will not
  _get_ that functionality, either.

| It is small by for a code file (700 lines, including lots of comments),
| but I consider it large and noisy by USENET post standards.

  700 lines!?  Geez.  Using implementation-specific features in Allegro CL,
  the core algorithm is 100 lines.  Setting up and preparing for this short
  and fast algorithm takes another 150 lines.

| My code is not perfect, and part of the reason it isn't is that the
| language has deficiencies.

  You ridiculous idiot.  You probably even _believe_ this bullshit.

| But I don't want to do it for CMUCL, SBCL, CLISP, Genera, ACL, ThinLisp,
| and every other implementation.

  Have you ever wondered how all these implementations sprung into being
  from nowhere when people like you do not want to implement things they
  say they want?  Ever wondered how all of this "free software" depends on
  people's willingness to implement things that sometimes are _boring_ and
  which some lazy fuck like yourself does not want to do?  

| In other words, if I pick one implementation and stick to it, I'd be fine
| - but then, so would I picking a Scheme implementation, OCAML, or a system

  It is not a question of picking one implementation and sticking with it,
  but of actually using an implementation to get what you want.  If you are
  so inept that you cannot design and implement something with an interface
  that does not expose the implementation-dependent features, that is not
  the fault of any language.  Whether to "stick with" an implementation is
  an orthogonal issue to whether you use implementation-specific features.
  If you want to make something really useful that needs to be portable or
  the foundation for something portable, you will probably need to use some
  implementation-specific features.  If not, you could have done it fully
  portably, right?

  Then there is the issue of how _often_ you need to use such featuers to
  implement common/standard things and how hard it is to do so.  You seem
  to believe that as soon as it is necessary to do something like this, you
  have found a flaw in the language.  This is fantastically misguided.

| But each system does its own non-weird magic, in an incompatible way.
| That's called non-portability.

  If you use one implementation's internal stuff and expect it to work
  elsewhere, yes, but it is the assumption that you can do that that is
  flawed.  If you use another implementation's internal stuff to provide
  the same interface to the same functionality, you have done a good thing.
  This is how smart programmers design both compatibility layers and pave
  the ground for new standards.

| I'm just criticizing CL, and there unhappily seems to be no one to ask
| about fixing that.  (Well, actually, raising the problem in c.l.l will
| hopefully attract the attention of implementers on the problem and its
| known solutions, so they might provide efficient APIs to multivalent
| strings/streams and modular integer operations).

  So if I understand you right, you think it is perfectly OK for a vendor
  to use internal, implementation-specific features to implement a common
  or standard specification (or, in case you are not quite up that level of
  quality, just fix things your way), that is perfectly OK, but if you do
  it yourself, it is _not_ OK?  Just _why_ is it that you cannot do this
  yourself?  What makes it so important to you that somebody else do the
  dirty work that you do not want to do yourself?

| >   You have to get at the bytes where they are actually found, just
| >   after they have been read, and just before they are written.
| >   Anything else is pretty damn stupid.

| Sure. Who said otherwise?

  You have strongly implied "otherwise", you insuffable numbnut.

| This just means more buffering to handle (costs development, performance,
| space, semantic gap, etc.)

  ... and this is where you say it!  This "more buffering" crap that _you_
  think is necessary is in fact _not_ necessary for your particular needs.
  As you well know, the MD5 algorithm uses 64-byte blocks and it does not
  care one hoot where they are.  If you use the _same_ buffer that you just
  read data into from the external source, you can actually get at the raw
  bytes _before_ they are interpreted as characters.  This is not hard to
  do.  This is not even difficult.  This is _not_ rocket science.  All this
  requires is that you are willing to study your implementation or talk to
  the vendor and get at the underlying buffer.  You are really annoying in
  the way you keep thinking that no better solution than your own can exist.

| Actually, it calls for doing everything with bytes, and nothing with
| characters (unless wrapped in a macro for immediate conversion), in any
| portable program sensitive to such problems -- except that this precludes
| the use of many text-processing libraries, which is the abstraction
| inversion.

  Wrong, you insufferable numbnut.

| Your claim all throughout was that text-processing was not about bytes.
| Well, it isn't about characters either, you know.

  Sigh.  Quit your stupid game-playing, will you?

  I think you are no more than another stupid troll who will never be
  satisfied no matter what anyone provides you with, and who will certainly
  never do any decent work on your own to get what you claim to want.

///
-- 
  Norway is now run by a priest from the fundamentalist Christian People's
  Party, the fifth largest party representing one eighth of the electorate.
-- 
  Carrying a Swiss Army pocket knife in Oslo, Norway, is a criminal offense.