brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (03/21/91)
In article <1991Mar20.192606.29608@linus.mitre.org> john@mingus.mitre.org (John D. Burger) writes: > brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: > ... even if compile times were instant I'd spend forever just > waiting for most programs to run. > Based on my experience, this is nonsense. I develop AI applications > in Common Lisp that do complex things like understand natural language > utterances and reason about how best to design graphical > representations of information, and these programs run fairly quickly, > i.e. fast enough to act as an interface to another program. Wow. So you have a naturally complex but short-running program. I admit such programs exist. They are not the mainstream, at least not in systems programming and numerical programming. > A machine is much more than its ``primitive datatypes.'' But Lisp > doesn't even provide full access to pointers. > What does this mean? "Pointers" are an artifact of languages like C, Be serious. Pointers (a.k.a. addresses) have been in every machine language at least since 1960. C provides a concept of ``memory'' (more precisely, the set of all pointer values, which equals the set of all char pointer values modulo typechecking) and pointers into memory. You can do things with memory in C that you CANNOT even express in Lisp. To return to the original point, C is more powerful than Lisp in this area. > In fact, I've been focusing on the prototyping and development stage > of a program, because that's when it's most important to get good > compile times *and* run times. > As someone who has worked in a C shop in another life, building > business applications, I can say that there's no comparison between the > two with respect to development time or maintainability of code. And I can say that the continued refusal of dynamic-typing advocates to actually *make* such a comparison objectively is one mark of a true religion. ---Dan
quale@khan.cs.wisc.edu (Douglas E. Quale) (03/21/91)
In article <4637:Mar2102:11:2991@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >typechecking) and pointers into memory. You can do things with memory in >C that you CANNOT even express in Lisp. To return to the original point, Examples, please. -- Doug Quale quale@khan.cs.wisc.edu
cs450a03@uc780.umd.edu (03/22/91)
Dan Bernstein writes: >And I can say that the continued refusal of dynamic-typing advocates to >actually *make* such a comparison objectively is one mark of a true >religion. Come on, Dan, what's an "objective" comparison? The only sort of case I know of where a program is written to the same spec in a number of different languages is class projects. And in that case there is very little in the way of a maintenance problem. Nor is speed much of a consideration. Just for the record, for the class that I have this account, my term project took about an hour to write, and the source listing and a sample run fit on a single page. That's with comments. (My prof, never having seen the language before, was able to understand pretty well what each step was doing, simply from the comments and the form of the statements). Other people, struggling with constructing parsers and symbol tables and so on took longer. But is this objective? Raul Rockwell
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (03/25/91)
In article <1991Mar21.123512.22876@daffy.cs.wisc.edu> quale@khan.cs.wisc.edu (Douglas E. Quale) writes: > In article <4637:Mar2102:11:2991@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: > >typechecking) and pointers into memory. You can do things with memory in > >C that you CANNOT even express in Lisp. To return to the original point, > Examples, please. p + i, as I already pointed out. You can find higher-level applications (e.g., byte-copying into a character buffer, which can then be written portably to disk and read back later) for yourself. Other points: GNU Emacs *is* written in C, with only a small amount of ``helper'' code to implement dynamic typing. Yes, this *does* provide all the perceived advantages of a dynamically typed language like Lisp, and in this case makes most of the resulting program look like Lisp. The total cost is that bit of helper code. Doug, you have made nothing of yourself in this newsgroup but a nuisance for at least the last few months. I post a working compose() in C, for example, and you have to insist in five separate articles that it doesn't work when nested. You challenge references rather than spending a few minutes to educate yourself; you repeatedly bring up dead issues and ignore arguments and logic that you don't like; most importantly, you apparently don't *want* to contribute. Why do you post at all? ---Dan
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (03/26/91)
In article <1991Mar21.155528.6068@linus.mitre.org> john@mingus.mitre.org (John D. Burger) writes: > brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: > [in response to my description of some complex and fast Lisp programs] > Wow. So you have a naturally complex but short-running program. I > admit such programs exist. They are not the mainstream, at least not > in systems programming and numerical programming. > What does "short-running" mean? What I meant was that the program doesn't run for a significant amount of time. (This obviously implies that the run time of the program doesn't matter, so inefficient code is reasonable.) ``Short'' and ``significant'' are subjective, of course, and depend on the situation at hand. I claim that run time is, overall, a significant percentage of turnaround time during the development and maintenance of most programs. Since programs in Lisp are often several times slower than the same programs in C, Lisp significantly slows down program development, all else being equal. So it's not worth programming in Lisp unless all else is not equal---i.e., unless Lisp significantly reduces the number of test runs, or the pain of maintenance. See below. > Be serious. Pointers (a.k.a. addresses) have been in every machine > language at least since 1960. > So have conditional jumps. What's the point? If you want to program > in machine language, do it. But almost everything that people do with jumps can be expressed with if/loop/break---and the exceptions or perceived exceptions have been enough to keep an unstructured jump in every popular language. In contrast, people want to do things with memory that they can't do in Lisp. C *is* more powerful than Lisp in this respect. > I don't want to have to know about the underlying architecture, and > you seem to want to program at that level, which explains why you like > Machine Independent Machine Language (aka C). I don't want to have to know about the underlying architecture either. I'm glad that C provides a powerful yet portable model of almost all existing hardware architectures. It's a shame that Lisp doesn't. [ returning to... ] > As someone who has worked in a C shop in another life, building > business applications, I can say that there's no comparison between > the two [C and Lisp] with respect to development time or > maintainability of code. That's not objective. Where are the examples? Where are the brilliant rewrites of statically typed code into dynamically typed code of a fraction of the length? Every example people give seems to depend almost entirely on the strength of available libraries. I'm all in favor of good libraries, but what does that have to do with dynamic typing? To return to my favorite example along these lines: Perhaps 1% of the GNU Emacs code is responsible for implementing dynamic typing in C; if it were all written in Lisp instead, it'd be about 99% of the original length. Where are the savings? ---Dan De syntactic gustibus non disputandum est.
bbc@rice.edu (Benjamin Chase) (03/26/91)
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >Other points: GNU Emacs *is* written in C, with only a small amount of >``helper'' code to implement dynamic typing. "GNU Emacs" is roughly 1/2 C and 1/2 elisp. Or did you mean just that file of machine code that gets run when you start gnu emacs? No, even that small part of GNU Emacs wasn't derived solely from C. Get some facts, Dan. -- Ben Chase <bbc@rice.edu>, Rice University, Houston, Texas
oz@yunexus.yorku.ca (Ozan Yigit) (03/26/91)
In article <16060:Mar2515:41:5691@kramden.acf.nyu.edu> Dan Bernstein writes: >Doug, you have made nothing of yourself in this newsgroup but a nuisance >for at least the last few months. I would dare say that this net has seen only one serious nuisance in the last little while, and that one has been posting from brnstnd@kramden.acf.nyu.edu. >You challenge references rather than spending a few minutes to >educate yourself; Look who is talking.
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (03/26/91)
In article <BBC.91Mar25115827@libya.rice.edu> Benjamin Chase <bbc@rice.edu> writes: > Or did you mean just that file of machine code that gets run when you > start gnu emacs? No, even that small part of GNU Emacs wasn't derived > solely from C. Yes, that is the GNU Emacs program, and I never said anything about what it was ``derived from.'' It is written in C, and any C programmer who wants to make use of dynamic typing can get away with a similarly tiny amount of helper code. No amount of crap about ``sole derivations'' or ``it's written in Lisp, really!'' will change this fact. What are you trying to do? Make a religious point, or get work done? I'm sure RMS didn't care about how impossible polymorphic lists are in C when he was working on Emacs. > Get some facts, Dan. Sheesh. At least I've had the sheer joy of compiling Emacs on a couple of unsupported systems, one of which can't handle undumping. I'm not an Emacs expert, but you can assume that I know what language a program is written in when I've worked with the code of that program. ---Dan
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (03/26/91)
In article <22144@yunexus.YorkU.CA> oz@yunexus.yorku.ca (Ozan Yigit) writes: > In article <16060:Mar2515:41:5691@kramden.acf.nyu.edu> Dan Bernstein writes: > >Doug, you have made nothing of yourself in this newsgroup but a nuisance > >for at least the last few months. > I would dare say that this net has seen only one serious nuisance in the > last little while, and that one has been posting from > brnstnd@kramden.acf.nyu.edu. I understand: It's a ``nuisance'' when someone refuses to accept the dogma of current computer science. Sorry, folks, but sorting is linear in the number of bytes, and you can implement composable functions in C, and you can solve the halting problem in practice, and C has more powerful pointer handling than Lisp. If you think it's a nuisance when someone tells the truth as he sees it, then yes, folks, I guess I'm Ozan's sort of nuisance. Unlike Ozan, I don't see rational disagreement as a problem. The problem in this group is the failure of people to try to see past differences in terminology and stick to technical issues. Articles like Ozan's---like this one, or almost any from Jim Giles---should be lost in the flood of useful discussions about what can be done with various language features and what should appear in future languages. I still wish it were possible to start a conversation here about pointers and arrays without having it degenerate into a series of religious arguments. It's not. Except for the ``contributions'' from Ozan and Doug, I've found the recent threads here quite useful. I only hope that this can continue into future discussions. ---Dan
cs450a03@uc780.umd.edu (03/26/91)
Dan Bernstein writes: >p + i, as I already pointed out. You can find higher-level applications >(e.g., byte-copying into a character buffer, which can then be written >portably to disk and read back later) for yourself. Any reason you can't call the buffer an array? *(p + i) is array addressing. >Other points: GNU Emacs *is* written in C, with only a small amount of >``helper'' code to implement dynamic typing. I think the small amount of code it takes to implement dynamic typing should count as a win for dynamic typing. As should the large amount of code which was written using it. You might argue that LISP is used because it is easy to change, not because of its runtime type-checking, but the two features work together. Raul Rockwell
cs450a03@uc780.umd.edu (03/26/91)
Dan Bernstein writes: >But almost everything that people do with jumps can be expressed with >if/loop/break---and the exceptions or perceived exceptions have been >enough to keep an unstructured jump in every popular language. Or if you want to get real fancy, you can put a case statement in a while loop. Wonderful way to spaghetti code. [Just an aside, not why I'm posting.] >Where are the examples? Where are the brilliant rewrites of >statically typed code into dynamically typed code of a fraction of >the length? Well... now that I've admitted that I've heard of APL... I remember a presentation by this economics professor, where he was implementing some nasty partial differential model of some theory. He had had this team of FORTRAN writers working on it for something like 6 months, and after generating something on the order of 20-50,000 lines of code they gave up. First pass at writing it in APL was something like 20 pages of code. In the presentation he had it down to three, and claimed that he could see further improvements that would take it down to even less. (His estimate was that it would get down to about a page). He also said that the FORTRAN team would be able to implement his model, now that they had something to base their work on. I don't remember much more than that, this was around 87-88, and at the time I was more interested in trying to figure out what the variables in the model stood for than I was in the code. By the way, please don't try and claim that APL has a better math library than FORTRAN. You'll upset a whole bunch of dusty deckers ;-) Raul Rockwell
fnwlr1@acad3.alaska.edu (RUTHERFORD WALTER L) (03/26/91)
In article <21189:Mar2521:55:0691@kramden.acf.nyu.edu>, brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes... > >I understand: It's a ``nuisance'' when someone refuses to accept the >dogma of current computer science. [examples of the truth a'la Dan Bernstein deleted to save space] >someone tells the truth as he sees it, then yes, folks, I guess I'm >Ozan's sort of nuisance. > Only when the truth as you see it includes statements like: >Doug, you have made nothing of yourself in this newsgroup but a nuisance >for at least the last few months. >and what should appear in future languages. I still wish it were >possible to start a conversation here about pointers and arrays without >having it degenerate into a series of religious arguments. It's not. ^^^^^^^^^^^^^^^^^^^ Would you please come up with a better phrase for the types of "conversations" which erupt here? You'll give religion a bad name. :-) --------------------------------------------------------------------- Walter Rutherford P.O. Box 83273 \ / Computers are NOT intelligent; Fairbanks, Alaska 99708 - X - / \ they just think they are! fnwlr1@acad3.alaska.edu ---------------------------------------------------------------------
gudeman@cs.arizona.edu (David Gudeman) (03/26/91)
In article <16521:Mar2516:10:0791@kramden.acf.nyu.edu> Dan Bernstein writes:
]Where are the examples? Where are the brilliant
]rewrites of statically typed code into dynamically typed code of a
]fraction of the length? Every example people give seems to depend almost
]entirely on the strength of available libraries...
]but what does that have to do with dynamic typing?
Dynamic typing encourages re-usability of code, thereby leading to
much more powerful libraries with fewer primitives.
]To return to my favorite example along these lines: Perhaps 1% of the
]GNU Emacs code is responsible for implementing dynamic typing in C; if
]it were all written in Lisp instead, it'd be about 99% of the original
]length. Where are the savings?
That's bogus. You haven't taken into account all the redundant code
that does slightly different things, or all the declarations.
--
David Gudeman
gudeman@cs.arizona.edu
noao!arizona!gudeman
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (03/26/91)
In article <1991Mar25.210406.9384@linus.mitre.org> john@clouseau.mitre.org (John D. Burger) writes: [ on ``short-running'' ] > Huh? I don't understand this at all; your implication is not obvious > to me. Anyway, as I said, the Lisp programs I'm referring to run for > hours/days at a time. Is that long enough to be significant? You said it was ``fast enough,'' so obviously its run time is not particularly significant. I claim that for most programs the opposite is true, and dynamic typing can greatly increase the turnaround time during development. You can measure the accuracy of this claim by dividing the CPU time of test runs by the total programming time, for various programs. > So it's not worth programming in Lisp unless all else is not > equal---i.e., unless Lisp significantly reduces the number of test > runs, or the pain of maintenance. See below. > All else isn't equal, as is usually the case when people say that. > Lisp gives you heterogenous collections, incremental compilation, a > REAL source level debugger, and lots more. That's why development in > Lisp IS significantly faster. A ``REAL source level debugger'' and incremental compilation are functions of the environment. Heterogeneous collections don't seem to be used in real applications---or do you have a counterexample? > ... e.g., byte-copying into a character buffer, which can then be > written portably to disk and read back later ... > This can be done in Lisp. No. You can use a list to simulate the buffer, but you cannot do the job as stated. You can construct other examples where Lisp's lack of pointer arithmetic or byte-oriented memory shows through. > I'm glad that C provides a powerful yet portable model of almost all > existing hardware architectures. It's a shame that Lisp doesn't. > It's not clear to me that it doesn't, but anyway, I don't want to > model hardware, I want to model the problems I need to solve. Huh? Are you not trying to write programs so that machines can run them? > I find your example, and others like it, much more compelling than any > rewrite examples. Why do you think it was deemed necessary to > implement dynamic typing in C for GNU Emacs? Why do you think X > Windows effectively implements dynamic typing for interface entities, > not to mention a run time interpreter? [ etc. ] ``Why do you think people write libraries and use them?'' Because it's easier to use a library than to rewrite its code. Can we apply your logic to insist that all library routines should be part of every language? The point is that someone who wants to use dynamic typing in C can easily do so. I believe we agree here. So what is gained by including dynamic typing in the language (hence compiler), rather than in a standard library? The obvious disadvantage is that most existing dynamically typed languages *force* you to use dynamic typing, and don't let you declare types even when you know what they will be. ---Dan
new@ee.udel.edu (Darren New) (03/26/91)
In article <27234:Mar2603:13:2991@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >[...] Heterogeneous collections don't seem to be >used in real applications---or do you have a counterexample? Please be sure to see the article I've already posted in which I give three examples of where I have used hetrogeneous lists. (Since this is your third posting asking for that list, I just wanted to make sure you saw it :-) -- Darren -- --- Darren New --- Grad Student --- CIS --- Univ. of Delaware --- ----- Network Protocols, Graphics, Programming Languages, Formal Description Techniques (esp. Estelle), Coffee, Amigas ----- +=+=+ My time is very valuable, but unfortunately only to me +=+=+
oz@yunexus.yorku.ca (Ozan Yigit) (03/26/91)
In article <see ref if you care> Dan Bernstein writes(?): >I understand: It's a ``nuisance'' when someone refuses to accept the >dogma of current computer science. It is a nuisance when ignorance and refusal to learn is glorified as the refusal of some would-be dogma. >Unlike Ozan, I don't see rational disagreement as a problem. You never have rational disagreements. That is the problem. oz --- We only know ... what we know, and | Internet: oz@nexus.yorku.ca that is very little. -- Dan Rather | UUCP: utzoo/utai!yunexus!oz
cs450a03@uc780.umd.edu (03/26/91)
Walter Rutherford writes: > [Dan Bernstein writes:] >>having it degenerate into a series of religious arguments. It's not. > ^^^^^^^^^^^^^^^^^^^ >Would you please come up with a better phrase for the types of >"conversations" which erupt here? You'll give religion a bad name. :-) How about "The Spanish Inquisition"? ;-) Er... The Static Inquisition??? Nah... doesn't have the right ring... Raul Rockwell
quale@saavik.cs.wisc.edu (Douglas E. Quale) (03/27/91)
In article <16060:Mar2515:41:5691@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >> >typechecking) and pointers into memory. You can do things with memory in >> >C that you CANNOT even express in Lisp. To return to the original point, >> Examples, please. > >p + i, as I already pointed out. You can find higher-level applications >(e.g., byte-copying into a character buffer, which can then be written >portably to disk and read back later) for yourself. Unfortunately, Dan, p + i is not a program in C or any other language I know, and I can get the equivalent effect with a null lisp program. Byte copying is trivial in Common Lisp. Big Deal. As far as portability goes, CL is much more portable than C because it insulates the program from differences in word size and other low level machine details. A typical "portable" C program running on n different platforms is usually n different programs selected by conditional compilation via #ifdef's. > >Other points: GNU Emacs *is* written in C, with only a small amount of >``helper'' code to implement dynamic typing. Yes, this *does* provide >all the perceived advantages of a dynamically typed language like Lisp, >and in this case makes most of the resulting program look like Lisp. The >total cost is that bit of helper code. > Emacs is written in elisp. Richard Stallman has explained why Emacs *can't* be written in C. The major advantage of lisp over C here is the fact that lisp is much more easily extensible. You are the only person I have ever heard claim that Emacs is written almost entirely in C. I don't wonder why. > >Doug, you have made nothing of yourself in this newsgroup but a nuisance >for at least the last few months. I post a working compose() in C, for >example, and you have to insist in five separate articles that it >doesn't work when nested. You challenge references rather than spending >a few minutes to educate yourself; you repeatedly bring up dead issues >and ignore arguments and logic that you don't like; most importantly, >you apparently don't *want* to contribute. Why do you post at all? > >---Dan Actually Dan, I don't post nearly as often in this group as do you because although I almost invariably disagree with everything you post here, apparently so does just about everyone else. (Oddly enough I have much greater sympathy for your arguments in other news groups. I don't post there because I generally don't have anything to add, and often they are matters outside my area of expertise. Your posting of compression sources and related discussion is excellent, the algorithm descriptions very clear and the discussion on copyrights taught me several important things.) I follow the discussion, remaining silent until you make a particularly outrageous claim, or something important seems to have been overlooked. More of my postings are sparked by the former than the latter because you are quite outrageous and folks here on this newsgroup are quite thorough. * I only challenge references when I believe they don't exist. If you don't * have any personal experience with a particular problem and don't have any * knowledge of the relevant literature, don't claim to. I am amused that you are annoyed that I called you out on Emacs, and completely ignored my request for the literature you claim to have read showing that software development and testing is faster in C than in Common Lisp. I think you can't provide any such references because I don't believe you have read any of the literature. (I also doubt that there's very much of it to support your fairly unique point of view anyway.) If you have such references, post them. I don't need an exact reference. If you give me the name of the journal and an approximate date and title I can look it up. As for compose, your response was repeatedly, "I posted it last month, I posted it last year, My mother posted it last year...." ad nauseum. If you really had the stuff, prove it. Continually saying something is trivial is not evidence. Dan, you are a master of evasion. You claim to have personal experience with Common Lisp which I doubt. You also claim to have read literature supporting a viewpoint that I haven't seen in the literature and I doubt you there as well. You bristle when asked for any evidence that what you're saying isn't just hot air. If you had the evidence you wouldn't have to bristle. Time to stand and deliver. (I expect another evasion.) -- Doug Quale quale@saavik.cs.wisc.edu
john@mingus.mitre.org (John D. Burger) (03/27/91)
We seem to have a vocabulary problem regarding program speed.
Regarding some Lisp programs that I described,
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
You said it was ``fast enough,'' so obviously its run time is not
particularly significant. I claim that for most programs the
opposite is true, and dynamic typing can greatly increase the
turnaround time during development. You can measure the accuracy of
this claim by dividing the CPU time of test runs by the total
programming time, for various programs.
I still don't understand this. The run time is significant. Period.
The program is not too slow. If I could have implemented it in a
statically typed language, it would almost certainly run faster. But
I contend that development time in that case would have been nearly
infinite.
As far as your measurements go, I haven't run any such experiments,
and neither has anyone else. But you know that. Again, in my
experience, which is real, development in Lisp and other
dynamically-typed languages is faster than the alternatives. Point
blank, have you ever developed any significant program in Lisp?
Concerning the pluses of Lisp, Dan continues:
A ``REAL source level debugger'' and incremental compilation are
functions of the environment.
Fine. Then the distribution of languages with these features should be
independent of whether those languages have dynamic typing. This
doesn't appear to be the case, however.
Heterogeneous collections don't seem to be used in real applications
---or do you have a counterexample?
Several examples have already been given by others. Frankly, I don't
see how "real applications" (whatever that means) can do without
heterogeneity. How would you represent logical formulae? A predicate
has a name and a collection of arguments: some are variables, some are
constants, some are function terms. A logical connective has a set of
arguments, some of which are other logical connectives, and some of
which are relational expressions.
How about a drawing program, in which you need to represent sets of
polygons, splines, bitmaps, and so on?
Even simpler, how about a calculator, doing arithmetic with integers,
reals, ratios and complex numbers?
The world is full of heterogeneous collections. I think people who
don't see any use in representing them are simply making a virtue of
necessity.
Concerning your "byte-copying" example, you don't appear to actually
know Common Lisp. Additionally, your example seems to hinge on the
fact that C represents characters as 1-byte integers. But then again,
C represents practically everything that way.
The point is that someone who wants to use dynamic typing in C can
easily do so. I believe we agree here.
The point is that lots of people feel they have to implement dynamic
typing in C. Doesn't that tell you something? But anyway, we agree
in the sense that, yes, dynamic typing can be implemented in C, but
ORTHOGONALLY TO THE EXISTING TYPE SYSTEM. I can put a TYPE field in
each of my structures, and then dispatch on its value at runtime, but
I can't declare at compile time that a particular structure will have
a particular TYPE value. The NIH Class Library for C++ is a good
example of this. In order to get runtime typing, they've had to
implement a SECOND type system on top of the first one, and never the
twain shall meet.
So what is gained by including dynamic typing in the language (hence
compiler), rather than in a standard library? The obvious
disadvantage is that most existing dynamically typed languages
*force* you to use dynamic typing, and don't let you declare types
even when you know what they will be.
This just isn't the case. Lisp (and most other dynamically-typed
languages) let you declare types all you want, and most Lisp compilers
pay attention and produce significantly smaller/faster code. The
situation you describe is exactly what's wrong with YOUR way of doing
dynamic typing, i.e. as an add on. The compiler can't know about it,
and therefore can't optimize it.
--
John Burger john@mitre.org
"You ever think about .signature files? I mean, do we really need them?"
- alt.andy.rooney
gudeman@cs.arizona.edu (David Gudeman) (03/27/91)
In article <1991Mar26.165516.13035@daffy.cs.wisc.edu> Douglas E. Quale writes:
]...Byte copying is trivial in Common Lisp...
Still, Dan's point is valid. There _are_ machine-level things you can
do in low-level languages that you can't do in Common Lisp, if for no
other reason than because Common Lisp has to protect its tags for
storage management.
It is also the case that pointer-like operations in Common Lisp are
less efficient than pointer operations in C. For example array
indexing usually involves a type check, a range check, and an extra
offset or two. This can be a problem since a lot of the time
efficiency is the main reason for using pointers.
--
David Gudeman
gudeman@cs.arizona.edu
noao!arizona!gudeman
peter@ficc.ferranti.com (Peter da Silva) (03/27/91)
In article <27234:Mar2603:13:2991@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: > Heterogeneous collections don't seem to be > used in real applications---or do you have a counterexample? Symbol tables. -- Peter da Silva. `-_-' peter@ferranti.com +1 713 274 5180. 'U` "Have you hugged your wolf today?"
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (03/27/91)
In article <1991Mar26.172536.12178@linus.mitre.org> john@mingus.mitre.org (John D. Burger) writes: > brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: > You said it was ``fast enough,'' so obviously its run time is not > particularly significant. I claim that for most programs the > opposite is true, and dynamic typing can greatly increase the > turnaround time during development. You can measure the accuracy of > this claim by dividing the CPU time of test runs by the total > programming time, for various programs. [ ... ] > As far as your measurements go, I haven't run any such experiments, > and neither has anyone else. But you know that. On the contrary. Often I spend a considerable length of time working on just one program. After the fact I have accounting records and various other logs to look at, and it makes perfect sense to total up the time spent running the program and divide it by the real time spent in that session. > Point > blank, have you ever developed any significant program in Lisp? What does ``significant'' mean? More than 10000 lines? No. > A ``REAL source level debugger'' and incremental compilation are > functions of the environment. > Fine. Then the distribution of languages with these features should be > independent of whether those languages have dynamic typing. This > doesn't appear to be the case, however. Huh? The Forth environments I've worked with have incremental compilation, and Saber-C provides a far superior debugging environment to anything I've seen for Lisp. Shall I conclude that static typing helps debugging? > Heterogeneous collections don't seem to be used in real applications > ---or do you have a counterexample? [ ... ] > How would you represent logical formulae? A predicate > has a name and a collection of arguments: some are variables, some are > constants, some are function terms. Sounds like a union type to me. > Concerning your "byte-copying" example, you don't appear to actually > know Common Lisp. Additionally, your example seems to hinge on the > fact that C represents characters as 1-byte integers. Obviously you misunderstood. Yes, the example *does* depend on the fact that C regards all of memory as character-addressible. This is exactly why the example *can't* be handled in Lisp. > The point is that someone who wants to use dynamic typing in C can > easily do so. I believe we agree here. > The point is that lots of people feel they have to implement dynamic > typing in C. Doesn't that tell you something? Lots of people feel they have to implement string functions in C. Doesn't that tell you something? It tells me that the string functions belong in a standard library. It sure doesn't tell me that the compiler should grok strings. > But anyway, we agree > in the sense that, yes, dynamic typing can be implemented in C, but > ORTHOGONALLY TO THE EXISTING TYPE SYSTEM. [ and orthogonality must imply that: ] > The compiler can't know about it, > and therefore can't optimize it. Oh? How come C++ is optimized quite reasonably even though it's commonly implemented as an orthogonal layer over C? How come so many of the dynamic typing optimizations reduce to good inlining and data flow heuristics---things that don't require the compiler to understand what you're doing? If your argument were true, then converting, say, X Windows to a dynamically typed language would speed it up. After all, the dynamic typing would be part of the compiler, and that *must* produce better optimization than an orthogonal system, right? So how come programs in dynamically typed languages are so slow? ---Dan
peter@ficc.ferranti.com (Peter da Silva) (03/28/91)
In article <1991Mar26.172536.12178@linus.mitre.org> john@mingus.mitre.org (John D. Burger) writes: > A ``REAL source level debugger'' and incremental compilation are > functions of the environment. > Fine. Then the distribution of languages with these features should be > independent of whether those languages have dynamic typing. This > doesn't appear to be the case, however. Just for the hell of it, let me point out that the two languages that have the greatest number of units out with these features *are* statically typed: Forth and Basic. -- Peter da Silva. `-_-' peter@ferranti.com +1 713 274 5180. 'U` "Have you hugged your wolf today?"
john@mingus.mitre.org (John D. Burger) (03/28/91)
In article <7988:Mar2700:09:2691@kramden.acf.nyu.edu> >In article <1991Mar26.172536.12178@linus.mitre.org> john@mingus.mitre.org (John D. Burger) writes: >> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >> You said it was ``fast enough,'' so obviously its run time is not >> particularly significant. I claim that for most programs the >> opposite is true, and dynamic typing can greatly increase the >> turnaround time during development. You can measure the accuracy of >> this claim by dividing the CPU time of test runs by the total >> programming time, for various programs. > [ ... ] >> As far as your measurements go, I haven't run any such experiments, >> and neither has anyone else. But you know that. > >On the contrary. Often I spend a considerable length of time working on >just one program. After the fact I have accounting records and various >other logs to look at, and it makes perfect sense to total up the time >spent running the program and divide it by the real time spent in that >session. > >> Point >> blank, have you ever developed any significant program in Lisp? > >What does ``significant'' mean? More than 10000 lines? No. > >> A ``REAL source level debugger'' and incremental compilation are >> functions of the environment. >> Fine. Then the distribution of languages with these features should be >> independent of whether those languages have dynamic typing. This >> doesn't appear to be the case, however. > >Huh? The Forth environments I've worked with have incremental >compilation, and > >> Heterogeneous collections don't seem to be used in real applications >> ---or do you have a counterexample? > [ ... ] >> How would you represent logical formulae? A predicate >> has a name and a collection of arguments: some are variables, some are >> constants, some are function terms. > >Sounds like a union type to me. > >> Concerning your "byte-copying" example, you don't appear to actually >> know Common Lisp. Additionally, your example seems to hinge on the >> fact that C represents characters as 1-byte integers. > >Obviously you misunderstood. Yes, the example *does* depend on the fact >that C regards all of memory as character-addressible. This is exactly >why the example *can't* be handled in Lisp. > >> The point is that someone who wants to use dynamic typing in C can >> easily do so. I believe we agree here. >> The point is that lots of people feel they have to implement dynamic >> typing in C. Doesn't that tell you something? > >Lots of people feel they have to implement string functions in C. >Doesn't that tell you something? It tells me that the string functions >belong in a standard library. It sure doesn't tell me that the compiler >should grok strings. > >> But anyway, we agree >> in the sense that, yes, dynamic typing can be implemented in C, but >> ORTHOGONALLY TO THE EXISTING TYPE SYSTEM. > [ and orthogonality must imply that: ] >> The compiler can't know about it, >> and therefore can't optimize it. > > >---Dan Concerning dynamic typing and nice environments, brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: Saber-C provides a far superior debugging environment to anything I've seen for Lisp. Shall I conclude that static typing helps debugging? Having used all of them, I state that Allegro Composer, Lucid's SPE and the Symbolics Lisp Machine are all FAR superior to Saber-C. But, you've missed the point. Saber-C works as well as it does because they've implemented a version of C with dynamic typing, as well as an interpreter. Other people are dealing with your heterogeneous collection arguments. Concerning your byte-copying example, again, this doesn't have anything to do with statis or dynamic typing. If you want to program in portable machine code, have a ball. How come C++ is optimized quite reasonably even though it's commonly implemented as an orthogonal layer over C? How come so many of the dynamic typing optimizations reduce to good inlining and data flow heuristics---things that don't require the compiler to understand what you're doing? C++ is commonly TRANSLATED to C, not implemented on top of C. How can a compiler do inlining if it doesn't understand what you're doing? -- John Burger john@mitre.org "You ever think about .signature files? I mean, do we really need them?" - alt.andy.rooney
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (03/28/91)
In article <1991Mar26.165516.13035@daffy.cs.wisc.edu> quale@saavik.cs.wisc.edu (Douglas E. Quale) writes: > Byte copying is trivial in Common Lisp. So translate *(int *)&buf = n; into Lisp. Here char *buf; int n. > A typical > "portable" C program running on n different platforms is usually n different > programs selected by conditional compilation via #ifdef's. What a load of crap. My latest compressor, for example, has so far been reported to work on platforms from about fifty vendors. Four of the configuration options enable optimizations that depend on available libraries. One enables extra code to handle a common stdio bug in older systems. Four set defaults for user options. The rest select between machine-independent optimizations. There aren't any #ifdefs other than the configuration options. This is hardly atypical of C programs. > Emacs is written in elisp. What a(nother) load of crap. Next Doug will be claim that sh, csh, and ksh are written not in C, but in shell code! After all, the vast majority of code that people use while executing the shell is, indeed, in an interpreted language, even if under the scenes there's that dirty C code actually running and doing all the work. > The major advantage of lisp over C here is the fact that > lisp is much more easily extensible. Yep, and the major advantage of sh over C here is the fact that sh is much more easily extensible. Do I conclude that sh is written in sh? Yes or no? > you are quite outrageous So who's abusing the English language? :-) > and completely > ignored my request for the literature you claim to have read showing that > software development and testing is faster in C than in Common Lisp. I never made such a claim. I said that compile time and run time were slower in dynamically typed languages; later I amended that to ``compile time or run time.'' More precisely, the literature shows the run time in dynamically typed languages as much slower than in statically typed languages. Research (mostly recent) on optimization of dynamically typed languages shows that the run time can come close (i.e., better than half the speed), but only at a huge expense in compile time. I believe these comments correctly summarize the relevant literature, and if you stop perverting my statements but are still too lazy to do your own homework, I'll give you sample references. > As for compose, your response was repeatedly, [ Doug exhibits his creative writing skills ] > If you really had > the stuff, prove it. Enclosed is another copy of the first article, since you didn't respond to any of my offers via email. This qualifies you as a royal asshole, by the way. Also enclosed for completeness are references to your first two articles implying that my compose() didn't work, and, just in case, one of the intermediate articles that you lied about. The interested reader (I doubt there are any) will note that my compose() nests properly, while Doug has said repeatedly that it doesn't. As I recall, he also claims to have been reading comp.lang.misc for more than three months. > You bristle when asked for any evidence that what you're saying isn't just > hot air. Yes, I do, as the challenges come from a perverting pain in the butt. I don't believe I have left any of your ``questions'' unanswered; I do hope that you learn some civility before you have the nerve to show your userid again in this newsgroup. If you claim once more that my compose() doesn't nest properly, or that I have been reticent in providing evidence that it does, I will feel no compunction in thrashing you in public for the next twenty mistakes you make. Don't take this as a threat, though; I don't want you to tell the truth until you understand that it really is the truth. ---Dan Path: kramden.acf.nyu.edu!brnstnd From: brnstnd@kramden.acf.nyu.edu (Dan Bernstein) Message-ID: <19468:Dec2100:23:0790@kramden.acf.nyu.edu> Date: Fri Dec 21 00:23:07 GMT 1990 Newsgroups: comp.lang.misc Subject: Look, Ma, I can dynamically compose functions in C! X-Original-Subject: Re: Complexity of syntax References: <20@garth.UUCP> <27534.276e5bd3@kuhub.cc.ukans.edu> <1990Dec19.222059.6878@mathrt0.math.chalmers.se> Organization: IR In article <1990Dec19.222059.6878@mathrt0.math.chalmers.se> augustss@cs.chalmers.se (Lennart Augustsson) writes: > To see the difference just try to write a function > that does function composition. Okay. (What follows isn't tested but you'll get the idea.) We'll work with a function descriptor type: struct basicfun { int (*f)(); } ; struct twofun { struct fun *first; struct fun *second; } struct fun { int type; union { struct basicfun b; struct twofun t; } u; } ; #define BASICTYPE 1 #define TWOTYPE 2 To convert a C function pointer into one of these things, given storage space: struct fun *cftofun(c,f) int (*c)(); struct fun *f; { f->type = BASICTYPE; f->u.b.f = c; return f; } To call one of these things, given the argument: int callfun(f,x) struct fun *f; int x; { switch(f->type) { case BASICTYPE: return f->u.b.f(x); case TWOTYPE: return callfun(f->u.t.second, callfun(f->u.t.first,x)); } } Finally, to answer the question: struct fun *compose(second,first,f) struct fun *second; struct fun *first; struct fun *f; { f->type = TWOTYPE; f->u.t.first = first; f->u.t.second = second; return f; } Of course, a more complete implementation would manage struct fun storage, possibly with garbage collection. A different strategy is to store basic functions as just pointers, and composed functions as a pointer to a special function, followed by the first and second pointers; then pointers to these ``objects'' would be passed in as arguments. Back to Lennart: > I claim that this is impossible to do in a portable way. You were saying? ---Dan Path: kramden.acf.nyu.edu!brnstnd From: brnstnd@kramden.acf.nyu.edu (Dan Bernstein) Newsgroups: comp.lang.misc Subject: Re: On whether C has first-class composable functions Message-ID: <25199:Feb801:33:1191@kramden.acf.nyu.edu> Date: Fri Feb 8 01:33:11 GMT 1991 References: <1991Feb6.161639.18311@spool.cs.wisc.edu> <12547:Feb621:05:4491@kramden.acf.nyu.edu> <1991Feb7.150537.9257@spool.cs.wisc.edu> Organization: IR Lines: 99 In article <1991Feb7.150537.9257@spool.cs.wisc.edu> quale@picard.cs.wisc.edu (Douglas E. Quale) writes: > Unfortunately, this doesn't solve the problem. Your `functions' are not > functions. What happens when I pass a Bernstein `function' to twalk(3c)?? ``Unfortunately, your bignum package doesn't solve the problem. Your `bignums' are not numbers. What happens when I pass a DECWRL bignum to getcwd()??'' The mistake here is the second statement. Bignums are numbers; they just aren't the same as C's integers. Similarly, anything supporting certain operations is a function; it doesn't have to be the same as C's functions. Your ``problem'' of passing a non-C-function to twalk() has been quite thoroughly addressed in other postings. Just because twalk() only accepts C functions doesn't mean that other functions aren't functions, either in theory or in practice. This has all been discussed to death before in this newsgroup. If you're trying to contribute something, make an effort to see what's already been contributed. > The question was NEVER, "Can C _implement_ dynamically allocable functions?" I chose the subject line (I choose most subject lines in comp.lang.misc these days) and I was using ``L has X'' to mean ``X can be implemented in L'' where L is a language and X is a semantic feature. Apparently people can't stand this usage, although nobody's been able to come up with any other sensible definition of ``has'' in this context; so I've stopped using ``has'' in this way. Nevertheless, that's what it means in the subject line. This has also been discussed to death before in this newsgroup. If you're trying to contribute something, make an effort to see what's already been contributed. > I can implement a Turing machine simulator in practically any language, > but it's not very interesting or useful. (Not in Fortran.) The reason that a Turing machine simulator isn't useful is that once you get down from theory to practice, you care about issues like efficiency. However, usefulness is not the same thing as power. Would you say that the original Forth doesn't have I/O facilities just because its I/O facilities aren't very useful? No. > Does C _have_ dynamically allocable functions? > No. What's your definition of ``has'' for a semantic feature? I'll bet that your definition will either be (1) syntactic, in which case you're confusing syntax and semantics; or (2) so ambiguous as to be useless; or (3) in agreement with mine. > Compose has a simple mathematical definition, and since Dan is so proud > of his math, he surely knows that (f o g) o h = f o (g o h). > (Strangely he expressed confusion over a nested call to compose in a > posting made by someone else some time ago, but this is really quite > elementary.) *** NOTE ADDED 3/27/91: The ``confusion'' is my quote ``What are you talking about'' when faced with a nonsensical nested compose(). See the article quoted at the end of this one. That call was improperly formed and nonsensical as both a mathematical expression and a C language expression. [ composing three functions in a row ] > Let's see Bernstein's compose function do that. *** NOTE ADDED 3/27/91: This is the first time Doug implied that my compose() didn't work as advertised. Are you shooting from the hip, or are you simply confused? It is trivial to compose() twice in a row. > (On a related note, > he also claimed that it is just as easy to prove program correctness in > C as it is in a functional language. Well, no, that's not really what I claimed, but I'll let this slide. > Since his implementation of compose > in C doesn't obey one of the most trivial identities for that function, > I wonder how he reaches that bizarre conclusion.) You are simply confused. > P.S. Dan, read _The_Structure_and_Interpretation_of_Programming_Languages_, > by Abelson, Sussman and Sussman. Jim Giles said he didn't learn > anything useful from that book, but I certainly did and you might too. I second Jim's opinion. > At the very least it will show you what you can do with first-class > functions. (A short preview: blocks, delayed evaluation, > call-by-name, own variables, coroutines, non-local exits and > objects for OOP.) Ah! Finally you come down out of the fluff and get to some real issues. As I noted in the previous article, I have found very little use for first-class functions in real-world problems. All of the applications you mention can easily be handled in C---and some of them, such as coroutines and so-called ``objects,'' simply don't gain anything from first-class functions. ---Dan Path: kramden.acf.nyu.edu!brnstnd From: brnstnd@kramden.acf.nyu.edu (Dan Bernstein) Newsgroups: comp.lang.misc Subject: Re: On whether C has first-class composable functions Message-ID: <6828:Feb906:14:3491@kramden.acf.nyu.edu> Date: Sat Feb 9 06:14:34 GMT 1991 References: <1991Feb7.150537.9257@spool.cs.wisc.edu> <25199:Feb801:33:1191@kramden.acf.nyu.edu> <1991Feb8.191014.6430@spool.cs.wisc.edu> Organization: IR Lines: 96 In article <1991Feb8.191014.6430@spool.cs.wisc.edu> quale@picard.cs.wisc.edu (Douglas E. Quale) writes: > In article <25199:Feb801:33:1191@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: > >I chose the subject line (I choose most subject lines in comp.lang.misc > >these days) and I was using ``L has X'' to mean ``X can be implemented > >in L'' where L is a language and X is a semantic feature. Apparently > This is not the meaning of ``has''. X can be implemented in L is a > meaningless statement for any languages that are Turing equivalent. First of all, most real languages are not equivalent to Turing machines. People commonly use one of two models for programs. The first says, roughly, that a program is valid if its memory use is bounded by a fixed amount over all possible inputs. (This is for people who don't worry about running out of memory.) The second says, roughly, that a program is valid if its memory use is between N and N+K for all inputs, where N depends on the program and K does not. (This is for when you are worrying about running out of memory.) Both models suffice for real languages. Neither model allows a Turing machine. That's why ``has'' does distinguish languages that have, e.g., dynamic allocation from languages that don't. Second, you didn't respond to my challenge to provide a useful definition of ``L has X'' for L a language and X a semantic feature. I claim that my definition is (1) unambiguous and (2) useful. Why do I say it's useful? Because ``has'' is a helper word. Sure, the statement ``C has first-class functions'' (meaning ``first-class functions can be implemented in C'') doesn't say much. But you can qualify it! You can say ``C has efficient first-class functions'' (``first class functions can be implemented efficiently in C'') or ``C has easy-to-use first-class functions'' or ``C has easy-to-implement first-class functions.'' > Meaningless terminology is not useful, Nevertheless, it has been defined for the purposes of this discussion, so it is no longer meaningless in context. > and quite frankly Dan, I challenge > you to give me evidence that _anyone_ uses ``has'' in the sense(lessness) > that you do. Webster's, definition 5c(b): ``exercise.'' Their example: ``have mercy on us.'' ``Mercy'' is a trait---a semantic feature. ``Doug Quale has mercy on us'' means that you stop rehashing every little bit of a dead discussion---uh, I mean, that Doug Quale exercises mercy, i.e., Doug combines his primitive operations to implement mercy. ``Doug has mercy upon you'' doesn't mean that mercy is one of Doug's *basic* traits, or that mercy is defined as part of Dougginess, or that Doug *always* exercises mercy, or that Doug can show mercy without outside help; similarly for ``C has dynamically allocatable functions.'' And, before you post some irrelevant quibble, let me point out that this definition of ``has'' can be applied to impersonal, inactive objects: ``inetd.conf has control over your connections.'' > I don't think I can say anything more about this. Then don't. > >That call was improperly formed and nonsensical as both a mathematical > >expression and a C language expression. > Dan, wtf are you talking about?? You referred to the time when I expressed confusion over the supposed meaning of somebody's nested compose() call. In case you don't remember, the call in question tried to compose the compose function with an integer function. Once again, that call was improperly formed and nonsensical as both a mathematical expression and a C language expression. > square o square o square > is perfectly sensible as a mathematical expression. Yes. [ about the square examples again ] > And yes, Dan, I specifically request you to try explain what is nonsensical > about those expressions. I never said that those expressions were nonsensical. Your implication is a lie, plain and simple. I doubt you have the integrity to review the articles and apologize, but I'll give you one chance to do so before I start quoting things in public. > Instead of continually saying it's trivial, post your compose code in C and > then we'll see how it stacks up. I did. Since you apparently would rather flame than think, here's the three-way composition that you claim to be so difficult. I've written it out step-by-step and put in comments just for you. compose(square,square,sqsq) /* put square o square in sqsq */ compose(square,sqsq,sqsqsq) /* put square o sqsq in sqsqsq */ printf("%d\n",apply(sqsqsq,2)); /* apply sqsqsq to 2 and print it */ Exercise: write the missing struct fun definitions and initializations. ---Dan Path: kramden.acf.nyu.edu!brnstnd From: brnstnd@kramden.acf.nyu.edu (Dan Bernstein) Message-ID: <13759:Jan800:19:2391@kramden.acf.nyu.edu> Date: Tue Jan 8 00:19:23 GMT 1991 Newsgroups: comp.lang.misc Subject: Re: Re^2: On whether C has first-class composable functions References: <442@data.UUCP> <4408:Jan421:44:3391@kramden.acf.nyu.edu> <443@data.UUCP> Organization: IR In article <443@data.UUCP> kend@data.UUCP (Ken Dickey) writes: > SCHEME also permits the treatment of functions as full flegded data > objects; they may be passed as arguments, returned as values, made > part of composite data structures, and notated as independent, unnamed > ("anonymous") entities. {Contrast this with most ALGOL-like > languages, in which a function can be written only by declaring it and > giving it a name; imagine being able to use an integer value only by > giving it a name in a declaration!). ``Full-fledged data objects,'' yes; but ``first-class'' doesn't mean ``full-fledged.'' > More recently, [Kent Dybvig, "The Scheme Programming Language", > Prentice Hall, 1987] > ...procedures are not always named. Instead, procedures are > first-class data objects similar to strings or numbers; identifiers > are bound to procedures in the same way they are bound to other > objects. Okay, that'd do it; but if that's the definition of ``first-class'' then you can have first-class objects that you can't pass as function arguments! I don't think any of us agree with that. Anyone want to contribute more definitions? > > > By the way, what function would "apply(compose(compose,f),x);" return in C? > > > Strike "composable"? > > What are you talking about? [ explanation ] Okay, you're saying that you want compose() to apply to the first argument of a function with many arguments. This would be more useful if you also had a way to switch around the arguments to a function--- e.g., to convert f(x,y) to g(y,x). There's no reason that these things can't be done with exactly the same techniques as the one-argument compose(), so I don't think your example is a reason to say that we're not talking about composable functions. ---Dan
barmar@think.com (Barry Margolin) (03/28/91)
In article <26146:Mar2804:56:5791@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >In article <1991Mar26.165516.13035@daffy.cs.wisc.edu> quale@saavik.cs.wisc.edu (Douglas E. Quale) writes: >> Byte copying is trivial in Common Lisp. >So translate *(int *)&buf = n; into Lisp. Here char *buf; int n. Assuming buf was created with (defvar buf (make-string <size>)) and <size> is large enough to hold a fixnum: (let ((temp (make-array () :element-type 'fixnum :displaced-to buf))) (declare (dynamic-extent temp)) (setf (aref temp) n)) Note, however, that this is not portable, but I'm not sure the original C code was, either. >> A typical >> "portable" C program running on n different platforms is usually n different >> programs selected by conditional compilation via #ifdef's. > >What a load of crap. My latest compressor, for example, has so far been >reported to work on platforms from about fifty vendors. Four of the >configuration options enable optimizations that depend on available >libraries. One enables extra code to handle a common stdio bug in older >systems. Four set defaults for user options. The rest select between >machine-independent optimizations. There aren't any #ifdefs other than >the configuration options. This is hardly atypical of C programs. Yes, it's quite possible to write such code. I'll bet pty is loaded with system-dependency #ifdef's, though. My guess is that the C world is probably split about even between those two classes of programs. >> Emacs is written in elisp. > >What a(nother) load of crap. Next Doug will be claim that sh, csh, and >ksh are written not in C, but in shell code! After all, the vast >majority of code that people use while executing the shell is, indeed, >in an interpreted language, even if under the scenes there's that dirty >C code actually running and doing all the work. If Emacs is implemented in C, then the shell is implemented in machine language. The Emacs interface that users see is written in a combination of C (most of the character-level I/O, and the Lisp interpreter) and ELisp (most of the commands). Similarly, the shell is implemented in C, but the commands that users type are implemented in a mixture of mostly C and shell script. >> The major advantage of lisp over C here is the fact that >> lisp is much more easily extensible. > >Yep, and the major advantage of sh over C here is the fact that sh is >much more easily extensible. Do I conclude that sh is written in sh? >Yes or no? I think this is a flawed analogy. When dealing with the shell, we normally distinguish the shell itself from the commands it executes (ignoring built-in shell commands), since the commands aren't directly associated with the shell -- if you change your search path, the command set changes. Emacs, however, starts up with a large collection of Lisp-written commands and functions built in, and many of them are fundamental to the operation of the editor. The shell will continue to run without any of the shell scripts that people ordinarily use, but Emacs will fall flat on its face without some of the Lisp functions. -- Barry Margolin, Thinking Machines Corp. barmar@think.com {uunet,harvard}!think!barmar
quale@saavik.cs.wisc.edu (Douglas E. Quale) (03/29/91)
The original challenge was so short I'll repeat it: In Common Lisp, (defun compose (f g) (lambda (&rest) (funcall f (apply g &rest)))) I think it looks better in Scheme, (define (compose f g) (lambda x (f (apply g x)))) These definitions use dynamic typing to obtain polymorphism. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ And now Dan's response: In article <26146:Mar2804:56:5791@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >Enclosed is another copy of the first article, since you didn't respond >to any of my offers via email. This qualifies you as a royal asshole, by >the way. Also enclosed for completeness are references to your first two >articles implying that my compose() didn't work, and, just in case, one >of the intermediate articles that you lied about. Probably mail isn't working on this machine correctly. I bear some responsibility for that, but I am content to let the judgement of which of us is a royal asshole to the readers of this newsgroup. > >The interested reader (I doubt there are any) will note that my >compose() nests properly, while Doug has said repeatedly that it >doesn't. As I recall, he also claims to have been reading comp.lang.misc >for more than three months. > >> You bristle when asked for any evidence that what you're saying isn't just >> hot air. > >Yes, I do, as the challenges come from a perverting pain in the butt. >I don't believe I have left any of your ``questions'' unanswered; I do >hope that you learn some civility before you have the nerve to show your >userid again in this newsgroup. If you claim once more that my compose() >doesn't nest properly, or that I have been reticent in providing >evidence that it does, I will feel no compunction in thrashing you in >public for the next twenty mistakes you make. Don't take this as a >threat, though; I don't want you to tell the truth until you understand >that it really is the truth. > >---Dan And Dan gives a pathetic attempt to code compose in C. Naturally his compose is not polymorphic, a key advantage of dynamic typing that was the whole point of this exercise. That point was specifically mentioned in the challenge since I figured Dan would try to worm out of it -- support for genericity is weak in C. As a parting thought, how long is Dan's nonpolymorphic compose compared to the fully polymorphic lisp versions? Seems like his code is infinitely less capable and well over three times longer. What a surprise. Go ahead Dan. Thrash me in public. You'll only make more of an ass of yourself than you already have, if that's possible. I'm still waiting for a polymorphic compose in C. That was quite clear in my post, but I'm saying it again since you seem to have trouble with English. -- Doug Quale quale@saavik.cs.wisc.edu
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (03/29/91)
In article <1991Mar28.064405.13664@Think.COM> barmar@think.com (Barry Margolin) writes: > Note, however, that this is not portable, but I'm not sure the original C > code was, either. Yes, it *is* portable in C, provided that buf is aligned as an int. I'll grant that Common Lisp has as much pointer support as Ada---i.e., the operations necessary to regard memory as a set of bytes was grafted on afterwards, with so few guarantees that you cannot write portable code in it. > Yes, it's quite possible to write such code. I'll bet pty is loaded with > system-dependency #ifdef's, though. My guess is that the C world is > probably split about even between those two classes of programs. Nope, none at all in pty's case, except the common idiom #ifdef BSD #include <limits.h> #endif isolated in one include file. Everything else is a configuration option to select among available libraries. I think this is rather typical of both systems code and non-systems code in C. [ comments about whether Emacs is written in elisp or in C ] I see your point, but, as I've said before: I refuse to admit that you can change any fundamental characteristics of a language simply by adding a library. Sure, the GNU Emacs distribution comes with a lot of elisp code, without which you'd be insane to use the system. But that elisp code is on *top* of the Emacs program. Emacs is written in C, and no amount of library writing can change this fact. ---Dan
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (03/29/91)
Beautiful, Doug. You repeatedly say that my compose() doesn't nest, you post some sort of final challenge, you accuse me of evasion, I repost the articles in question, and now you try to escape humiliation by perverting the issue into whether compose() can be polymorphic in C. That last bit is evasion, Douglas. Sorry, but it won't work. The issue back then was function composition, NOT dynamic typing. You repeatedly shot from the hip on the issue of whether the available implementations of compose() in C could nest. Now I've called you on it, I've quoted articles where you made a fool of yourself, and you won't be able to pretend that you were saying something else. In this last article, you claim that my reposted compose() routine was in response to your points about dynamic typing. That claim is a lie. Since you're obviously so desperate to avoid embarassment, I can understand your perversions; that doesn't make them the truth. You also seem to be confusing dynamic typing with various other issues, including function allocation. I invite you to learn Forth. ---Dan
barmar@think.com (Barry Margolin) (03/29/91)
In article <2328:Mar2819:54:2491@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: [Regarding my Lisp translation of '*(int *)&buf = n':] >In article <1991Mar28.064405.13664@Think.COM> barmar@think.com (Barry Margolin) writes: >> Note, however, that this is not portable, but I'm not sure the original C >> code was, either. > >Yes, it *is* portable in C, provided that buf is aligned as an int. I'll >grant that Common Lisp has as much pointer support as Ada---i.e., the >operations necessary to regard memory as a set of bytes was grafted on >afterwards, with so few guarantees that you cannot write portable code >in it. I guess we are now stuck on agreeing what "portable" means. After executing: char buf[sizeof int]; *(int *)&buf = 1; what is the value of buf[0]? On some machines it will be 0, on other machines it will be 1, and some strange machines could produce other values. I admit that it's *more* portable than the Lisp translation; the C code has implementation-dependent results, whereas the Common Lisp version has undefined consequences. Indeed, you'll notice that my example used FIXNUM rather than INTEGER as the type of the displaced array, because a Lisp Machine will signal an error if you try to store a bignum, or any non-immediate data type, into an array displaced to a character array. I believe Fortran 77 also disallows equivalencing character arrays with other data types. >> Yes, it's quite possible to write such code. I'll bet pty is loaded with >> system-dependency #ifdef's, though. My guess is that the C world is >> probably split about even between those two classes of programs. > >Nope, none at all in pty's case, except the common idiom #ifdef BSD >#include <limits.h> #endif isolated in one include file. Everything else >is a configuration option to select among available libraries. I think >this is rather typical of both systems code and non-systems code in C. When you say "select among available libraries", are you implying that all the libraries are available in all the Unix implementations that pty runs on, and it's the choice of the user running the configuration script which one to use? Or did you mean "select among possibly available libraries"? If the latter, I thought that was the kind of dependencies that were being described; whether the choice is made by a configuration script or #ifdef directives seems like an insignificant detail. Don't different Unix flavors have different naming schemes for pseudotty devices? I don't think SunOS has any libraries that deal specifically with pseudotty's; every SunOS program I've ever seen that uses them contains an inlined loop to find an available pty, open it, fork, etc. It's really a shame, because they each have different assumptions about the maximum number of possible ptys, and frequently have to be updated when we increase the number of ptys. > [ comments about whether Emacs is written in elisp or in C ] > >I see your point, but, as I've said before: I refuse to admit that you >can change any fundamental characteristics of a language simply by >adding a library. Sure, the GNU Emacs distribution comes with a lot of >elisp code, without which you'd be insane to use the system. But that >elisp code is on *top* of the Emacs program. Emacs is written in C, and >no amount of library writing can change this fact. I just remembered another difference. The Emacs that end-users run is created by starting up a bootstrap program that is written in C and contains the Elisp interpreter and the C portions of the editor, loading in Lisp libraries, and dumping the memory image out into an executable file. By your reasoning, a program that I implement by loading code into Lucid Lisp and dumping out the image is written in the language that Lucid Lisp is written in, even though I might not even know how to program in that language! -- Barry Margolin, Thinking Machines Corp. barmar@think.com {uunet,harvard}!think!barmar
peter@ficc.ferranti.com (Peter da Silva) (03/29/91)
Look, folks, this C versus the world debate is the biggest pain in the neck in comp.lang.misc. I apologise for my own small part in it, here, and I'm bowing out. Next time you see someone claim that C can do anything, or that C is bogus because it can't do something, keep this in mind: Use the right tool for the job: C is the right tool for some jobs, because of the basic "portable assembler" design of the language lets you get down and dirty and write lean code. It is he wrong tool for some jobs, because the "portable assembler" design of the language forces you to get down and dirty and re-invent the wheel. The same is true of any language. You can write Fortran, Lisp, or Prolog style code in any language. If you're using a language that encourages lisp-style coding and what you need is a Forth, or you want to do AI and all you have is Basic, you're going to do a lot more work or buy more hardware than if you pick the right tool. AND: There has never been a language in which it is the least bit difficult to write bad code... -- Peter da Silva. `-_-' peter@ferranti.com +1 713 274 5180. 'U` "Have you hugged your wolf today?"
wilson@uicbert.eecs.uic.edu (Paul Wilson) (03/30/91)
peter@ficc.ferranti.com (Peter da Silva) writes: >In article <1991Mar26.172536.12178@linus.mitre.org> john@mingus.mitre.org (John D. Burger) writes: >> A ``REAL source level debugger'' and incremental compilation are >> functions of the environment. >Just for the hell of it, let me point out that the two languages that >have the greatest number of units out with these features *are* statically >typed: Forth and Basic. ^^^^^ But Forth doesn't have a "REAL source level," so how could it have a REAL source level debugger? Anything where you see raw words on the stack (as opposed to variables with names and/or types) sounds like debugging intermediate code to me. :-) (Sorry, I couldn't resist.) >-- >Peter da Silva. `-_-' peter@ferranti.com >+1 713 274 5180. 'U` "Have you hugged your wolf today?" -- Paul Paul R. Wilson Software Systems Laboratory lab ph.: (312) 996-9216 U. of Illin. at C. EECS Dept. (M/C 154) wilson@bert.eecs.uic.edu Box 4348 Chicago,IL 60680 -- Paul R. Wilson Software Systems Laboratory lab ph.: (312) 996-9216 U. of Illin. at C. EECS Dept. (M/C 154) wilson@bert.eecs.uic.edu Box 4348 Chicago,IL 60680
peter@ficc.ferranti.com (Peter da Silva) (03/30/91)
In article <1991Mar29.164740.25066@uicbert.eecs.uic.edu> wilson@uicbert.eecs.uic.edu (Paul Wilson) writes: > peter@ficc.ferranti.com (Peter da Silva) writes: > >In article <1991Mar26.172536.12178@linus.mitre.org> john@mingus.mitre.org (John D. Burger) writes: > >> A ``REAL source level debugger'' and incremental compilation are > >> functions of the environment. > >Just for the hell of it, let me point out that the two languages that > >have the greatest number of units out with these features *are* statically > >typed: Forth and Basic. > ^^^^^ > But Forth doesn't have a "REAL source level," so how could it have a > REAL source level debugger? > Anything where you see raw words on the stack (as opposed to variables > with names and/or types) sounds like debugging intermediate code to me. > :-) (Sorry, I couldn't resist.) This is a reasonable point, but I understand that people find other stack-based languages (POP?, Postscript) quite adequate. For programming in Forth, you have to think Forth: A-REASONABLE-POINT SWAP SET-ATTRIBUTE LANGUAGES STACK-BASED DUP POP ?HAS-ATTRIBUTE 0= ABORT" OOPS" DUP POSTSCRIPT HAS-ATTRIBUTE OTHER-PEOPLE FIND-REASONABLE SELF UNDERSTANDING SET-ATTRIBUTE FORTH PROGRAMMING-IN IF FORTH THINK THEN Oops, I left stack-based languages on the stack. -- Peter da Silva. `-_-' peter@ferranti.com +1 713 274 5180. 'U` "Have you hugged your wolf today?"
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (04/01/91)
In article <1991Mar29.064102.24914@Think.COM> barmar@think.com (Barry Margolin) writes: > char buf[sizeof int]; > *(int *)&buf = 1; > what is the value of buf[0]? On some machines it will be 0, on other > machines it will be 1, and some strange machines could produce other > values. So what? Just because code is portable doesn't mean it will produce the same results on different machines. What's 32767 * 32767 in Ada? The code works, is useful, and has well-defined results under any C compiler. It can't be translated into portable Lisp code. > Or did you mean "select among possibly available libraries"? Yep, that one. It is not a failure of C that different C platforms provide different nonstandard libraries, and an application that can take advantage of such libraries is hardly ``loaded with machine-dependent #ifdefs.'' > Don't different Unix flavors have different naming schemes for pseudotty > devices? I don't think SunOS has any libraries that deal specifically with > pseudotty's; every SunOS program I've ever seen that uses them contains an > inlined loop to find an available pty, open it, fork, etc. It's really a > shame, because they each have different assumptions about the maximum > number of possible ptys, and frequently have to be updated when we increase > the number of ptys. Yes, it is, and wouldn't it be a lot simpler if all these assumptions were isolated in a couple of configuration options in a single program? > By your reasoning, a program that I implement by loading code into Lucid > Lisp and dumping out the image is written in the language that Lucid Lisp > is written in, even though I might not even know how to program in that > language! No. I didn't say elisp code was written in C. I said Emacs was written in C. Just because it happens to come with a whole bunch of elisp add-ons doesn't change the language Emacs is written in. Would you say C is written in C, just because C platforms come with a whole bunch of libraries that C programs can use? ---Dan