> I guess we're back to my earlier question (more or less): Did the lisp > machines crash often due to not having address spaces?
Rarely. They almost never crashed from stray or bad pointers.
However, it is trivial to crash a Lisp Machine deliberately (iterate through the SYS package setting every symbol value to NIL, for example). I think this would be the `moral equivalent' of zeroing out memory in a more primitive language.
Tim Bradshaw <t...@cley.com> writes: > > I would have an easier time "trusting" my environment if I knew its > > safety relies on proofs rather than on mere hope that not one of a buch of > > a few thousand programmers who I personally don't know haven't screwed up > > somewhere.
> Well, that's good. Perhaps you should start writing a provably > correct shared-memory multiprocessor OS that scales to, say, a 100 > processor machine reasonably well and supports all the features of, > say, Solaris on such HW, and performs as well.
It's not hard to make the argument that he has, given that he's working on SML/NJ. The *first* thing that's needed is a solid language platform.
david rush -- With guns, we are citizens. Without them, we are subjects. -- YZGuy, IPL
Tim Bradshaw <t...@cley.com> writes: > * Thomas Bushnell wrote:
> > In the case of Linux, for example, it doesn't check automatically, but > > only as directed by the kernel--the big, complicated, filled-with-bugs > > kernel.
> Sure, but the kernel only has to set up the page tables once, then the > HW will prevent you trashing (or seeing) other people's memory, > including the OS's. I'm obviously not suggesting a pure hardware > solution, did you really think I was?
Here's the point I was making, I'll spell it out more carefully:
You were arguing that proof-carrying code, or trusted-compiler-generated code was not an adequate replacement for a user/kernel barrier (and concomitant user/user process barriers). It seemed to me that you were saying that was because you wouldn't be willing to actually trust the compiler or the proof-checker to do a perfect job, and so it might let in things that shouldn't be let in.
My reply is that your "hardware" solution actually still depends on the compiler's ability to correctly compile the kernel code (and not generate stray memory writes that might clobber page tables, for example). It also depends on your ability to read through the page-table handling code, and verify that it really does enforce the required barriers. It depends on there being no errant code (anywhere!) in the kernel which might execute a stray memory write that happens to clobber a page table.
So you are really trusting quite a lot.
A proof-checker is pretty easy to get right.
Moreover, a trusted-compiler is just like any other compiler. That is, when I trust the trusted-compiler not to generate stray memory writes, I'm doing *exactly* the same thing as when I trust whatever compiles the kernel not to generate stray memory writes.
* Thomas Bushnell wrote: > You were arguing that proof-carrying code, or > trusted-compiler-generated code was not an adequate replacement for a > user/kernel barrier (and concomitant user/user process barriers). It > seemed to me that you were saying that was because you wouldn't be > willing to actually trust the compiler or the proof-checker to do a > perfect job, and so it might let in things that shouldn't be let in.
Well, no, I wasn't. What I actually wrote was:
Because I can't lay my hands on any other kind. The only kind of native code I'd regard as trusted is that for which there is a formal correctness proof. Since I can't get an X server or a Lisp system which has such a proof for instance, I'm constrained to run ones which might follow random pointers occasionally. In order to reduce the damage that this kind of problem does I like to have a whole lot of dynamic checks on things.
Tim Bradshaw <t...@cley.com> writes: > Because I can't lay my hands on any other kind. The only kind of > native code I'd regard as trusted is that for which there is a formal > correctness proof. Since I can't get an X server or a Lisp system > which has such a proof for instance, I'm constrained to run ones which > might follow random pointers occasionally. In order to reduce the > damage that this kind of problem does I like to have a whole lot of > dynamic checks on things.
Ah, thanks for the clarification.
If you are running traditional process/kernel programs, they may well rely on such protections (even if inadvertently).
The discussion is, however, focused on new systems--ones which, for example, might have no process/kernel split. Or, for example, adding extensions to existing well-designed systems.
Why do you want a formal proof for a Lisp system before you accept its pointer guarantees, but you don't expect a formal proof for the C compiler or your kernel, before you accept their guarantees?
* Thomas Bushnell, BSG | Finally, you do not improve your arguments by calling someone an idiot. | It only makes you look foolish.
You are arguing against ludicrous and bogus arguments you have imputed to me, but which I have not expressed, implied, or made it possible to infer in the first place. _That_ was what was wrong, not your "argument". I have extremely low tolerance for people who play rhetorical games where the goal is to embarrass someone instead of actually making a point, and if you engage in gratuitous fault-finding, too, there is no good-will left on my end at all.
/// -- In a fight against something, the fight has value, victory has none. In a fight for something, the fight is a loss, victory merely relief.
>So I guess that proved correct systems cost a lot more than this, if >they can be written at all.
>I wonder, also, how the military people manage to get hardware which >is provably correct too - they must have some pretty amazing >technology to stop the things that cause random failures for the rest >of us hurting them. I guess they get to save a lot by leaving off all >the dynamic checks since their software is known to be correct...
perhaps not entirely addressing your questions, still, you might be interested in what the following company does: http://www.polyspace.com/
Yes, I know, it's for C and (to my own astonishment) they use abstract interpretation (an obscure method, even statically typed people not necessarly like) and no, of course, they do not detect *all* errors at compile time as they claim, but they give the developer the opportunity to prove certain properties or narrow down potentially buggy parts (and this provably correct!) So, I can imagine that combining such a tool with computer guided (human) theorem proving may actually get you a bit closer to an all provably correct OS.
On Fri, Mar 08, 2002 at 03:45:42PM -0500, Matthias Blume wrote: > On Fri, 08 Mar 2002 15:31:47 -0500, Jochen Schmidt wrote:
> > Daniel C. Wang wrote:
> >> It is extends the work I presented at POPL 2001. I won't make any > >> claims of practicality until I bite the bullet and build a large scale > >> system. However, the underlying design is sound. If you're not > >> concerned about type saftey then the work still offers you a recipe of > >> what minimal abstractions you need to do a GC in your favoriate untyped > >> language.
> > Just curious - do you mean Lisp by mentioning the term "untyped > > language"?
> I think he meant "languages where it is possible to violate at runtime > the type abstractions that were present at compile time". With this, > yes, Lisp is in that class.
A brief glance at the CLHS or CLTL2 will reveal a quite rich system of types. I think the term you are looking for is "static" in reference to what he said above, not "untyped" which is a misnomer.
Your definition of "untyped"-ness also reveals a definite "static"-outlook, which is a different view than that taken by Lispers. In the static view (which I am not condemning), there are distinct and separate phases for compilation and execution. As a result, no changes may be introduced into the running program and the consequence is that compile-time type- invariants are held. Thus it is possible to claim that a program which has a type-error must've been programmed in a language that did not distinguish between types (which "untyped" implies to me) because there is no way to make further changes that rectify the error.
In the "dynamic" view that Lisps generally favor, there is no time set aside only for compilation and no time set aside only for execution. Since it is quite possible to merge newly-compiled code into an already- running image, the language and compiler needs to accomodate the fact that at some point in the process the type-invariants may be broken (even if it is only temporarily). The solution to this, while preserving the dynamic nature of Lisp, is the excellent condition system found in CL, which allows you to work with the system even in an "exceptional" state. No longer is it possible to claim that a type-error implies untyped-ness, because it is the nature of the system that incremental updates may break certain invariants. A "type-error" means that the system is in fact performing type-checking and distinguishes between types, which would be a rather odd thing to be called "untyped". Furthermore there is a strong sense of object-identity in CL which is linked to "strong" type-checking.
Please do not confuse "dynamic" with "weak" or "untyped". There are more points of view than the static one out there, and some of them suit certain problem-sets better than others. There are even languages which can be considered to be static and weakly typed, such as C. I find the two criteria to be orthogonal.
-- ; Matthew Danish <mdan...@andrew.cmu.edu> ; OpenPGP public key: C24B6010 on keyring.debian.org ; Signed or encrypted mail welcome. ; "There is no dark side of the moon really; matter of fact, it's all dark."
Erik Naggum <e...@naggum.net> writes: > I have extremely low tolerance for people who play rhetorical > games where the goal is to embarrass someone instead of actually > making a point, and if you engage in gratuitous fault-finding, > too, there is no good-will left on my end at all.
As do I. Please accept my apology for any slight; I was not trying to engage in gratuitous fault-finding.
My training in philosophy sometimes gets ahead of me, I'm afraid. When confronted with a proposition that I believe to be false, I find the clearest most direct counterexample; the goal is never focused on the person, but only on the proposition. And I don't have any intention of belittleing someone or scoring rhetorical points; I'm actually a very issue-focused person. But that tends (again) to get ahead of me at times, and people interpret my zeal to demonstrate the falisty of some proposition as a zeal to demonstrate the foolishness of some other person. But that is never my goal--though I grant that it can be near impossible to tell.
So this is a plea for good will. In the particular case, I was trying to augment the previous poster's example, the point being that hand-typed tables can be maddeningly hard to get right at times, and even harder to find bugs in than normal code. I once had such a case in (IIRC) a table of parities for ascii. There was a bug in one of the values, and it was so hard to notice in the midst of a big table, that (once I found the bug) I immediately replaced it with a table programmatically generated on startup. *That* I could be sure was correct.
In the instant case, however, my message was even worse, given the presence of a foolish carelessness in my part (since, of course, omitting the "I" was part of the original problem statement).
* tb+use...@becket.net (Thomas Bushnell, BSG) | Why do you want a formal proof for a Lisp system before you accept its | pointer guarantees, but you don't expect a formal proof for the C | compiler or your kernel, before you accept their guarantees?
But has anyone actually asked for a formal proof for a Lisp system?
Mostly, what I have written and what I understand Tim to be writing is a resounding rejection of all the wild claims made by the "proof" and "static typing" crowd, namly that such tactics at the source level is _sufficient_ to ensure a bug-free and fully operationsl system, and that is only necessary because of their attacks on the infrastructure upon which we rely today for problems that very few of us believe would go away with all that fancy-schmancy type-based proof cruft, which has a lot of theoretical values in how to design and not to design software, but those crowds are so incredibly snotty about their "superior" theories and so absolutely clueless about many real-world issues that simply do not fit their theories, and which therefore appear to many to be a case of "if the theory does not fit, you must acquit", which so many people who have "good theories" resort to in order to purposefully discard those parts of reality that are not explainable by their theories. I mean, I know some really smart people who have these incredibly ludicrous ideas about how to design and run societies because they flat out refuse to believe that bad people exist, and so completely ignore the threat they pose and offer no way to deal with anyone who would seize the opportunity to do someone harm. My theory of society-building is that people are only polite and friendly and can work together because there are some very serious and credible counter-forces that would be applied against any real or attempted use of force to begin with, and that translates to how computers have to deal with all of those malicious people who do _not_ perceive a credible counter-force to their destructive intents and to all those _mishaps_ that just happen to software in a very unfriendly real world.
/// -- In a fight against something, the fight has value, victory has none. In a fight for something, the fight is a loss, victory merely relief.
Matthias Blume wrote: > On Fri, 08 Mar 2002 15:31:47 -0500, Jochen Schmidt wrote:
>> Daniel C. Wang wrote:
>>> It is extends the work I presented at POPL 2001. I won't make any >>> claims of practicality until I bite the bullet and build a large scale >>> system. However, the underlying design is sound. If you're not >>> concerned about type saftey then the work still offers you a recipe of >>> what minimal abstractions you need to do a GC in your favoriate untyped >>> language.
>> Just curious - do you mean Lisp by mentioning the term "untyped >> language"?
> I think he meant "languages where it is possible to violate at runtime > the type abstractions that were present at compile time". With this, > yes, Lisp is in that class.
Then I would give our lisp newcomers from the static typed world the advice that they learn to decide between "dynamic strong typing" and "static strong typing". It is completely nonsense to call lisp untyped and shows that someone has absolutely no clue about typing at all.
Erik Naggum <e...@naggum.net> writes: > Mostly, what I have written and what I understand Tim to be writing is a > resounding rejection of all the wild claims made by the "proof" and > "static typing" crowd, namly that such tactics at the source level is > _sufficient_ to ensure a bug-free and fully operationsl system > [....]
I don't think it is; such wild claims are certainly, well, wild.
I think the point is that proof carrying code, or using only pointer-safe languages, obviates the need for memory barriers between programs. It certainly doesn't obviate the need for other security and reliability techniques.
* tb+use...@becket.net (Thomas Bushnell, BSG) | My training in philosophy sometimes gets ahead of me, I'm afraid. When | confronted with a proposition that I believe to be false, I find the | clearest most direct counterexample; the goal is never focused on the | person, but only on the proposition.
However, the space of things that are the negations of falsehoods is rather large and does not at all need to include any truth. By picking a particular negation of a falsehood, you imply that your angle on what is false is sufficient to construct a counterexample. This is generally not true. When somebody is opposed to something, as is the case here, there is no telling what they actually would like propose. By choosing some counter-example to a negative argument, you actually do impute intention and opinions about what a person would propose if they did not oppose your particular argument to begin with. I have a very hard time seeing how this can _not_ result in hostilities.
| But that tends (again) to get ahead of me at times, and people interpret | my zeal to demonstrate the falisty of some proposition as a zeal to | demonstrate the foolishness of some other person. But that is never my | goal--though I grant that it can be near impossible to tell.
If someone spends a lot of time demonstrating the falsity of something a person does not even express or imply, because the falsity you perceive is in your view a counter-argument to your position. It is vital to keep track of positive and negative propositions and arguments in order to make this work. Because the disproportionally larger space of a negative proposition, the negative of a negative may not even include the positive -- and that means that you must be very careful in countering arguments against your own position with counter-examples. Instead, support your initial position.
| So this is a plea for good will. In the particular case, I was trying to | augment the previous poster's example, the point being that hand-typed | tables can be maddeningly hard to get right at times, and even harder to | find bugs in than normal code.
However, it was not hand-typed. Christ, give me a break. First, if it were a hand-typed table, the line with l-p would not _all_ be lowercase, now, would it? Second, just because something is in source form does not mean it was typed in by a human being. It is far easier to read a case statement that actually contains the cases than code that builds a hairly table. It is also far better to let the compiler writers worry about the optimization of table lookup than to do that grunt work yourself. case is the right tool for the job.
Of all the languages in which you can write code, the Lisp family offers the best way of all to produce some output and recycle it as code. I do this a lot, because it is often easier to write Emacs Lisp code to write code for you than it is to type it in manually, anyway.
| I once had such a case in (IIRC) a table of parities for ascii. There | was a bug in one of the values, and it was so hard to notice in the midst | of a big table, that (once I found the bug) I immediately replaced it | with a table programmatically generated on startup. *That* I could be | sure was correct.
Well, I prefer to produce source code in intimate cooperation with the editor, Emacs.
| In the instant case, however, my message was even worse, given the | presence of a foolish carelessness in my part (since, of course, | omitting the "I" was part of the original problem statement).
I think your careless assumption that it was hand-typed should have been amply refuted by the presence of a systematic error that should unlikely have been made by hand.
/// -- In a fight against something, the fight has value, victory has none. In a fight for something, the fight is a loss, victory merely relief.
* Thomas Bushnell wrote: > Why do you want a formal proof for a Lisp system before you accept its > pointer guarantees, but you don't expect a formal proof for the C > compiler or your kernel, before you accept their guarantees?
I would like formal proofs for both. Since I can't get them for either I want to have as many layers of probably-working stuff between me and disaster. Given that there is one instance of the kernel which gets tested continually (and has not yet failed on our systems) as against some thousand or so user programs none of which I trust, I'm also reasonably convinced that the kernel actually is correct enough, whereas I have plenty of evidence that the programs (including lisp systems) are not entirely trustworthy.
(Incidentally this is the general flaw in the `why do you trust this thing and not that thing' argument. If `this thing' is a library or kernel which is used all the time and `that thing' is several hundred programs, then it is completely rational to trust this thing more than that thing. It's the reason why when my Lisp programs die, I tend to assume that I've made a mistake rather than the compiler is buggy. Statistics is a wonderful thing, although something alien to the `discrete' CS mindset I realise.)
Matthias Blume <matth...@shimizu-blume.com> writes: > now. I am quite confident that in, say, 100 years the world of OS design > will look quite different, but it will take a major revolution or two to > get there.
Tim Bradshaw <t...@cley.com> writes: > I wonder, also, how the military people manage to get hardware which > is provably correct too - they must have some pretty amazing > technology to stop the things that cause random failures for the rest > of us hurting them. I guess they get to save a lot by leaving off all
ROTFLBTC.
comp.risks is next door.
(Yes, this _must_ be a small malfunction of my irony detector.)
In article <okfhenq90mr....@bellsouth.net>, David Rush wrote: > Tim Bradshaw <t...@cley.com> writes: >> > I would have an easier time "trusting" my environment if I knew its >> > safety relies on proofs rather than on mere hope that not one of a buch of >> > a few thousand programmers who I personally don't know haven't screwed up >> > somewhere.
>> Well, that's good. Perhaps you should start writing a provably >> correct shared-memory multiprocessor OS that scales to, say, a 100 >> processor machine reasonably well and supports all the features of, >> say, Solaris on such HW, and performs as well.
> It's not hard to make the argument that he has, given that he's > working on SML/NJ. The *first* thing that's needed is a solid language > platform.
Maybe so; only that Lisp is a solid language platform, too. SML/NJ is started by a shell script called ``.run-sml''. I had to hack it before I could use SML/NJ, because it contained a bug that passed a command line argument like "foo bar" as two arguments "foo" and "bar". The shell script wasn't written in SML, of course, but the point is: bugs lurk everywhere. You will not magically get rid of them only because you use a language that is statically strongly typed instead of one that is dynamically strongly typed. Typed lambda calculus is a nice thing. But that does not imply at all, as many people seem to believe, that we suddenly all have to use a statically typed language in order to write good software. You can just as well regard dynamic typing as a /feature/ of your language which makes your language more expressive and hence programming easier; and easily written programs usually have /less/ bugs than more complicated ones. There is no way to prove whether this is true or not. All you can do is try and see for yourself :-)
And another point I made long ago /still/ remains: If people think we need statically typed languages to write working software, because there provably won't be any runtime type-errors [1], why not go all the way and demand Haskell? Look into your mind and answer yourself why you wouldn't write an OS in Haskell and you are almost there: You'll suddenly see why Lisp people don't use statically typed languages :-)
(defun start-program (program &rest args) (handler-case (apply (symbol-function program) args) (type-error (cnd) (format *error-output* "~&~A was shut down because of a type error:~&~A" program cnd))))
BLARK 7 > (start-program 'first-two 42) FIRST-TWO was shut down because of a type error: 42 is not of type CONS. NIL
BLARK 8 >
See? Why couldn't my OS do just that? No weird things happen, no BSOD, no kernel panic. Aren't there any exceptions you might forget to catch in *ML?
[1] As if those languages didn't contain undocumented loopholes that let you circumvent that security; read the OCaml list and learn that advanced users of OCaml use them all the time. I always have to laugh when I see that.
Regards, -- Nils Goesche PGP key ID 0x42B32FC9
"The sooner all the animals are dead, the sooner we'll find their money." -- Ed Bluestone
In comp.lang.scheme Tim Bradshaw <t...@cley.com> wrote:
> * Sander Vesik wrote:
>> Nobody in commercial use cares about that level - the 'proved correct' >> things would only be found in teh inner circles of large defence networks >> in paranoid countries.
> Well, this is kind of interesting. People with big commercial > applications *definitely* care about them being reliable and correct, > and are willing to pay serious money for this. Banking systems can > cost many, many millions of pounds a day if they're down, and more > than that if they develop undetected errors.
They also tend to ask questions like 'how many millions of transactions per second' and 'lets say this disk here goes bad, what happens then'? They don't just want systems that are reliable - they want systems that are reliabe, fast and have a large capacity. And they couldn't care less whetever the downtime is due to OS, database or hardware.
> So I guess that proved correct systems cost a lot more than this, if > they can be written at all.
You are assuming that a "proved correct" OS kernel is huge beneficial asset on its own.
> I wonder, also, how the military people manage to get hardware which > is provably correct too - they must have some pretty amazing
For a start, they don't buy off the shelf PC boxes.
> technology to stop the things that cause random failures for the rest > of us hurting them. I guess they get to save a lot by leaving off all
Well, redundant and self-checking hardware isn't exactly new. There are also algorithms for software that check that the result is correct as part of the computation.
> the dynamic checks since their software is known to be correct...
On Sat, 09 Mar 2002 11:22:16 -0500, Nils Goesche wrote: > In article <okfhenq90mr....@bellsouth.net>, David Rush wrote: >> Tim Bradshaw <t...@cley.com> writes: >>> > I would have an easier time "trusting" my environment if I knew its >>> > safety relies on proofs rather than on mere hope that not one of a >>> > buch of a few thousand programmers who I personally don't know >>> > haven't screwed up somewhere.
>>> Well, that's good. Perhaps you should start writing a provably >>> correct shared-memory multiprocessor OS that scales to, say, a 100 >>> processor machine reasonably well and supports all the features of, >>> say, Solaris on such HW, and performs as well.
>> It's not hard to make the argument that he has, given that he's working >> on SML/NJ. The *first* thing that's needed is a solid language >> platform.
> Maybe so; only that Lisp is a solid language platform, too.
But it is not statically typed, so the point is moot. It is not expressive enough to do the things that I want to do. (That is: I can't express invariants as types.)
> SML/NJ is > started by a shell script called ``.run-sml''. I had to hack it before > I could use SML/NJ, because it contained a bug that passed a command > line argument like "foo bar" as two arguments "foo" and "bar". The > shell script wasn't written in SML, of course, but the point is: bugs > lurk everywhere.
Thank you for just making my point: Since we still have to live in the world of Unix, we have to somehow get started. That's why there is Unix-specific stuff. I'd *love* to get rid of it, but currently I can't, precisely because of how the OS works.
You will not magically get rid of them only because
> you use a language that is statically strongly typed instead of one that > is dynamically strongly typed. Typed lambda calculus is a nice thing. > But that does not imply at all, as many people seem to believe, that we > suddenly all have to use a statically typed language in order to write > good software. You can just as well regard dynamic typing as a /feature/ > of your language which makes your language more expressive and hence > programming easier; and easily written programs usually have /less/ bugs > than more complicated ones. There is no way to prove whether this is > true or not. All you can do is try and see for yourself :-)
Well, what can I say. I did, and I found the opposite to be true. But I said that already...
> And another point I made long ago /still/ remains: If people think we > need statically typed languages to write working software, because there > provably won't be any runtime type-errors [1], why not go all the way > and demand Haskell? Look into your mind and answer yourself why you > wouldn't write an OS in Haskell and you are almost there: You'll > suddenly see why Lisp people don't use statically typed languages :-)
Nonsense. In Haskell it is very, very hard to get an intuitive graps on resource consumption. Switch two operands of a +, and your program blows up. This is due to lazy evaluation (which, for many other purposes, has its very good sides, too). This has nothing to do with static vs. dynamic typing.
> See? Why couldn't my OS do just that? No weird things happen, no BSOD, > no kernel panic. Aren't there any exceptions you might forget to catch > in *ML?
True. But there are static exception analyzers that try to mitigate this problem. In the end, yes, there will always be things that need to be checked at runtime. But I am not willing to pay for those that don't have to be.
The exception thing is also a program design problem -- and those don't get magically resolved by switching over to a statically typed language alone. What the language gives you is a set of tools that enable you to redesign the problem.
Simple example: I have a finite map data structure. Should lookup raise an exception if the item to be looked up is not in the domain of the map? Well, I prefer to have lookup return an option. This is sometimes less convenient to use, but it makes it clear at the type level that one must somehow be prepared to deal with the failure case. (Of course, in certain applications the other interface is more convenient.)
> [1] As if those languages didn't contain undocumented loopholes that > let you circumvent that security; read the OCaml list and learn that > advanced users of OCaml use them all the time. I always have to > laugh when I see that.
So do I. (I don't program in Ocaml.) By the way, Ocaml is a very poor example because "language" coincides with "the one and only implementation". But take SML, for example: There are *no* "undocumented" loopholes in the "language", but most implementations probably do provide some "escape hatches". Clearly, if the language is to be used in the way that I outlined, then there must be no loopholes in the implementation. (Or, those loopholes must be governed by some access control mechanism. This is just like "root" in Unix: "root" is a *gigantic* loophole, but only privileged users have access to it -- at least that's the theory. :-)
In comp.lang.scheme Matthias Blume <matth...@shimizu-blume.com> wrote:
[snip]
> Thank you for just making my point: Since we still have to live in the world > of Unix, we have to somehow get started. That's why there is > Unix-specific stuff. I'd *love* to get rid of it, but currently I can't, > precisely because of how the OS works.
You mean there is a realy, quantifyable problem that keeps you from supporting the
#!/path/to/interpreter [arg1 [arg2 ... ] ...]
format?
> So do I. (I don't program in Ocaml.) By the way, Ocaml is a very poor > example because "language" coincides with "the one and only > implementation". But take SML, for example: There are *no* > "undocumented" loopholes in the "language", but most implementations > probably do provide some "escape hatches". Clearly, if the language is > to be used in the way that I outlined, then there must be no loopholes > in the implementation. (Or, those loopholes must be governed by some > access control mechanism. This is just like "root" in Unix: "root" is > a *gigantic* loophole, but only privileged users have access to it -- at > least that's the theory. :-)
This is not strictly true - both the bsd runlevels and the B2 variants of the various commercial unix-es are examples where this isn't true.
In article <pan.2002.03.09.12.48.52.348925.31...@shimizu-blume.com>, Matthias Blume wrote: > On Sat, 09 Mar 2002 11:22:16 -0500, Nils Goesche wrote:
>> In article <okfhenq90mr....@bellsouth.net>, David Rush wrote: >>> Tim Bradshaw <t...@cley.com> writes: >>>> > I would have an easier time "trusting" my environment if I knew its >>>> > safety relies on proofs rather than on mere hope that not one of a >>>> > buch of a few thousand programmers who I personally don't know >>>> > haven't screwed up somewhere.
>>>> Well, that's good. Perhaps you should start writing a provably >>>> correct shared-memory multiprocessor OS that scales to, say, a 100 >>>> processor machine reasonably well and supports all the features of, >>>> say, Solaris on such HW, and performs as well.
>>> It's not hard to make the argument that he has, given that he's working >>> on SML/NJ. The *first* thing that's needed is a solid language >>> platform.
>> Maybe so; only that Lisp is a solid language platform, too.
> But it is not statically typed, so the point is moot.
Maybe it is moot for you; some people, however, think that we need a statically typed language for writing a reliable OS. I know that your point is actually a bit different, but I wasn't talking only to you.
> It is not expressive enough to do the things that I want to do. > (That is: I can't express invariants as types.)
This reminds me of a Perl programmer who says ``I want Perl because I can easily do fancy regexp things with it'' ;-)
>> SML/NJ is >> started by a shell script called ``.run-sml''. I had to hack it before >> I could use SML/NJ, because it contained a bug that passed a command >> line argument like "foo bar" as two arguments "foo" and "bar". The >> shell script wasn't written in SML, of course, but the point is: bugs >> lurk everywhere.
> Thank you for just making my point: Since we still have to live in the world > of Unix, we have to somehow get started. That's why there is > Unix-specific stuff. I'd *love* to get rid of it, but currently I can't, > precisely because of how the OS works.
Hey, it's *my* point :-) I anticipated that response, that's why I added ``It isn't written in XML, of course''. BTW, Unix has no problems at all with spaces in arguments to processes, it's sh, something quite different. The only significance of this is that bugs come from various directions. Static typing gets rid of one particular kind of bug, a million others remain. And as there is no such thing as a free lunch, you pay a price for getting rid of run-time type errors. If what you get for what you pay for is worth it, fine; I, however, believe it isn't.
>> You will not magically get rid of them only because >> you use a language that is statically strongly typed instead of one that >> is dynamically strongly typed. Typed lambda calculus is a nice thing. >> But that does not imply at all, as many people seem to believe, that we >> suddenly all have to use a statically typed language in order to write >> good software. You can just as well regard dynamic typing as a /feature/ >> of your language which makes your language more expressive and hence >> programming easier; and easily written programs usually have /less/ bugs >> than more complicated ones. There is no way to prove whether this is >> true or not. All you can do is try and see for yourself :-)
> Well, what can I say. I did, and I found the opposite to be true. But I > said that already...
Maybe, but that's all we can say: We tried and came to different conclusions. Neither of us can prove that he is right on this. Other than actually writing the OS, which is quite hard :-)
>> And another point I made long ago /still/ remains: If people think we >> need statically typed languages to write working software, because there >> provably won't be any runtime type-errors [1], why not go all the way >> and demand Haskell? Look into your mind and answer yourself why you >> wouldn't write an OS in Haskell and you are almost there: You'll >> suddenly see why Lisp people don't use statically typed languages :-)
> Nonsense. In Haskell it is very, very hard to get an intuitive graps on > resource consumption. Switch two operands of a +, and your program blows > up. This is due to lazy evaluation (which, for many other purposes, has > its very good sides, too). This has nothing to do with static vs. > dynamic typing.
It has to do with the question whether we need static typing for writing reliable code - indirectly: If that were true, if we really needed provable facts about our programs to make them safe, then why not use Haskell? Because we can prove much more things much more easily about purely functional code; you give good reasons why choosing Haskell would be stupid, but if it is allowed to make such arguments, maybe some other arguments that would lead to the conclusion that we don't need static typing either, would /also/ be allowed... Do you really not understand this?
>> See? Why couldn't my OS do just that? No weird things happen, no BSOD, >> no kernel panic. Aren't there any exceptions you might forget to catch >> in *ML?
> True. But there are static exception analyzers that try to mitigate this > problem. In the end, yes, there will always be things that need to be > checked at runtime. But I am not willing to pay for those that don't > have to be.
Yes, that was /your/ point all along. I wasn't talking about that. What I'd answer to /you/ is that I doubt that you would gain very much by eliminating some runtime checks - at least not enough that it was worth the inevitable price that comes with it... I can't prove that, of course; but stop acting as if you or anybody else could prove otherwise, because they can't.
> Simple example: I have a finite map data structure. Should lookup raise > an exception if the item to be looked up is not in the domain of the map? > Well, I prefer to have lookup return an option. This is sometimes less > convenient to use, but it makes it clear at the type level that one must > somehow be prepared to deal with the failure case. (Of course, in > certain applications the other interface is more convenient.)
I agree and am happy that Lisp agrees, too :-)
Regards, -- Nils Goesche PGP key ID 0x42B32FC9
"The sooner all the animals are dead, the sooner we'll find their money." -- Ed Bluestone
Matthias Blume <matth...@shimizu-blume.com> writes: > On Sat, 09 Mar 2002 11:22:16 -0500, Nils Goesche wrote:
> > In article <okfhenq90mr....@bellsouth.net>, David Rush wrote: > >> Tim Bradshaw <t...@cley.com> writes: > >>> > I would have an easier time "trusting" my environment if I knew its > >>> > safety relies on proofs rather than on mere hope that not one of a > >>> > buch of a few thousand programmers who I personally don't know > >>> > haven't screwed up somewhere.
> >>> Well, that's good. Perhaps you should start writing a provably > >>> correct shared-memory multiprocessor OS that scales to, say, a 100 > >>> processor machine reasonably well and supports all the features of, > >>> say, Solaris on such HW, and performs as well.
> >> It's not hard to make the argument that he has, given that he's working > >> on SML/NJ. The *first* thing that's needed is a solid language > >> platform.
> > Maybe so; only that Lisp is a solid language platform, too.
> But it is not statically typed, so the point is moot. It is not > expressive enough to do the things that I want to do. (That is: I can't > express invariants as types.)
And why do you need to express an "invariant" as a "type"?
Seriously, most uses of the type system I saw in *ML languages are to define "sublanguages". Here is an example from a Type Checker written in very standard (AFAIU) SML/NJ
datatype Expression = constant of Constant | variable of Variable | lambda of Variable * Expression | conditional of Expression * Expression * Expression | application of Expression * Expression | let_exp of (Variable list) * (Expression list) * Expression | letrec_exp of (Variable list) * (Expression list) * Expression | oper of Operator * Expression * Expression
So, now you have your "type" which is nothing else than a glorified S-expr. This is essentially my personal experience with *ML programs.
Yes. I do believe that type inferencing does buy you a lot. I just do not think it buys you enough to make you switch.
* (compile 'baz) In: LAMBDA NIL (FOO 3) Warning: Result is a NUMBER, not a (VALUES &OPTIONAL LIST &REST T).
Compilation unit finished. 1 warning
BAZ T T
You may not consider this sufficient, but it is already a lot.
...
> Simple example: I have a finite map data structure. Should lookup raise > an exception if the item to be looked up is not in the domain of the map? > Well, I prefer to have lookup return an option. This is sometimes less > convenient to use, but it makes it clear at the type level that one must > somehow be prepared to deal with the failure case. (Of course, in > certain applications the other interface is more convenient.)
This is one of the typical examples of different viewpoints, which are just an example of "diversity".
You insistence on "at the type level" you "prefer to return an option" (it'd be nice to explain what this actually means) is just a fancy way to say: my function will return a second value of NIL if the item is not in the map. E.g. this is what GETHASH does. Somehow, I will have to deal with the case, but this is simply part of the "contract" the function writer is asking me to respect. There is nothing magical about "types" in this context (unless I am grossly misunderstanding something).
I.e. defining something like
datatype 'a result = item of 'a | not_found
fun find x [] = not_found | find x (first::rest) = if x = first then item(first) else find x rest
and then writing code that does not handle the `not_found' type constant is just the same as writing code that does not handle the NIL.
fun foo item(x) = x + 4
is definable (AFAIK) and all you will get is a warning about a possible match exception. Granted, it is better than doing
(defun find* (x list) ....)
(defun foo (x) (+ x 4))
(foo (find* 3 '(1 2 44)))
But the bottom line is that you will still get a runtime error if you wrote
foo (find 3 [1, 2, 44])
And, at the end of the day, by moving to *ML, I have lost code and data equivalency, a powerful macro system and multimethods. This is why I stick to CL, hoping that the compilers will improve their type inferencing capabilites.
Cheers
-- Marco Antoniotti ======================================================== NYU Courant Bioinformatics Group tel. +1 - 212 - 998 3488 719 Broadway 12th Floor fax +1 - 212 - 995 4122 New York, NY 10003, USA http://bioinformatics.cat.nyu.edu "Hello New York! We'll do what we can!" Bill Murray in `Ghostbusters'.
On Sat, 09 Mar 2002 13:37:42 -0500, Nils Goesche wrote: >>> And another point I made long ago /still/ remains: If people think we >>> need statically typed languages to write working software, because >>> there provably won't be any runtime type-errors [1], why not go all >>> the way and demand Haskell? Look into your mind and answer yourself >>> why you wouldn't write an OS in Haskell and you are almost there: >>> You'll suddenly see why Lisp people don't use statically typed >>> languages :-)
>> Nonsense. In Haskell it is very, very hard to get an intuitive graps >> on resource consumption. Switch two operands of a +, and your program >> blows up. This is due to lazy evaluation (which, for many other >> purposes, has its very good sides, too). This has nothing to do with >> static vs. dynamic typing.
> It has to do with the question whether we need static typing for writing > reliable code - indirectly: If that were true, if we really needed > provable facts about our programs to make them safe, then why not use > Haskell? Because we can prove much more things much more easily about > purely functional code; you give good reasons why choosing Haskell would > be stupid, but if it is allowed to make such arguments, maybe some other > arguments that would lead to the conclusion that we don't need static > typing either, would /also/ be allowed... Do you really not understand > this?
I understand that you are trying to make this point. But I haven't seen those "other arguments" yet, at least not convincing ones. And I happen to believe that they don't really exists.
>> Simple example: I have a finite map data structure. Should lookup >> raise an exception if the item to be looked up is not in the domain of >> the map? Well, I prefer to have lookup return an option. This is >> sometimes less convenient to use, but it makes it clear at the type >> level that one must somehow be prepared to deal with the failure case. >> (Of course, in certain applications the other interface is more >> convenient.)
> I agree and am happy that Lisp agrees, too :-)
How does Lisp remind me (at compile time!) that I am not handling a case that I should handle?