* Re: bottom types and threaded exits
@ 2000-09-25 19:56 Damien Doligez
0 siblings, 0 replies; 13+ messages in thread
From: Damien Doligez @ 2000-09-25 19:56 UTC (permalink / raw)
To: caml-list
>From: Remi VANICAT <remi.vanicat@labri.u-bordeaux.fr>
>exception Sould_never_be_here
>
>let f () = while true do () done ; raise Sould_never_be_here
That's what "assert false" was invented for: the canonical expression
that "returns" a result of type 'a and should normally never be
evaluated.
let f () = while true do () done; assert false;;
-- Damien
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: bottom types and threaded exits
2000-10-02 16:28 ` Markus Mottl
@ 2000-10-05 18:39 ` Pierre Weis
0 siblings, 0 replies; 13+ messages in thread
From: Pierre Weis @ 2000-10-05 18:39 UTC (permalink / raw)
To: Markus Mottl; +Cc: caml-list
> On Mon, 02 Oct 2000, Patrick M Doane wrote:
> > This may be too obvious to point out, but that statement isn't always
> > true. From the Pervasives library:
> >
> > val input_value : in_channel -> 'a
> >
> > clearly returns. I don't quite understood why the return type isn't
> > a monomorphic type variable though.
>
> The "input_value"-function is unfortunately not type safe: you can "cast"
> whatever data you get from the channel to any kind of type - whether this
> is correct or not. There is currently no better way to do it if you want to
> reconstruct marshalled data (data that was sent with output_value). You
> have to trust that the OCaml-data you get is of the type you expect.
>
> Pierre mentioned that there is work going on in this field (a PhD-thesis)
> that should make I/O much safer. Is there any news about this?
>
> Best regards,
> Markus Mottl
>
> --
> Markus Mottl, mottl@miss.wu-wien.ac.at, http://miss.wu-wien.ac.at/~mottl
Nothing to add to Markus explanation, except that the type of (the
equivalent of) input_value in the new system is
Forall $a. in_channel -> $a
the $ in $a meaning that this is not a regular structural polymorphic
type parameter, but a special ``dynamic'' type parameter (with special
typing rule and compilation).
Jun Furuse is working on the subject. His PhD-thesis is on the way
(more than 150 pages written). The type system and compiler are up and
running on top of a 2.99 Objective Caml system. The current plan is to
distribute this version as soon as the final draft of the thesis is
achieved, since the thesis definitively has the highest priority.
Pierre Weis
INRIA, Projet Cristal, Pierre.Weis@inria.fr, http://cristal.inria.fr/~weis/
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: bottom types and threaded exits
2000-10-02 13:11 ` Patrick M Doane
@ 2000-10-02 16:28 ` Markus Mottl
2000-10-05 18:39 ` Pierre Weis
0 siblings, 1 reply; 13+ messages in thread
From: Markus Mottl @ 2000-10-02 16:28 UTC (permalink / raw)
To: Patrick M Doane; +Cc: Stefan Monnier, caml-list
On Mon, 02 Oct 2000, Patrick M Doane wrote:
> This may be too obvious to point out, but that statement isn't always
> true. From the Pervasives library:
>
> val input_value : in_channel -> 'a
>
> clearly returns. I don't quite understood why the return type isn't
> a monomorphic type variable though.
The "input_value"-function is unfortunately not type safe: you can "cast"
whatever data you get from the channel to any kind of type - whether this
is correct or not. There is currently no better way to do it if you want to
reconstruct marshalled data (data that was sent with output_value). You
have to trust that the OCaml-data you get is of the type you expect.
Pierre mentioned that there is work going on in this field (a PhD-thesis)
that should make I/O much safer. Is there any news about this?
Best regards,
Markus Mottl
--
Markus Mottl, mottl@miss.wu-wien.ac.at, http://miss.wu-wien.ac.at/~mottl
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: bottom types and threaded exits
2000-09-30 14:28 ` Stefan Monnier
@ 2000-10-02 13:11 ` Patrick M Doane
2000-10-02 16:28 ` Markus Mottl
0 siblings, 1 reply; 13+ messages in thread
From: Patrick M Doane @ 2000-10-02 13:11 UTC (permalink / raw)
To: Stefan Monnier; +Cc: caml-list
On 30 Sep 2000, Stefan Monnier wrote:
> A function of type "t1 -> t2" does not necessarily return an object of type t2.
> But if it does return, then the value is of type t2.
> Similarly, a function of type "t1 -> 'a" (if it returns) returns an value
> of type 'a. Parametricity allows us to infer from that that if t1 does
> not contain 'a as a free type variable, then the function will necessarily
> never return (since it has no way to construct an value of
> type 'a).
This may be too obvious to point out, but that statement isn't always
true. From the Pervasives library:
val input_value : in_channel -> 'a
clearly returns. I don't quite understood why the return type isn't
a monomorphic type variable though.
Patrick Doane
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: bottom types and threaded exits
2000-09-30 14:25 ` Pierre Weis
@ 2000-09-30 15:19 ` Markus Mottl
0 siblings, 0 replies; 13+ messages in thread
From: Markus Mottl @ 2000-09-30 15:19 UTC (permalink / raw)
To: Pierre Weis; +Cc: Julian Assange, caml-list
On Sat, 30 Sep 2000, Pierre Weis wrote:
> Once more I would prefer a more general recursive function, that would
> loop for any (even non looping) function. For instance:
>
> # let rec bottom f = f (); bottom f;;
> val bottom : (unit -> 'a) -> 'b = <fun>
>
> and I consider the 'b in the type of bottom as clearly indicating the
> looping for ever nature of any application of the bottom function.
The name "bottom" might be a bit confusing in this context, because "f"
could be a function with observable side effects (e.g. I/O), whereas
"bottom" is usually used to indicate non-termination only, which cannot be
observed.
But this function (with a different name) and others would come handy more
often than once, e.g.:
let rec forever f = f (); forever f
let try_forever e f = try forever f with exn -> if e <> exn then raise exn
This would allow:
let _ =
try_forever End_of_file (fun () -> print_endline (read_line ()));
print_endline "Done!"
It is much more tedious (and error-prone if one forgets the "begin ...
end") to write the following:
let _ =
begin
try while true do print_endline (read_line ()) done
with End_of_file -> ()
end;
print_endline "Done!"
Maybe functions similar to "forever" and "try_forever" could make it into
the standard library? Such loops come up quite often with e.g. servers or
I/O-loops in general.
Best regards,
Markus Mottl
--
Markus Mottl, mottl@miss.wu-wien.ac.at, http://miss.wu-wien.ac.at/~mottl
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: bottom types and threaded exits
2000-09-30 9:12 ` Julian Assange
2000-09-30 14:25 ` Pierre Weis
@ 2000-09-30 14:28 ` Stefan Monnier
2000-10-02 13:11 ` Patrick M Doane
1 sibling, 1 reply; 13+ messages in thread
From: Stefan Monnier @ 2000-09-30 14:28 UTC (permalink / raw)
To: caml-list
>>>>> "Julian" == Julian Assange <proff@iq.org> writes:
> It depends on what level of semantics you are looking at. As far as
> type proofing is concerned, 'a is correct. However at a higher level
> you can say `the function never returns so saying that it returns any
> type is incorrect'. The problem is that some functions that do return,
A function of type "t1 -> t2" does not necessarily return an object of type t2.
But if it does return, then the value is of type t2.
Similarly, a function of type "t1 -> 'a" (if it returns) returns an value
of type 'a. Parametricity allows us to infer from that that if t1 does
not contain 'a as a free type variable, then the function will necessarily
never return (since it has no way to construct an value of
type 'a).
It would maybe be a good idea to analyze the types based on a few
such parametricity-derived theorems and print a more meaningful type
(i.e. use 'noreturn rather than 'a for the above case or 'ignored
for an argument type 'a which appears only once).
Stefan
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: bottom types and threaded exits
2000-09-30 9:12 ` Julian Assange
@ 2000-09-30 14:25 ` Pierre Weis
2000-09-30 15:19 ` Markus Mottl
2000-09-30 14:28 ` Stefan Monnier
1 sibling, 1 reply; 13+ messages in thread
From: Pierre Weis @ 2000-09-30 14:25 UTC (permalink / raw)
To: Julian Assange; +Cc: caml-list
> Xavier Leroy <Xavier.Leroy@inria.fr> writes:
>
> > That's one way of putting it, but as Pierre Weis mentioned, fully
> > polymorphic types such as 'a appear naturally during type inference
> > for non-terminating expressions.
>
> Yes, I found that quite cool.
Ok, but note that there is nothing special in the compiler to do so:
it is a mere consequence of the Damas-Milner typing discipline.
> > Semantically, it is correct to assign type 'a to any expression that
> > never returns normally: there are no values of type 'a, but such
> > expressions never result in a value.
>
> It depends on what level of semantics you are looking at. As far as
> type proofing is concerned, 'a is correct. However at a higher level
> you can say `the function never returns so saying that it returns any
> type is incorrect'. The problem is that some functions that do return,
> return 'a. Ocaml's overloading of 'a, is much the same as lisps
> overloading of nil and C's overloading of 0 or void*. You might
> counter saying that 'a is defined in terms of type-unification, thus
> reading additional meaning into the type is bogus. But such a view
> denies the semantics of what is being typed. A computer language --
> one of the important semantics of which is that is capable of capable
> of generating functions that fail to return.
I think there is some misunderstanding here. The meaning of type
variables (those 'a) can be semantically quite different depending on
their binding status. This is not random stuff: it is based on
theoretical grounds, such as:
Theorem: There is no Caml value with type 'a (meaning for all 'a. 'a).
Theorem: If the target type of a function is a universally quantified
type variable that does not appear in the source type of the function,
then this function never returns: it fails to terminate or raises an
exception.
The converse property is false, since a function may loop without having
such a polymorphic type.
Examples: all of the following functions loop for ever; for some of
them this can be proved from the mere examination of their type, for
others it cannot.
# let rec f x = f x;;
val f : 'a -> 'b = <fun>
This 'b is free in the source type of f: f loops or fail.
# let rec g x = g (x + 1);;
val g : int -> 'a = <fun>
This 'a is free in the source type of g: g loops or fails.
# let rec h x = h x + 1;;
val h : 'a -> int = <fun>
This 'a is bound in the source type of h, we know that h is
polymorphic but we cannot conclude something about its termination.
# let rec i x = i (i x);;
val i : 'a -> 'a = <fun>
This 'a in the target type is bound in the source type: we cannot
conclude something about the termination of i from its type (although,
the code of i clearly fails to terminate).
# let rec j x = j (x + 1) + 1;;
val j : int -> int = <fun>
j has a regular type, we cannot conclude something about its
termination.
> `the function never returns so saying that it returns any
> type is incorrect'.
You mean for instance that the type of the preceding j function
(int -> int) is wrong since j is looping and never returns anything ?
Sorry, nobody can implement such a typing discipline due to the
well-know halting problem.
> The problem is that some functions that do return,
> return 'a.
Oversimplified and confusing. You confuse 'a type variables that are
bound in the source type of the function with 'a type variables that
are not. You should say ``some functions that do return, return 'a
that is bound into their source type'', and ``no functions that do
return, return an 'a that is unbound into their source type'' (this is
also a bit oversimplified, we should introduce the notion of positive
and negative occurrence of type variables...).
> Ocaml's overloading of 'a, is much the same as lisps
> overloading of nil and C's overloading of 0 or void*.
You should see now that there is no notion of overloading of type
variables in Caml. Nor any relationship with any nil NULL or void*
polymorphic default value.
> You might counter saying that 'a is defined in terms of
> type-unification, thus reading additional meaning into the type is
> bogus.
On the contrary, reading additional meaning into the type is a good
idea, I tried to give some simple examples in this message. But you
can use types for many more semantical properties (exceptions, safety
of programs, ...). Thus ``reading additional meaning into the type'' is
really a good idea.
> But such a view denies the semantics of what is being typed. A
> computer language -- one of the important semantics of which is that
> is capable of capable of generating functions that fail to return.
Absolutely, we do want to be able to define functions that fail to
return. That's why implementing a view such as: ``the type must tell
if the function may loop'' is hopeless, if you have general recursion in
the language. If you accept to abandon general recursion, you may
gain some much stronger typing disciplines (e.g. dependent types in
Coq) that gives you stronger properties of ``what is being types''.
> > Thread.exit should also have type unit -> 'a; the reason it currently
> > has type unit -> unit is due to the way it is implemented
> > (as Thread.kill(Thread.self())), but this is more of an historical
> > accident.
>
> I've used:
>
> let exit = Thread.exit (); assert false
>
> to get the required type. While clearly a hack, it's better to use a
> simple construct like this instead of having a casting to 'a
> mechanism. Although I find full-bown determinacy types, mercury style
> (but god forbid mercury heavy handed type syntax) quite appealing.
What do you want here:
- an exit function (then you must write let exit () = ...) ?
- or a value of type 'a (that you cannot have in Caml, as is well-known) ?
In the first case, why not using a recursive function, such as:
let rec exit () = Thread.exit (); exit ();;
val exit : unit -> 'a = <fun>
In the second case, you will not have it. You will write an expression
that fails to return the desired value!
> > Finally, concerning "while true do e done", there is only one typing
> > rule in the type-checker for "while p do e done", which assumes that
> > "p" may become false and the loop may thus terminate with the result
> > "()", hence the "unit" type.
>
> This is fair. I think an assert false at the end of the loop, or
>
> let bottom f = f (); assert false
> bottom (fun () -> while true do () done)
>
> is effective.
Once more I would prefer a more general recursive function, that would
loop for any (even non looping) function. For instance:
# let rec bottom f = f (); bottom f;;
val bottom : (unit -> 'a) -> 'b = <fun>
and I consider the 'b in the type of bottom as clearly indicating the
looping for ever nature of any application of the bottom function.
> Although, once again, it'd be nice to see a 'bottom rather
> than 'a type come out of this, even if the two are semantically equivalent
> in the eye of the type checker.
As you may know the type parameters in type schemes are bound at the
beginning of the type scheme (prenex quantification). Hence the names
of type parameters are irrelevant. Hence 'bottom -> 'bottom and 'a ->
'a are equivalent. Anyway, we can imagine to replace negative
occurrences of type parameters that do not appear in positive
position by names that you would prefer : 'bottom, 'bottom1, 'bottom2,
etc. I don't know if the extra implementation burden is worth the
little (subliminal) additional information.
Pierre Weis
INRIA, Projet Cristal, Pierre.Weis@inria.fr, http://cristal.inria.fr/~weis/
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: bottom types and threaded exits
2000-09-26 9:16 ` Xavier Leroy
@ 2000-09-30 9:12 ` Julian Assange
2000-09-30 14:25 ` Pierre Weis
2000-09-30 14:28 ` Stefan Monnier
0 siblings, 2 replies; 13+ messages in thread
From: Julian Assange @ 2000-09-30 9:12 UTC (permalink / raw)
To: Xavier Leroy; +Cc: caml-list, proff
Xavier Leroy <Xavier.Leroy@inria.fr> writes:
> That's one way of putting it, but as Pierre Weis mentioned, fully
> polymorphic types such as 'a appear naturally during type inference
> for non-terminating expressions.
Yes, I found that quite cool.
> Semantically, it is correct to assign type 'a to any expression that
> never returns normally: there are no values of type 'a, but such
> expressions never result in a value.
It depends on what level of semantics you are looking at. As far as
type proofing is concerned, 'a is correct. However at a higher level
you can say `the function never returns so saying that it returns any
type is incorrect'. The problem is that some functions that do return,
return 'a. Ocaml's overloading of 'a, is much the same as lisps
overloading of nil and C's overloading of 0 or void*. You might
counter saying that 'a is defined in terms of type-unification, thus
reading additional meaning into the type is bogus. But such a view
denies the semantics of what is being typed. A computer language --
one of the important semantics of which is that is capable of capable
of generating functions that fail to return.
> Thread.exit should also have type unit -> 'a; the reason it currently
> has type unit -> unit is due to the way it is implemented
> (as Thread.kill(Thread.self())), but this is more of an historical
> accident.
I've used:
let exit = Thread.exit (); assert false
to get the required type. While clearly a hack, it's better to use a
simple construct like this instead of having a casting to 'a
mechanism. Although I find full-bown determinacy types, mercury style
(but god forbid mercury heavy handed type syntax) quite appealing.
> Finally, concerning "while true do e done", there is only one typing
> rule in the type-checker for "while p do e done", which assumes that
> "p" may become false and the loop may thus terminate with the result
> "()", hence the "unit" type.
This is fair. I think an assert false at the end of the loop, or
let bottom f = f (); assert false
bottom (fun () -> while true do () done)
is effective. Although, once again, it'd be nice to see a 'bottom rather
than 'a type come out of this, even if the two are semantically equivalent
in the eye of the type checker.
Cheers,
Julian.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: bottom types and threaded exits
2000-09-23 14:25 Julian Assange
2000-09-24 19:14 ` Pierre Weis
2000-09-25 10:08 ` Remi VANICAT
@ 2000-09-26 9:16 ` Xavier Leroy
2000-09-30 9:12 ` Julian Assange
2 siblings, 1 reply; 13+ messages in thread
From: Xavier Leroy @ 2000-09-26 9:16 UTC (permalink / raw)
To: Julian Assange, caml-list
> Pervasives.exit is of type int -> 'a
> Here we see ocaml using 'a to represent _|_. This hack is presumably
> so type unification still works in the face of potentially
> non-terminating computations
That's one way of putting it, but as Pierre Weis mentioned, fully
polymorphic types such as 'a appear naturally during type inference
for non-terminating expressions.
The prime example is recursive functions with no bottom case (let rec
f x = f (x + 1)), but raising an exception (raise Exn) also has type 'a.
Semantically, it is correct to assign type 'a to any expression that
never returns normally: there are no values of type 'a, but such
expressions never result in a value.
By the same reasoning, since a call to Pervasives.exit never returns,
it is safe and indeed logical to give it type int -> 'a.
Thread.exit should also have type unit -> 'a; the reason it currently
has type unit -> unit is due to the way it is implemented
(as Thread.kill(Thread.self())), but this is more of an historical
accident.
Finally, concerning "while true do e done", there is only one typing
rule in the type-checker for "while p do e done", which assumes that
"p" may become false and the loop may thus terminate with the result
"()", hence the "unit" type.
It would be semantically sound to give "while true do e done" the type
'a, but it would require a special type-checking rule for the "while"
construct when the predicate is "true", which sounds a bit weird.
However, we already implemented such a special case for "assert false"
(type 'a) w.r.t. "assert cond" (type unit).
- Xavier Leroy
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: bottom types and threaded exits
2000-09-25 10:08 ` Remi VANICAT
@ 2000-09-25 18:38 ` John Prevost
0 siblings, 0 replies; 13+ messages in thread
From: John Prevost @ 2000-09-25 18:38 UTC (permalink / raw)
To: Remi VANICAT; +Cc: caml-list
>>>>> "rv" == Remi VANICAT <remi.vanicat@labri.u-bordeaux.fr> writes:
rv> Julian Assange <proff@iq.org> writes:
>> Pervasives.exit is of type int -> 'a
>>
>> Here we see ocaml using 'a to represent _|_. This hack is
>> presumably so type unification still works in the face of
>> potentially non-terminating computations, e.g:
>>
>> let f a = try f a with Failure _ -> exit(1)
>>
>> How can one force 'a? For instance, Thread.exit and
>>
>> let f () = while true do () done
>>
>> has a type of unit -> unit.
>>
>> One can write something such as
>>
>> let f () = while true do () done ; Pervasives.exit (1)
>>
>> But this is clearly a hack.
>From what I can tell, what you're trying to do here is just make the
result type of a non-terminating computation go to 'a. This is
actually quite easy--you just need to loop in a way that doesn't
constrain the type. while ... do ... done always returns unit (which
is good, since usually you use it in a way that terminates.
The appropriate way to do it that will get type 'a is (in your case):
let rec f () = f ()
Note that if you choose the more direct translation
let rec f () = if true then f ()
you get constrained to type unit -> unit again, since a one-branched
if returns unit for the else branch.
So, an example of a vaguely useful function would be:
let rec call_forever f x = f x; call_forever f x
which has type:
val call_forever : ('a -> 'b) -> 'a -> 'c
So, it is not so much that 'a as bottom is a hack, as that the system
only produces such types when the result type is totally
unconstrained--and that doesn't happen with things like while loops,
only with recursion--where a function always returns the result of
calling itself (or another such function.)
John.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: bottom types and threaded exits
2000-09-23 14:25 Julian Assange
2000-09-24 19:14 ` Pierre Weis
@ 2000-09-25 10:08 ` Remi VANICAT
2000-09-25 18:38 ` John Prevost
2000-09-26 9:16 ` Xavier Leroy
2 siblings, 1 reply; 13+ messages in thread
From: Remi VANICAT @ 2000-09-25 10:08 UTC (permalink / raw)
To: caml-list
Julian Assange <proff@iq.org> writes:
> Pervasives.exit is of type int -> 'a
>
> Here we see ocaml using 'a to represent _|_. This hack is presumably
> so type unification still works in the face of potentially
> non-terminating computations, e.g:
>
> let f a =
> try
> f a
> with
> Failure _ -> exit(1)
>
> How can one force 'a? For instance, Thread.exit and
>
> let f () = while true do () done
>
> has a type of unit -> unit.
>
> One can write something such as
>
> let f () = while true do () done ; Pervasives.exit (1)
>
> But this is clearly a hack.
i would use an execption :
exception Sould_never_be_here
let f () = while true do () done ; raise Sould_never_be_here
--
Rémi Vanicat
vanicat@labri.u-bordeaux.fr
http://dept-info.labri.u-bordeaux.fr/~vanicat
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: bottom types and threaded exits
2000-09-23 14:25 Julian Assange
@ 2000-09-24 19:14 ` Pierre Weis
2000-09-25 10:08 ` Remi VANICAT
2000-09-26 9:16 ` Xavier Leroy
2 siblings, 0 replies; 13+ messages in thread
From: Pierre Weis @ 2000-09-24 19:14 UTC (permalink / raw)
To: Julian Assange; +Cc: caml-list
[...]
> Trying to define a type of int -> 'a naturally leads
> to a compiler error of 'a being unbound.
What about:
# let rec loop x = loop (x + 1);;
val loop : int -> 'a = <fun>
This is a pretty convincing non-terminating computation, isn't it ?
Pierre Weis
INRIA, Projet Cristal, Pierre.Weis@inria.fr, http://cristal.inria.fr/~weis/
^ permalink raw reply [flat|nested] 13+ messages in thread
* bottom types and threaded exits
@ 2000-09-23 14:25 Julian Assange
2000-09-24 19:14 ` Pierre Weis
` (2 more replies)
0 siblings, 3 replies; 13+ messages in thread
From: Julian Assange @ 2000-09-23 14:25 UTC (permalink / raw)
To: caml-list; +Cc: proff
Pervasives.exit is of type int -> 'a
Here we see ocaml using 'a to represent _|_. This hack is presumably
so type unification still works in the face of potentially
non-terminating computations, e.g:
let f a =
try
f a
with
Failure _ -> exit(1)
How can one force 'a? For instance, Thread.exit and
let f () = while true do () done
has a type of unit -> unit.
One can write something such as
let f () = while true do () done ; Pervasives.exit (1)
But this is clearly a hack.
If the type of Pervasices.exit is traced back, it originates in the
`external affairs powers' of the ocaml type system and is thus not
prone to type inferment. Functions never normally cause an *increase*
in generality. Trying to define a type of int -> 'a naturally leads
to a compiler error of 'a being unbound.
Cheers,
Julian.
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2000-10-05 18:39 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-09-25 19:56 bottom types and threaded exits Damien Doligez
-- strict thread matches above, loose matches on Subject: below --
2000-09-23 14:25 Julian Assange
2000-09-24 19:14 ` Pierre Weis
2000-09-25 10:08 ` Remi VANICAT
2000-09-25 18:38 ` John Prevost
2000-09-26 9:16 ` Xavier Leroy
2000-09-30 9:12 ` Julian Assange
2000-09-30 14:25 ` Pierre Weis
2000-09-30 15:19 ` Markus Mottl
2000-09-30 14:28 ` Stefan Monnier
2000-10-02 13:11 ` Patrick M Doane
2000-10-02 16:28 ` Markus Mottl
2000-10-05 18:39 ` Pierre Weis
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox