From ketil+haskell at ii.uib.no Fri Feb 1 02:52:02 2008 From: ketil+haskell at ii.uib.no (Ketil Malde) Date: Fri Feb 1 02:51:28 2008 Subject: Proposal: Add concatMapM function (#2042) In-Reply-To: <1508723353.20080131161308@gmail.com> (Bulat Ziganshin's message of "Thu\, 31 Jan 2008 16\:13\:08 +0300") References: <478B90A4.4090807@gmail.com> <479F1801.20801@gmail.com> <404396ef0801290418v4755f9f3n1ddd175c3e56d66e@mail.gmail.com> <20080129175243.GA18863@scytale.galois.com> <479F6CBD.3090009@imn.htwk-leipzig.de> <259254796.20080129225150@gmail.com> <47A1ADEE.80407@gmail.com> <90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com> <1508723353.20080131161308@gmail.com> Message-ID: <87r6fxazbx.fsf@nmd9999.imr.no> Bulat Ziganshin writes: Bulat Ziganshin writes: > the right way to deal with [text encoding] "modifiers" is to attach > them to the Handle itself like this: > > f <- openFile "name" >>= withLocking >>= withEncoding utf8 This is nice! I think the Haskell Way of interpreting bytes as Latin-1 - while unfortunate in today's multi-everything environment - is something we just have to live with. Too much code expects this behavior, and too many tasks require just reading ASCII to be burdened with complications of locales and character sets. Attaching modifiers to handles appears to solve the problem of retaining 100% backwards compatibility, while opening for dealing with modern character sets. Somebody raised the question of reading a Content-type field, etc: would it be possible to "rewind" a handle after setting encoding? For Content-type fields, I suspect the header is usually limited to ASCII anyway, so adding decoding for subsequent text is probably sufficient. But how about a 'withDefaultEncoding' modifier that inspects the first two (or four?) bytes for a Unicode BOM, and either sets decoding accordingly and continues, or sets encoding according to locale *and* lets the user read the first bytes when reading from the handle. -k -- If I haven't seen further, it is by standing in the footprints of giants From rl at cse.unsw.edu.au Fri Feb 1 03:03:36 2008 From: rl at cse.unsw.edu.au (Roman Leshchinskiy) Date: Fri Feb 1 03:02:57 2008 Subject: Proposal: Add concatMapM function (#2042) In-Reply-To: <1508723353.20080131161308@gmail.com> References: <478B90A4.4090807@gmail.com> <479F1801.20801@gmail.com> <404396ef0801290418v4755f9f3n1ddd175c3e56d66e@mail.gmail.com> <20080129175243.GA18863@scytale.galois.com> <479F6CBD.3090009@imn.htwk-leipzig.de> <259254796.20080129225150@gmail.com> <47A1ADEE.80407@gmail.com> <90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com> <1508723353.20080131161308@gmail.com> Message-ID: <47A2D258.7050704@cse.unsw.edu.au> Bulat Ziganshin wrote: > > the right way to deal with "modifiers" is to attach them to the Handle > itself like this: > > f <- openFile "name" >>= withLocking >>= withEncoding utf8 IMO, global state is never "the right way" if it can be avoided. It will always lead to problems. Especially in a functional language like Haskell. Roman From johan.tibell at gmail.com Fri Feb 1 03:56:09 2008 From: johan.tibell at gmail.com (Johan Tibell) Date: Fri Feb 1 03:55:23 2008 Subject: Proposal: Add concatMapM function (#2042) In-Reply-To: <87r6fxazbx.fsf@nmd9999.imr.no> References: <478B90A4.4090807@gmail.com> <404396ef0801290418v4755f9f3n1ddd175c3e56d66e@mail.gmail.com> <20080129175243.GA18863@scytale.galois.com> <479F6CBD.3090009@imn.htwk-leipzig.de> <259254796.20080129225150@gmail.com> <47A1ADEE.80407@gmail.com> <90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com> <1508723353.20080131161308@gmail.com> <87r6fxazbx.fsf@nmd9999.imr.no> Message-ID: <90889fe70802010056n48f9250eo579137c0542a05d7@mail.gmail.com> > I think the Haskell Way of interpreting bytes as Latin-1 - while > unfortunate in today's multi-everything environment - is something we > just have to live with. Too much code expects this behavior, and too > many tasks require just reading ASCII to be burdened with > complications of locales and character sets. Why do we have to live with it? I understand why we ended up with the situation we have today. Most languages have/had the same problem. It's being fixed in other languages like Python. Not fixing it makes it a huge pain to deal with Strings from different sources (e.g. libraries) since you don't know if the content is Unicode code points (which String is defined as containing) or raw bytes because the programmer used the wrong type. > .... But how about a 'withDefaultEncoding' modifier that > inspects the first two (or four?) bytes for a Unicode BOM, and either > sets decoding accordingly and continues, or sets encoding according > to locale *and* lets the user read the first bytes when reading from > the handle. The BOM mark is not always present and is not enough to decide which encoding was used. You could invent and encoding of Unicode that doesn't use one. Some recommended reading (for everyone): http://www.joelonsoftware.com/articles/Unicode.html -- Johan From wnoise at ofb.net Fri Feb 1 04:01:24 2008 From: wnoise at ofb.net (Aaron Denney) Date: Fri Feb 1 04:00:56 2008 Subject: Proposal: Add concatMapM function (#2042) References: <478B90A4.4090807@gmail.com> <479F1801.20801@gmail.com> <404396ef0801290418v4755f9f3n1ddd175c3e56d66e@mail.gmail.com> <20080129175243.GA18863@scytale.galois.com> <479F6CBD.3090009@imn.htwk-leipzig.de> <259254796.20080129225150@gmail.com> <47A1ADEE.80407@gmail.com> <90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com> <1508723353.20080131161308@gmail.com> <47A2D258.7050704@cse.unsw.edu.au> Message-ID: On 2008-02-01, Roman Leshchinskiy wrote: > Bulat Ziganshin wrote: >> >> the right way to deal with "modifiers" is to attach them to the Handle >> itself like this: >> >> f <- openFile "name" >>= withLocking >>= withEncoding utf8 > > IMO, global state is never "the right way" if it can be avoided. It will > always lead to problems. Especially in a functional language like Haskell. This isn't global state, but local to the handle, and only affects where the handle is passed in. It's just extending an opaque data type. -- Aaron Denney -><- From Alistair_Bayley at invescoperpetual.co.uk Fri Feb 1 04:16:47 2008 From: Alistair_Bayley at invescoperpetual.co.uk (Bayley, Alistair) Date: Fri Feb 1 04:16:42 2008 Subject: Proposal: Add concatMapM function (#2042) In-Reply-To: <87r6fxazbx.fsf@nmd9999.imr.no> References: <478B90A4.4090807@gmail.com> <479F1801.20801@gmail.com><404396ef0801290418v4755f9f3n1ddd175c3e56d66e@mail.gmail.com><20080129175243.GA18863@scytale.galois.com><479F6CBD.3090009@imn.htwk-leipzig.de><259254796.20080129225150@gmail.com> <47A1ADEE.80407@gmail.com><90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com><1508723353.20080131161308@gmail.com> <87r6fxazbx.fsf@nmd9999.imr.no> Message-ID: <125EACD0CAE4D24ABDB4D148C4593DA9049E9277@GBLONXMB02.corp.amvescap.net> > From: libraries-bounces@haskell.org > [mailto:libraries-bounces@haskell.org] On Behalf Of Ketil Malde > > Somebody raised the question of reading a Content-type field, etc: > would it be possible to "rewind" a handle after setting encoding? For > Content-type fields, I suspect the header is usually limited to ASCII > anyway, so adding decoding for subsequent text is probably > sufficient. I think this is relevant: http://www.haskell.org/pipermail/haskell-cafe/2004-September/006801.html Alistair ***************************************************************** Confidentiality Note: The information contained in this message, and any attachments, may contain confidential and/or privileged material. It is intended solely for the person(s) or entity to which it is addressed. Any review, retransmission, dissemination, or taking of any action in reliance upon this information by persons or entities other than the intended recipient(s) is prohibited. If you received this in error, please contact the sender and delete the material from any computer. ***************************************************************** From rl at cse.unsw.edu.au Fri Feb 1 04:44:06 2008 From: rl at cse.unsw.edu.au (Roman Leshchinskiy) Date: Fri Feb 1 04:43:26 2008 Subject: Proposal: Add concatMapM function (#2042) In-Reply-To: References: <478B90A4.4090807@gmail.com> <479F1801.20801@gmail.com> <404396ef0801290418v4755f9f3n1ddd175c3e56d66e@mail.gmail.com> <20080129175243.GA18863@scytale.galois.com> <479F6CBD.3090009@imn.htwk-leipzig.de> <259254796.20080129225150@gmail.com> <47A1ADEE.80407@gmail.com> <90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com> <1508723353.20080131161308@gmail.com> <47A2D258.7050704@cse.unsw.edu.au> Message-ID: <47A2E9E6.6070208@cse.unsw.edu.au> Aaron Denney wrote: > On 2008-02-01, Roman Leshchinskiy wrote: >> Bulat Ziganshin wrote: >>> the right way to deal with "modifiers" is to attach them to the Handle >>> itself like this: >>> >>> f <- openFile "name" >>= withLocking >>= withEncoding utf8 >> IMO, global state is never "the right way" if it can be avoided. It will >> always lead to problems. Especially in a functional language like Haskell. > > This isn't global state, but local to the handle, and only affects where > the handle is passed in. It's just extending an opaque data type. If I can destructively change the encoding assocated with a Handle, then it's global state. Roman From simonmarhaskell at gmail.com Fri Feb 1 05:31:37 2008 From: simonmarhaskell at gmail.com (Simon Marlow) Date: Fri Feb 1 05:31:00 2008 Subject: Proposal: Add concatMapM function (#2042) In-Reply-To: <125EACD0CAE4D24ABDB4D148C4593DA9049E9277@GBLONXMB02.corp.amvescap.net> References: <478B90A4.4090807@gmail.com> <479F1801.20801@gmail.com><404396ef0801290418v4755f9f3n1ddd175c3e56d66e@mail.gmail.com><20080129175243.GA18863@scytale.galois.com><479F6CBD.3090009@imn.htwk-leipzig.de><259254796.20080129225150@gmail.com> <47A1ADEE.80407@gmail.com><90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com><1508723353.20080131161308@gmail.com> <87r6fxazbx.fsf@nmd9999.imr.no> <125EACD0CAE4D24ABDB4D148C4593DA9049E9277@GBLONXMB02.corp.amvescap.net> Message-ID: <47A2F509.9020706@gmail.com> Bayley, Alistair wrote: >> From: libraries-bounces@haskell.org >> [mailto:libraries-bounces@haskell.org] On Behalf Of Ketil Malde >> >> Somebody raised the question of reading a Content-type field, etc: >> would it be possible to "rewind" a handle after setting encoding? For >> Content-type fields, I suspect the header is usually limited to ASCII >> anyway, so adding decoding for subsequent text is probably >> sufficient. > > > I think this is relevant: > > http://www.haskell.org/pipermail/haskell-cafe/2004-September/006801.html We've talked a lot in the past about a stream-layering IO abstraction. I'd forgotten about Oleg's post, thanks. Here are some others. There's the prototype I worked on: http://www.haskell.org/~simonmar/io/System.IO.html There's Bulat's Stream library, which is pretty complete: http://haskell.org/haskellwiki/Library/Streams And Takano Akio's version, in which he divides the type classes into smaller pieces. This is closer to the direction I thought we should go: http://yogimo.sakura.ne.jp/ssc/ Right now though, I'm not sure all this is going in the right direction. Dealing with all those mutable buffers is quite a headache (for the library writer, not the user), and lazy bytestrings have shown us that there are simpler ways to get good I/O performance. What's more, as Duncan Coutts has pointed out to me on more than one occasion, it's much easier to layer streams when the streams are lazy lists. As much as I hate to say it, there's a lot to be said for lazy I/O in this respect. However, lazy I/O has other problems - deterministically catching errors, unpredictable resource usage, unpredictable interaction with other I/O, and so on. Is there a nice solution? Something else we might look at is Oleg's left folds: http://okmij.org/ftp/Haskell/#fold-stream http://www.haskell.org/pipermail/haskell/2003-September/012741.html Cheers, Simon From bulat.ziganshin at gmail.com Fri Feb 1 05:34:28 2008 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Fri Feb 1 05:34:56 2008 Subject: Proposal: Add concatMapM function (#2042) In-Reply-To: <47A2D258.7050704@cse.unsw.edu.au> References: <478B90A4.4090807@gmail.com> <479F1801.20801@gmail.com> <404396ef0801290418v4755f9f3n1ddd175c3e56d66e@mail.gmail.com> <20080129175243.GA18863@scytale.galois.com> <479F6CBD.3090009@imn.htwk-leipzig.de> <259254796.20080129225150@gmail.com> <47A1ADEE.80407@gmail.com> <90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com> <1508723353.20080131161308@gmail.com> <47A2D258.7050704@cse.unsw.edu.au> Message-ID: <4410520824.20080201133428@gmail.com> Hello Roman, Friday, February 1, 2008, 11:03:36 AM, you wrote: >> the right way to deal with "modifiers" is to attach them to the Handle >> itself like this: >> >> f <- openFile "name" >>= withLocking >>= withEncoding utf8 > IMO, global state is never "the right way" if it can be avoided. It will > always lead to problems. Especially in a functional language like Haskell. so you propose something like this: s <- readString "/path/filename" TextMode "utf8" line_num ? :) please read http://haskell.org/haskellwiki/Library/Streams - it's not what you have imagined reading this example -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From simonmarhaskell at gmail.com Fri Feb 1 05:46:33 2008 From: simonmarhaskell at gmail.com (Simon Marlow) Date: Fri Feb 1 05:45:51 2008 Subject: Proposal: Add concatMapM function (#2042) In-Reply-To: <47A2F509.9020706@gmail.com> References: <478B90A4.4090807@gmail.com> <479F1801.20801@gmail.com><404396ef0801290418v4755f9f3n1ddd175c3e56d66e@mail.gmail.com><20080129175243.GA18863@scytale.galois.com><479F6CBD.3090009@imn.htwk-leipzig.de><259254796.20080129225150@gmail.com> <47A1ADEE.80407@gmail.com><90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com><1508723353.20080131161308@gmail.com> <87r6fxazbx.fsf@nmd9999.imr.no> <125EACD0CAE4D24ABDB4D148C4593DA9049E9277@GBLONXMB02.corp.amvescap.net> <47A2F509.9020706@gmail.com> Message-ID: <47A2F889.7000107@gmail.com> Simon Marlow wrote: > Bayley, Alistair wrote: >>> From: libraries-bounces@haskell.org >>> [mailto:libraries-bounces@haskell.org] On Behalf Of Ketil Malde >>> >>> Somebody raised the question of reading a Content-type field, etc: >>> would it be possible to "rewind" a handle after setting encoding? For >>> Content-type fields, I suspect the header is usually limited to ASCII >>> anyway, so adding decoding for subsequent text is probably >>> sufficient. >> >> >> I think this is relevant: >> >> http://www.haskell.org/pipermail/haskell-cafe/2004-September/006801.html > > We've talked a lot in the past about a stream-layering IO abstraction. > I'd forgotten about Oleg's post, thanks. > > Here are some others. There's the prototype I worked on: > > http://www.haskell.org/~simonmar/io/System.IO.html > > There's Bulat's Stream library, which is pretty complete: > > http://haskell.org/haskellwiki/Library/Streams > > And Takano Akio's version, in which he divides the type classes into > smaller pieces. This is closer to the direction I thought we should go: > > http://yogimo.sakura.ne.jp/ssc/ I should also mention John Goerzen's HVIO library: http://hackage.haskell.org/packages/archive/MissingH/1.0.0/doc/html/System-IO-HVIO.html Cheers, Simon From johan.tibell at gmail.com Fri Feb 1 06:08:26 2008 From: johan.tibell at gmail.com (Johan Tibell) Date: Fri Feb 1 06:07:41 2008 Subject: Proposal: Add concatMapM function (#2042) In-Reply-To: <47A2F509.9020706@gmail.com> References: <478B90A4.4090807@gmail.com> <479F6CBD.3090009@imn.htwk-leipzig.de> <259254796.20080129225150@gmail.com> <47A1ADEE.80407@gmail.com> <90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com> <1508723353.20080131161308@gmail.com> <87r6fxazbx.fsf@nmd9999.imr.no> <125EACD0CAE4D24ABDB4D148C4593DA9049E9277@GBLONXMB02.corp.amvescap.net> <47A2F509.9020706@gmail.com> Message-ID: <90889fe70802010308i1a906087q3d3106197e877456@mail.gmail.com> > Right now though, I'm not sure all this is going in the right direction. > Dealing with all those mutable buffers is quite a headache (for the library > writer, not the user), and lazy bytestrings have shown us that there are > simpler ways to get good I/O performance. What's more, as Duncan Coutts > has pointed out to me on more than one occasion, it's much easier to layer > streams when the streams are lazy lists. As much as I hate to say it, > there's a lot to be said for lazy I/O in this respect. However, lazy I/O > has other problems - deterministically catching errors, unpredictable > resource usage, unpredictable interaction with other I/O, and so on. Is > there a nice solution? Something else we might look at is Oleg's left folds: > > http://okmij.org/ftp/Haskell/#fold-stream > http://www.haskell.org/pipermail/haskell/2003-September/012741.html I initially used lazy I/O with lazy bytestrings in my web server but I'm changing that behvior to use left folds instead precisely because of the reasons you (and Oleg) mentioned. Unfortunately, that means I need a incremental Parsec for bytestrings (I think) so there's yet another library to write. Oh well. :) -- Johan From bulat.ziganshin at gmail.com Fri Feb 1 06:02:25 2008 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Fri Feb 1 06:27:11 2008 Subject: Proposal: Add concatMapM function (#2042) In-Reply-To: <47A2F509.9020706@gmail.com> References: <478B90A4.4090807@gmail.com> <479F1801.20801@gmail.com><404396ef0801290418v4755f9f3n1ddd175c3e56d66e@mail.gmail.com><20080129175243.GA18863@scytale.galois.com><479F6CBD.3090009@imn.htwk-leipzig.de><259254796.20080129225150@gmail.com> <47A1ADEE.80407@gmail.com><90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com><1508723353.20080131161308@gmail.com> <87r6fxazbx.fsf@nmd9999.imr.no> <125EACD0CAE4D24ABDB4D148C4593DA9049E9277@GBLONXMB02.corp.amvescap.net> <47A2F509.9020706@gmail.com> Message-ID: <18410652986.20080201140225@gmail.com> Hello Simon, Friday, February 1, 2008, 1:31:37 PM, you wrote: > Right now though, I'm not sure all this is going in the right direction. > Dealing with all those mutable buffers is quite a headache (for the library > writer, not the user), and lazy bytestrings have shown us that there are > simpler ways to get good I/O performance. What's more, as Duncan Coutts > has pointed out to me on more than one occasion, it's much easier to layer > streams when the streams are lazy lists. As much as I hate to say it, > there's a lot to be said for lazy I/O in this respect. However, lazy I/O > has other problems - deterministically catching errors, unpredictable > resource usage, unpredictable interaction with other I/O, and so on. also add lack of multithreading/locking support and questionable interaction with C libs. i still think that the proper solution is to provide imperative i/o library as the basis and build lazy bytestring one on the top of it. most users will use high-level library unfortunately, BS and Streams libs were never integrated together -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From bulat.ziganshin at gmail.com Fri Feb 1 06:11:00 2008 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Fri Feb 1 06:27:22 2008 Subject: Proposal: Add concatMapM function (#2042) In-Reply-To: <90889fe70802010056n48f9250eo579137c0542a05d7@mail.gmail.com> References: <478B90A4.4090807@gmail.com> <404396ef0801290418v4755f9f3n1ddd175c3e56d66e@mail.gmail.com> <20080129175243.GA18863@scytale.galois.com> <479F6CBD.3090009@imn.htwk-leipzig.de> <259254796.20080129225150@gmail.com> <47A1ADEE.80407@gmail.com> <90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com> <1508723353.20080131161308@gmail.com> <87r6fxazbx.fsf@nmd9999.imr.no> <90889fe70802010056n48f9250eo579137c0542a05d7@mail.gmail.com> Message-ID: <19210299389.20080201141100@gmail.com> Hello Johan, Friday, February 1, 2008, 11:56:09 AM, you wrote: >> I think the Haskell Way of interpreting bytes as Latin-1 - while >> unfortunate in today's multi-everything environment - is something we >> just have to live with. Too much code expects this behavior, and too >> many tasks require just reading ASCII to be burdened with >> complications of locales and character sets. > Why do we have to live with it? I understand why we ended up with the > situation we have today. Most languages have/had the same problem. the problem is just over-complication of existing Handle implementation - it's about 2kloc of high-messed code. taking into account that it lacks a lot of other required features, it's quite meaningless to spend a lot of time fixing it for just one particular problem i've implemented 2 versions of Streams library which includes everything i know about i/o (i.e. no networking, overlapped i/o or iconv) and started to implement its 3rd version which includes bytestring i/o but then switched to more interesting project. Streams is still the most complete haskell i/o library and quite useful. its main drawback is lack of docs, especially for second version, but to some degree you can understand it just by analogy with System.IO interfaces -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From bulat.ziganshin at gmail.com Fri Feb 1 06:25:52 2008 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Fri Feb 1 06:27:32 2008 Subject: Proposal: Add concatMapM function (#2042) In-Reply-To: <87r6fxazbx.fsf@nmd9999.imr.no> References: <478B90A4.4090807@gmail.com> <479F1801.20801@gmail.com> <404396ef0801290418v4755f9f3n1ddd175c3e56d66e@mail.gmail.com> <20080129175243.GA18863@scytale.galois.com> <479F6CBD.3090009@imn.htwk-leipzig.de> <259254796.20080129225150@gmail.com> <47A1ADEE.80407@gmail.com> <90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com> <1508723353.20080131161308@gmail.com> <87r6fxazbx.fsf@nmd9999.imr.no> Message-ID: <428207430.20080201142552@gmail.com> Hello Ketil, Friday, February 1, 2008, 10:52:02 AM, you wrote: >> f <- openFile "name" >>= withLocking >>= withEncoding utf8 > Attaching modifiers to handles appears to solve the problem of > retaining 100% backwards compatibility, while opening for dealing with > modern character sets. may be it's too draconian restriction but i proposed just to use new library in the new code. we can provide easy way to switch from Handles by providing emulation module System.Stream.IO which exports things with the old names - Handle, hGetContents... - but new implementation > Somebody raised the question of reading a Content-type field, etc: > would it be possible to "rewind" a handle after setting encoding? For > Content-type fields, I suspect the header is usually limited to ASCII > anyway, so adding decoding for subsequent text is probably > sufficient. But how about a 'withDefaultEncoding' modifier that > inspects the first two (or four?) bytes for a Unicode BOM, and either > sets decoding accordingly and continues, or sets encoding according > to locale *and* lets the user read the first bytes when reading from > the handle. core of my library is *interfaces*, not implementations. openFile provides a getByte/putByte interfaces and also trivial getChar/putChar which just reads/writes one byte. withEncoding modifier provides another getChar/putChar implementations what process several bytes at once. you can dress file to one or another modifier at any moment, its internal read/write pointer isn't affected: f <- openFile "name" content <- readLine f -- read first line using Latin-1 f' <- withEncoding (lookup content) f str <- readLine f' -- read second line using encoding given on first line -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From bulat.ziganshin at gmail.com Fri Feb 1 06:30:56 2008 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Fri Feb 1 06:31:25 2008 Subject: Proposal: Add concatMapM function (#2042) In-Reply-To: <47A2F889.7000107@gmail.com> References: <478B90A4.4090807@gmail.com> <479F1801.20801@gmail.com><404396ef0801290418v4755f9f3n1ddd175c3e56d66e@mail.gmail.com><20080129175243.GA18863@scytale.galois.com><479F6CBD.3090009@imn.htwk-leipzig.de><259254796.20080129225150@gmail.com> <47A1ADEE.80407@gmail.com><90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com><1508723353.20080131161308@gmail.com> <87r6fxazbx.fsf@nmd9999.imr.no> <125EACD0CAE4D24ABDB4D148C4593DA9049E9277@GBLONXMB02.corp.amvescap.net> <47A2F509.9020706@gmail.com> <47A2F889.7000107@gmail.com> Message-ID: <153911645.20080201143056@gmail.com> Hello Simon, Friday, February 1, 2008, 1:46:33 PM, you wrote: >> We've talked a lot in the past about a stream-layering IO abstraction. >> There's Bulat's Stream library, which is pretty complete: >> >> http://haskell.org/haskellwiki/Library/Streams >> >> And Takano Akio's version, in which he divides the type classes into >> smaller pieces. This is closer to the direction I thought we should go: >> >> http://yogimo.sakura.ne.jp/ssc/ > I should also mention John Goerzen's HVIO library: > http://hackage.haskell.org/packages/archive/MissingH/1.0.0/doc/html/System-IO-HVIO.html to clear up things, HVIO was a basis for Streams, and Streams was a basis for SSC -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From ketil+haskell at ii.uib.no Fri Feb 1 08:29:02 2008 From: ketil+haskell at ii.uib.no (Ketil Malde) Date: Fri Feb 1 08:28:27 2008 Subject: Proposal: Add concatMapM function (#2042) In-Reply-To: <428207430.20080201142552@gmail.com> (Bulat Ziganshin's message of "Fri\, 1 Feb 2008 14\:25\:52 +0300") References: <478B90A4.4090807@gmail.com> <479F1801.20801@gmail.com> <404396ef0801290418v4755f9f3n1ddd175c3e56d66e@mail.gmail.com> <20080129175243.GA18863@scytale.galois.com> <479F6CBD.3090009@imn.htwk-leipzig.de> <259254796.20080129225150@gmail.com> <47A1ADEE.80407@gmail.com> <90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com> <1508723353.20080131161308@gmail.com> <87r6fxazbx.fsf@nmd9999.imr.no> <428207430.20080201142552@gmail.com> Message-ID: <87hcgsajq9.fsf@nmd9999.imr.no> Bulat Ziganshin writes: > may be it's too draconian restriction but i proposed just to use new > library in the new code. For backwards compatibility, I agree it would be preferable to retain the current default implementation, but opinions appear to differ. Whatever. > f <- openFile "name" > content <- readLine f -- read first line using Latin-1 > f' <- withEncoding (lookup content) f > str <- readLine f' -- read second line using encoding given on first line This is clear enough, but for the BOM-dependent decoding, you may have to do the equivalent of having the next call to 'readLine' re-read the first line instead. -k -- If I haven't seen further, it is by standing in the footprints of giants From rl at cse.unsw.edu.au Fri Feb 1 08:30:14 2008 From: rl at cse.unsw.edu.au (Roman Leshchinskiy) Date: Fri Feb 1 08:29:34 2008 Subject: Proposal: Add concatMapM function (#2042) In-Reply-To: <4410520824.20080201133428@gmail.com> References: <478B90A4.4090807@gmail.com> <479F1801.20801@gmail.com> <404396ef0801290418v4755f9f3n1ddd175c3e56d66e@mail.gmail.com> <20080129175243.GA18863@scytale.galois.com> <479F6CBD.3090009@imn.htwk-leipzig.de> <259254796.20080129225150@gmail.com> <47A1ADEE.80407@gmail.com> <90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com> <1508723353.20080131161308@gmail.com> <47A2D258.7050704@cse.unsw.edu.au> <4410520824.20080201133428@gmail.com> Message-ID: <47A31EE6.9080409@cse.unsw.edu.au> Bulat Ziganshin wrote: > Hello Roman, > > Friday, February 1, 2008, 11:03:36 AM, you wrote: > >>> the right way to deal with "modifiers" is to attach them to the Handle >>> itself like this: >>> >>> f <- openFile "name" >>= withLocking >>= withEncoding utf8 > >> IMO, global state is never "the right way" if it can be avoided. It will >> always lead to problems. Especially in a functional language like Haskell. > > so you propose something like this: > > s <- readString "/path/filename" TextMode "utf8" line_num No. In my view, file handles and encodings exist on completely different levels of abstraction. The former are (or ought to be) simply an interface to the underlying OS capabilities. The latter would be part of a high-level I/O library which shouldn't even have the concept of a handle (and should use typed I/O). Also, it doesn't always make sense to associate an encoding with an entire file. For instance, a Russian-Greek dictionary might use ISO 8859-5 for Russian words and ISO 8859-7 for Greek ones. Roman From lemming at henning-thielemann.de Fri Feb 1 09:07:44 2008 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Fri Feb 1 09:06:57 2008 Subject: Proposal: Add concatMapM function (#2042) In-Reply-To: <47A31EE6.9080409@cse.unsw.edu.au> References: <478B90A4.4090807@gmail.com> <479F1801.20801@gmail.com> <404396ef0801290418v4755f9f3n1ddd175c3e56d66e@mail.gmail.com> <20080129175243.GA18863@scytale.galois.com> <479F6CBD.3090009@imn.htwk-leipzig.de> <259254796.20080129225150@gmail.com> <47A1ADEE.80407@gmail.com> <90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com> <1508723353.20080131161308@gmail.com> <47A2D258.7050704@cse.unsw.edu.au> <4410520824.20080201133428@gmail.com> <47A31EE6.9080409@cse.unsw.edu.au> Message-ID: On Sat, 2 Feb 2008, Roman Leshchinskiy wrote: > Bulat Ziganshin wrote: > > Hello Roman, > > > > Friday, February 1, 2008, 11:03:36 AM, you wrote: > > > >>> the right way to deal with "modifiers" is to attach them to the Handle > >>> itself like this: > >>> > >>> f <- openFile "name" >>= withLocking >>= withEncoding utf8 > > > >> IMO, global state is never "the right way" if it can be avoided. It will > >> always lead to problems. Especially in a functional language like Haskell. > > > > so you propose something like this: > > > > s <- readString "/path/filename" TextMode "utf8" line_num > > No. In my view, file handles and encodings exist on completely different > levels of abstraction. What about changing the subject in order to preserve the thread for further contributions to the concatMapM issue? From bulat.ziganshin at gmail.com Fri Feb 1 09:36:54 2008 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Fri Feb 1 11:10:32 2008 Subject: i/o encodings In-Reply-To: <87hcgsajq9.fsf@nmd9999.imr.no> References: <478B90A4.4090807@gmail.com> <479F1801.20801@gmail.com> <404396ef0801290418v4755f9f3n1ddd175c3e56d66e@mail.gmail.com> <20080129175243.GA18863@scytale.galois.com> <479F6CBD.3090009@imn.htwk-leipzig.de> <259254796.20080129225150@gmail.com> <47A1ADEE.80407@gmail.com> <90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com> <1508723353.20080131161308@gmail.com> <87r6fxazbx.fsf@nmd9999.imr.no> <428207430.20080201142552@gmail.com> <87hcgsajq9.fsf@nmd9999.imr.no> Message-ID: <1707666901.20080201173654@gmail.com> Hello Ketil, Friday, February 1, 2008, 4:29:02 PM, you wrote: >> may be it's too draconian restriction but i proposed just to use new >> library in the new code. > For backwards compatibility, I agree it would be preferable to retain > the current default implementation, but opinions appear to differ. > Whatever. the problem is not abstract "backward compatibility" but programs that switches from the old lib to the new one. they should get exactly the old services for old names - in order to not rewrite program new programs what need new behavior just need to import new interface which may provide UTF-8 encoding for text files by default >> f <- openFile "name" >> content <- readLine f -- read first line using Latin-1 >> f' <- withEncoding (lookup content) f >> str <- readLine f' -- read second line using encoding given on first line > This is clear enough, but for the BOM-dependent decoding, you may have > to do the equivalent of having the next call to 'readLine' re-read the > first line instead. it's not a problem - file pointer is retained in f and f' just interprets the bytes it read: f <- openFile "name" bom <- readBytes 4 f -- read first 4 bytes vRewind f f' <- withEncoding (lookup bom) f str <- readLine f' -- read first line using BOM encoding -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From bos at serpentine.com Fri Feb 1 12:30:53 2008 From: bos at serpentine.com (Bryan O'Sullivan) Date: Fri Feb 1 12:30:07 2008 Subject: Proposal: Add concatMapM function (#2042) In-Reply-To: <87r6fxazbx.fsf@nmd9999.imr.no> References: <478B90A4.4090807@gmail.com> <479F1801.20801@gmail.com> <404396ef0801290418v4755f9f3n1ddd175c3e56d66e@mail.gmail.com> <20080129175243.GA18863@scytale.galois.com> <479F6CBD.3090009@imn.htwk-leipzig.de> <259254796.20080129225150@gmail.com> <47A1ADEE.80407@gmail.com> <90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com> <1508723353.20080131161308@gmail.com> <87r6fxazbx.fsf@nmd9999.imr.no> Message-ID: <47A3574D.2060103@serpentine.com> Ketil Malde wrote: > But how about a 'withDefaultEncoding' modifier that > inspects the first two (or four?) bytes for a Unicode BOM, and either > sets decoding accordingly and continues, or sets encoding according > to locale *and* lets the user read the first bytes when reading from > the handle. I really don't like the idea of gluing notions of encoding and decoding to Handles, because Handles are so limited in their usefulness. Even something as simple as reading an encrypted file defeats this approach. Never mind stream sockets, datagram sockets, memory mapped files, or any of a dozen other ways of getting data that will have an encoding. References: <478B90A4.4090807@gmail.com> <479F6CBD.3090009@imn.htwk-leipzig.de> <259254796.20080129225150@gmail.com> <47A1ADEE.80407@gmail.com> <90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com> <1508723353.20080131161308@gmail.com> <87r6fxazbx.fsf@nmd9999.imr.no> <125EACD0CAE4D24ABDB4D148C4593DA9049E9277@GBLONXMB02.corp.amvescap.net> <47A2F509.9020706@gmail.com> <90889fe70802010308i1a906087q3d3106197e877456@mail.gmail.com> Message-ID: <47A35856.8050106@serpentine.com> Johan Tibell wrote: > I initially used lazy I/O with lazy bytestrings in my web server but > I'm changing that behvior to use left folds instead precisely because > of the reasons you (and Oleg) mentioned. Unfortunately, that means I > need a incremental Parsec for bytestrings (I think) so there's yet > another library to write. It wouldn't be hard to take bytestringparser and perform the same transformation on it as Adam Langley did with his IncrementalGet parser for strict-binary. I've been skipping it due to lack of time, but it's an obviously right thing to do. <479F1801.20801@gmail.com> <404396ef0801290418v4755f9f3n1ddd175c3e56d66e@mail.gmail.com> <20080129175243.GA18863@scytale.galois.com> <479F6CBD.3090009@imn.htwk-leipzig.de> <259254796.20080129225150@gmail.com> <47A1ADEE.80407@gmail.com> <90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com> <1508723353.20080131161308@gmail.com> <47A2D258.7050704@cse.unsw.edu.au> <47A2E9E6.6070208@cse.unsw.edu.au> Message-ID: On 2008-02-01, Roman Leshchinskiy wrote: > Aaron Denney wrote: >> On 2008-02-01, Roman Leshchinskiy wrote: >>> Bulat Ziganshin wrote: >>>> the right way to deal with "modifiers" is to attach them to the Handle >>>> itself like this: >>>> >>>> f <- openFile "name" >>= withLocking >>= withEncoding utf8 >>> IMO, global state is never "the right way" if it can be avoided. It will >>> always lead to problems. Especially in a functional language like Haskell. >> >> This isn't global state, but local to the handle, and only affects where >> the handle is passed in. It's just extending an opaque data type. > > If I can destructively change the encoding assocated with a Handle, then > it's global state. Right. But the example given doesn't necessarily have that. x <- [5, 6] >>= (return .) (+ 1) No modification is going on, but return of new values. I don't know how Bulat's stream library is implemented, but I expected a new handle wrapping the old to be returned. -- Aaron Denney -><- From agl at imperialviolet.org Fri Feb 1 20:06:55 2008 From: agl at imperialviolet.org (Adam Langley) Date: Fri Feb 1 20:06:07 2008 Subject: Incremental parsing and left folds In-Reply-To: <47A35856.8050106@serpentine.com> References: <478B90A4.4090807@gmail.com> <259254796.20080129225150@gmail.com> <47A1ADEE.80407@gmail.com> <90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com> <1508723353.20080131161308@gmail.com> <87r6fxazbx.fsf@nmd9999.imr.no> <125EACD0CAE4D24ABDB4D148C4593DA9049E9277@GBLONXMB02.corp.amvescap.net> <47A2F509.9020706@gmail.com> <90889fe70802010308i1a906087q3d3106197e877456@mail.gmail.com> <47A35856.8050106@serpentine.com> Message-ID: <396556a20802011706qecf6842we792616bd067dd4c@mail.gmail.com> On Feb 1, 2008 9:35 AM, Bryan O'Sullivan wrote: > It wouldn't be hard to take bytestringparser and perform the same > transformation on it as Adam Langley did with his IncrementalGet parser > for strict-binary. I've been skipping it due to lack of time, but it's > an obviously right thing to do. I think the hurdle here would be that you can't easily rollback the state. Normally, in a parser one can just take the current state and revert to that if a parsing path fails. However, in an incremental parser, of the style of IncrementalGet, rolling back the state would mean that the additional data which has been supplied to the parser, via continuations, will be lost and needs to be resupplied. That's a non-solution because the caller shouldn't need to know anything about the internals of the parser. I think one could get around this by having a couple of states, the latter being a list of all the additional ByteStrings that the parser has received. Then, after having prospectively failed a certain parse path, the failure must include the list of additional data, which can be merged into the new state for the next prospective path. This failure value must be internal and, at the top level, translated into a more user-friendly failure. Unless something special is done, this also means that the incremental parser couldn't walk over huge streams of data, because it would still be holding all the input in case it gets reverted. Of course, the top level cannot be reverted, so maybe it's worth special casing this. AGL -- Adam Langley agl@imperialviolet.org http://www.imperialviolet.org 650-283-9641 From david at loisch.de Sat Feb 2 06:41:44 2008 From: david at loisch.de (David Leuschner) Date: Sat Feb 2 06:40:55 2008 Subject: darcs patch: Figure out timezone offset from timezone name Message-ID: Sat Feb 2 12:33:17 CET 2008 David Leuschner * Figure out timezone offset from timezone name -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: text/x-darcs-patch Size: 10435 bytes Desc: A darcs patch for your repository! Url : http://www.haskell.org/pipermail/libraries/attachments/20080202/e14f4820/attachment.bin From johan.tibell at gmail.com Sat Feb 2 13:34:18 2008 From: johan.tibell at gmail.com (Johan Tibell) Date: Sat Feb 2 13:33:29 2008 Subject: i/o encodings In-Reply-To: <1707666901.20080201173654@gmail.com> References: <478B90A4.4090807@gmail.com> <259254796.20080129225150@gmail.com> <47A1ADEE.80407@gmail.com> <90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com> <1508723353.20080131161308@gmail.com> <87r6fxazbx.fsf@nmd9999.imr.no> <428207430.20080201142552@gmail.com> <87hcgsajq9.fsf@nmd9999.imr.no> <1707666901.20080201173654@gmail.com> Message-ID: <90889fe70802021034k33b60fe4rb614196de02d55b0@mail.gmail.com> On Feb 1, 2008 3:36 PM, Bulat Ziganshin wrote: > Hello Ketil, > > Friday, February 1, 2008, 4:29:02 PM, you wrote: > > >> may be it's too draconian restriction but i proposed just to use new > >> library in the new code. > > > For backwards compatibility, I agree it would be preferable to retain > > the current default implementation, but opinions appear to differ. > > Whatever. > > the problem is not abstract "backward compatibility" but programs that > switches from the old lib to the new one. they should get exactly the > old services for old names - in order to not rewrite program Couldn't we handle backward compability by having say a 1.x line and a 2.x line of a library and push fixes to both? I'm afraid that libraries will turn into a mess eventually if they must support all old software in new versions. -- Johan From alexander.dunlap at gmail.com Sat Feb 2 13:35:19 2008 From: alexander.dunlap at gmail.com (Alexander Dunlap) Date: Sat Feb 2 13:34:35 2008 Subject: Readline read_history and write_history addition In-Reply-To: <2608b8a80801230519v72388283xf35f1de120571ca2@mail.gmail.com> References: <57526e770801182310r2e44c662wd513465d71e67bda@mail.gmail.com> <57526e770801191543u71ad5c52r2edd09387c8fe870@mail.gmail.com> <6d74b0d20801211027v621580b2k6584eb3b24bf8320@mail.gmail.com> <57526e770801212034g790f1671p38d47b681bd687bb@mail.gmail.com> <20080122221326.GA20619@matrix.chaos.earth.li> <2608b8a80801221549k41b193cq303a3847f98554e1@mail.gmail.com> <20080123005111.GA25334@matrix.chaos.earth.li> <2608b8a80801230435u6a18fb7bh1046cc446120d75@mail.gmail.com> <20080123125724.GA2912@matrix.chaos.earth.li> <2608b8a80801230519v72388283xf35f1de120571ca2@mail.gmail.com> Message-ID: <57526e770802021035u170e47cey77edea12eaa5c340@mail.gmail.com> On Jan 23, 2008 5:19 AM, Yitzchak Gale wrote: > > > Those are asynchronous phenomena. > > > I'm not sure what you mean by that? > > It's a synchronous exception. > > Sorry. I meant external. In the following sense: > > The semantics of the program explicitly involve > it in a larger external system, in a way that it > might make sense to allow exceptions to propagate > out to the external system. > > With readline history, it is clear that we must handle > all conditions internally, so this condition is not met. > Since E1-3 are also not met, we should not throw > IO exceptions. > > -Yitz > The deadline for comments has passed and it seems like there isn't any opposition to adding this to the library. The only thing that remains is to make a decision on the exceptions vs. IO Bool thing. It seems like most are in favor of throwing an exception. For instances where an exception would be too intrusive, I don't see how it would be too hard to write a wrapper function that would have exactly the same monad requirements as the original function but return an IO Bool instead of an error, e.g. > tryReadHistory = catch readHistory (\e -> ... So where do we go from here? Alex From gale at sefer.org Sat Feb 2 14:30:28 2008 From: gale at sefer.org (Yitzchak Gale) Date: Sat Feb 2 14:29:39 2008 Subject: Readline read_history and write_history addition In-Reply-To: <57526e770802021035u170e47cey77edea12eaa5c340@mail.gmail.com> References: <57526e770801182310r2e44c662wd513465d71e67bda@mail.gmail.com> <6d74b0d20801211027v621580b2k6584eb3b24bf8320@mail.gmail.com> <57526e770801212034g790f1671p38d47b681bd687bb@mail.gmail.com> <20080122221326.GA20619@matrix.chaos.earth.li> <2608b8a80801221549k41b193cq303a3847f98554e1@mail.gmail.com> <20080123005111.GA25334@matrix.chaos.earth.li> <2608b8a80801230435u6a18fb7bh1046cc446120d75@mail.gmail.com> <20080123125724.GA2912@matrix.chaos.earth.li> <2608b8a80801230519v72388283xf35f1de120571ca2@mail.gmail.com> <57526e770802021035u170e47cey77edea12eaa5c340@mail.gmail.com> Message-ID: <2608b8a80802021130i2b4486c3m74bc6ef7fdd2c425@mail.gmail.com> Alexander Dunlap wrote: > For instances where an exception would be too intrusive, I don't see > how it would be too hard to write a wrapper function In a library that does not have direct access to the IO monad, it would be not just hard - it would be impossible. That is because of type restrictions in the current versions of catch, block, and friends. For example, if you are writing a library that exports something like: class MonadIO m => MyMonad m where... you can't block or catch exceptions, so you have to limit yourself as much as possible to operations that are unlikely to throw IO exceptions. Otherwise, you have to pass on responsibility to users of the library, which makes the library much less useful. That, in turn, would make the use of readline very awkward and complex - or in some cases even impossible - in programs based on monad transformers, one of the most beautiful and powerful idioms in Haskell. What a shame. (The other case is the one Ian mentioned, but as he points out, that could be considered a bug in the library.) On the other hand, it would never be too intrusive to write a wrapper providing an exception if that is really required. So that would be more general. The question becomes: given all of the other bindings in this readline library, is there any conceivable simple usage of readline that would usually not raise exceptions? If not, we should try to fix that. Otherwise, the situation is hopeless anyway, so then it would sadly not make any difference what we do with this particular binding. Regards, Yitz From dons at galois.com Sat Feb 2 14:36:33 2008 From: dons at galois.com (Don Stewart) Date: Sat Feb 2 14:35:45 2008 Subject: darcs patch: Figure out timezone offset from timezone name In-Reply-To: References: Message-ID: <20080202193633.GC23937@scytale.galois.com> david: > Sat Feb 2 12:33:17 CET 2008 David Leuschner > * Figure out timezone offset from timezone name This should be forwarded to the time library maintainer, Bjorn Bringert. From igloo at earth.li Sat Feb 2 14:48:31 2008 From: igloo at earth.li (Ian Lynagh) Date: Sat Feb 2 14:47:49 2008 Subject: darcs patch: Figure out timezone offset from timezone name In-Reply-To: <20080202193633.GC23937@scytale.galois.com> References: <20080202193633.GC23937@scytale.galois.com> Message-ID: <20080202194831.GA1827@matrix.chaos.earth.li> On Sat, Feb 02, 2008 at 11:36:33AM -0800, Donald Bruce Stewart wrote: > david: > > Sat Feb 2 12:33:17 CET 2008 David Leuschner > > * Figure out timezone offset from timezone name > > This should be forwarded to the time library maintainer, Bjorn Bringert. It's Ashley Yakeley according to the Cabal file. Thanks Ian From duncan.coutts at worc.ox.ac.uk Sat Feb 2 14:49:11 2008 From: duncan.coutts at worc.ox.ac.uk (Duncan Coutts) Date: Sat Feb 2 14:48:22 2008 Subject: darcs patch: Figure out timezone offset from timezone name In-Reply-To: <20080202193633.GC23937@scytale.galois.com> References: <20080202193633.GC23937@scytale.galois.com> Message-ID: <1201981751.13130.168.camel@localhost> On Sat, 2008-02-02 at 11:36 -0800, Don Stewart wrote: > david: > > Sat Feb 2 12:33:17 CET 2008 David Leuschner > > * Figure out timezone offset from timezone name > > This should be forwarded to the time library maintainer, Bjorn Bringert. If that is the case then he should probably update the email address that darcs uses: http://darcs.haskell.org/packages/time/_darcs/prefs/email It is currently set to this list. Duncan From judah.jacobson at gmail.com Sat Feb 2 15:03:55 2008 From: judah.jacobson at gmail.com (Judah Jacobson) Date: Sat Feb 2 15:03:19 2008 Subject: Readline read_history and write_history addition In-Reply-To: <2608b8a80802021130i2b4486c3m74bc6ef7fdd2c425@mail.gmail.com> References: <57526e770801182310r2e44c662wd513465d71e67bda@mail.gmail.com> <57526e770801212034g790f1671p38d47b681bd687bb@mail.gmail.com> <20080122221326.GA20619@matrix.chaos.earth.li> <2608b8a80801221549k41b193cq303a3847f98554e1@mail.gmail.com> <20080123005111.GA25334@matrix.chaos.earth.li> <2608b8a80801230435u6a18fb7bh1046cc446120d75@mail.gmail.com> <20080123125724.GA2912@matrix.chaos.earth.li> <2608b8a80801230519v72388283xf35f1de120571ca2@mail.gmail.com> <57526e770802021035u170e47cey77edea12eaa5c340@mail.gmail.com> <2608b8a80802021130i2b4486c3m74bc6ef7fdd2c425@mail.gmail.com> Message-ID: <6d74b0d20802021203x7ae35e0fjaee1a1c961731856@mail.gmail.com> On Sat, Feb 2, 2008 at 11:30 AM, Yitzchak Gale wrote: > Alexander Dunlap wrote: > > For instances where an exception would be too intrusive, I don't see > > how it would be too hard to write a wrapper function > > In a library that does not have direct access to the IO > monad, it would be not just hard - it would be impossible. > That is because of type restrictions in the current versions > of catch, block, and friends. You haven't said why something like the following would not be sufficient: readHistoryM :: MonadIO m => String -> m Bool readHistoryM file = liftIO $ do result <- try (readHistory file) return (result == Right ()) -Judah From bjorn at bringert.net Sat Feb 2 15:17:33 2008 From: bjorn at bringert.net (Bjorn Bringert) Date: Sat Feb 2 15:16:43 2008 Subject: darcs patch: Figure out timezone offset from timezone name In-Reply-To: <1201981751.13130.168.camel@localhost> References: <20080202193633.GC23937@scytale.galois.com> <1201981751.13130.168.camel@localhost> Message-ID: On Feb 2, 2008 8:49 PM, Duncan Coutts wrote: > > On Sat, 2008-02-02 at 11:36 -0800, Don Stewart wrote: > > david: > > > Sat Feb 2 12:33:17 CET 2008 David Leuschner > > > * Figure out timezone offset from timezone name > > > > This should be forwarded to the time library maintainer, Bjorn Bringert. > > If that is the case then he should probably update the email address > that darcs uses: > > http://darcs.haskell.org/packages/time/_darcs/prefs/email > > It is currently set to this list. > > Duncan I also thought that Ashley Yakeley was the maintainer. I have written the code that this patch concerns though. The patch seems nice, but there are some problems: - Time zone information is not static. - Time zone names are sometimes ambiguous. Shouldn't we really use the OS time zone database for this? /Bj?rn From gale at sefer.org Sat Feb 2 16:14:28 2008 From: gale at sefer.org (Yitzchak Gale) Date: Sat Feb 2 16:13:39 2008 Subject: Readline read_history and write_history addition In-Reply-To: <6d74b0d20802021203x7ae35e0fjaee1a1c961731856@mail.gmail.com> References: <57526e770801182310r2e44c662wd513465d71e67bda@mail.gmail.com> <20080122221326.GA20619@matrix.chaos.earth.li> <2608b8a80801221549k41b193cq303a3847f98554e1@mail.gmail.com> <20080123005111.GA25334@matrix.chaos.earth.li> <2608b8a80801230435u6a18fb7bh1046cc446120d75@mail.gmail.com> <20080123125724.GA2912@matrix.chaos.earth.li> <2608b8a80801230519v72388283xf35f1de120571ca2@mail.gmail.com> <57526e770802021035u170e47cey77edea12eaa5c340@mail.gmail.com> <2608b8a80802021130i2b4486c3m74bc6ef7fdd2c425@mail.gmail.com> <6d74b0d20802021203x7ae35e0fjaee1a1c961731856@mail.gmail.com> Message-ID: <2608b8a80802021314k7bcbc643n22d4ee53e6506d73@mail.gmail.com> Alexander Dunlap wrote: >>> For instances where an exception would be too intrusive, I don't see >>> how it would be too hard to write a wrapper function I wrote: >> In a library that does not have direct access to the IO >> monad, it would be not just hard - it would be impossible. >> That is because of type restrictions in the current versions >> of catch, block, and friends. Judah Jacobson wrote: > You haven't said why something like the following would not be sufficient: > > readHistoryM :: MonadIO m => String -> m Bool > readHistoryM file = liftIO $ do > result <- try (readHistory file) > return (result == Right ()) Because a library - other than readline itself - can't force its users to do that. OK. Here's a simplified real-world example. Say you want to write a simple library that interfaces the text-to-speech facilities available on multiple platforms. To play nicely with programs written in a monadic style, the interface might be something like: class MonadIO m => Speech m where sayText :: String -> m () runSpeech :: m a -> IO a instance Speech SomeSpeechSystem where sayText t = ... runSpeech x = do liftIO startSomeSpeechSystem ret <- x liftIO stopSomeSpeechSystem return ret Unfortunately, bracket is not available. So if x throws an uncaught IO exception, you may leave around zombies, database corruption, missiles armed for launch, etc. Well, if your speech system doesn't arm any missiles, you may consider it a reasonable risk to use this library in programs that could throw an IO exception on some rare error condition. But the proposal here is to raise the exception in a common situation that will definitely occur in regular usage. That may be fine in Java or Python, but it is a bad idea for IO exceptions in Haskell. Alexander Dunlap wrote: > So why couldn't you have a Utils.hs file that imports System.IO and > provides the wrapper around readHistory? Then you can use the > tryReadHistory function in your MonadIO-exporting module _exactly_ the > same way as the original readHistory function. You can. But if you are writing a library, your users might not. Regards, Yitz From alexander.dunlap at gmail.com Sat Feb 2 16:17:44 2008 From: alexander.dunlap at gmail.com (Alexander Dunlap) Date: Sat Feb 2 16:16:54 2008 Subject: Fwd: Readline read_history and write_history addition In-Reply-To: <57526e770802021317p1ebe5821y523e103963f311af@mail.gmail.com> References: <57526e770801182310r2e44c662wd513465d71e67bda@mail.gmail.com> <20080123005111.GA25334@matrix.chaos.earth.li> <2608b8a80801230435u6a18fb7bh1046cc446120d75@mail.gmail.com> <20080123125724.GA2912@matrix.chaos.earth.li> <2608b8a80801230519v72388283xf35f1de120571ca2@mail.gmail.com> <57526e770802021035u170e47cey77edea12eaa5c340@mail.gmail.com> <2608b8a80802021130i2b4486c3m74bc6ef7fdd2c425@mail.gmail.com> <6d74b0d20802021203x7ae35e0fjaee1a1c961731856@mail.gmail.com> <2608b8a80802021314k7bcbc643n22d4ee53e6506d73@mail.gmail.com> <57526e770802021317p1ebe5821y523e103963f311af@mail.gmail.com> Message-ID: <57526e770802021317i5038126bue53572e64d6131ae@mail.gmail.com> On Feb 2, 2008 1:14 PM, Yitzchak Gale wrote: > Alexander Dunlap wrote: > >>> For instances where an exception would be too intrusive, I don't see > >>> how it would be too hard to write a wrapper function > > I wrote: > >> In a library that does not have direct access to the IO > >> monad, it would be not just hard - it would be impossible. > >> That is because of type restrictions in the current versions > >> of catch, block, and friends. > > Judah Jacobson wrote: > > You haven't said why something like the following would not be sufficient: > > > > readHistoryM :: MonadIO m => String -> m Bool > > readHistoryM file = liftIO $ do > > result <- try (readHistory file) > > return (result == Right ()) > > Because a library - other than readline itself - can't > force its users to do that. > > OK. Here's a simplified real-world example. Say you want to > write a simple library that interfaces the text-to-speech facilities > available on multiple platforms. To play nicely with programs > written in a monadic style, the interface might be something like: > > class MonadIO m => Speech m where > sayText :: String -> m () > runSpeech :: m a -> IO a > > instance Speech SomeSpeechSystem where > sayText t = ... > runSpeech x = do > liftIO startSomeSpeechSystem > ret <- x > liftIO stopSomeSpeechSystem > return ret > > Unfortunately, bracket is not available. So if x throws an > uncaught IO exception, you may leave around zombies, > database corruption, missiles armed for launch, etc. > > Well, if your speech system doesn't arm any missiles, > you may consider it a reasonable risk to use this > library in programs that could throw an IO exception > on some rare error condition. > > But the proposal here is to raise the exception in a > common situation that will definitely occur in regular > usage. That may be fine in Java or Python, but it > is a bad idea for IO exceptions in Haskell. > > Alexander Dunlap wrote: > > So why couldn't you have a Utils.hs file that imports System.IO and > > provides the wrapper around readHistory? Then you can use the > > tryReadHistory function in your MonadIO-exporting module _exactly_ the > > same way as the original readHistory function. > > You can. But if you are writing a library, your users > might not. > > Regards, > Yitz > I don't understand. Why don't you compile the functions we are suggesting _into the library_? Alex From agl at imperialviolet.org Sat Feb 2 16:34:24 2008 From: agl at imperialviolet.org (Adam Langley) Date: Sat Feb 2 16:33:34 2008 Subject: Incremental parsing and left folds In-Reply-To: <396556a20802011706qecf6842we792616bd067dd4c@mail.gmail.com> References: <478B90A4.4090807@gmail.com> <47A1ADEE.80407@gmail.com> <90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com> <1508723353.20080131161308@gmail.com> <87r6fxazbx.fsf@nmd9999.imr.no> <125EACD0CAE4D24ABDB4D148C4593DA9049E9277@GBLONXMB02.corp.amvescap.net> <47A2F509.9020706@gmail.com> <90889fe70802010308i1a906087q3d3106197e877456@mail.gmail.com> <47A35856.8050106@serpentine.com> <396556a20802011706qecf6842we792616bd067dd4c@mail.gmail.com> Message-ID: <396556a20802021334u1c79814dx36cf60f9dd6b0cf4@mail.gmail.com> On Feb 1, 2008 5:06 PM, Adam Langley wrote: > I think one could get around this by having a couple of states, the > latter being a list of all the additional ByteStrings that the parser > has received. Then, after having prospectively failed a certain parse > path, the failure must include the list of additional data, which can > be merged into the new state for the next prospective path. This > failure value must be internal and, at the top level, translated into > a more user-friendly failure. That was actually bit tougher than I thought, but I got something working: http://www.imperialviolet.org/Incremental.hs Half the bottom functions are still commented out because I got bored, but the plus operator works (I think). I managed a couple of simple tests that I threw at it. I'm pretty sure the cutContinuation is a terrible hack but, apart from having continuations in both directions, it was the best that I could come up with. However, I obvious don't understand Parsec because I made the try operator redundant, and I'm pretty sure that shouldn't have happened. AGL -- Adam Langley agl@imperialviolet.org http://www.imperialviolet.org 650-283-9641 From judah.jacobson at gmail.com Sat Feb 2 17:05:50 2008 From: judah.jacobson at gmail.com (Judah Jacobson) Date: Sat Feb 2 17:05:00 2008 Subject: Readline read_history and write_history addition In-Reply-To: <2608b8a80802021314k7bcbc643n22d4ee53e6506d73@mail.gmail.com> References: <57526e770801182310r2e44c662wd513465d71e67bda@mail.gmail.com> <2608b8a80801221549k41b193cq303a3847f98554e1@mail.gmail.com> <20080123005111.GA25334@matrix.chaos.earth.li> <2608b8a80801230435u6a18fb7bh1046cc446120d75@mail.gmail.com> <20080123125724.GA2912@matrix.chaos.earth.li> <2608b8a80801230519v72388283xf35f1de120571ca2@mail.gmail.com> <57526e770802021035u170e47cey77edea12eaa5c340@mail.gmail.com> <2608b8a80802021130i2b4486c3m74bc6ef7fdd2c425@mail.gmail.com> <6d74b0d20802021203x7ae35e0fjaee1a1c961731856@mail.gmail.com> <2608b8a80802021314k7bcbc643n22d4ee53e6506d73@mail.gmail.com> Message-ID: <6d74b0d20802021405p56c80f91gf806e2fbca4d4b65@mail.gmail.com> On Sat, Feb 2, 2008 at 1:14 PM, Yitzchak Gale wrote: > Alexander Dunlap wrote: > >>> For instances where an exception would be too intrusive, I don't see > >>> how it would be too hard to write a wrapper function > > > I wrote: > >> In a library that does not have direct access to the IO > >> monad, it would be not just hard - it would be impossible. > >> That is because of type restrictions in the current versions > >> of catch, block, and friends. > > > Judah Jacobson wrote: > > You haven't said why something like the following would not be sufficient: > > > > readHistoryM :: MonadIO m => String -> m Bool > > readHistoryM file = liftIO $ do > > result <- try (readHistory file) > > return (result == Right ()) > > Because a library - other than readline itself - can't > force its users to do that. > > OK. Here's a simplified real-world example. Say you want to > write a simple library that interfaces the text-to-speech facilities > available on multiple platforms. To play nicely with programs > written in a monadic style, the interface might be something like: > > class MonadIO m => Speech m where > sayText :: String -> m () > runSpeech :: m a -> IO a > > instance Speech SomeSpeechSystem where > sayText t = ... > runSpeech x = do > liftIO startSomeSpeechSystem > ret <- x > liftIO stopSomeSpeechSystem > return ret > > Unfortunately, bracket is not available. So if x throws an > uncaught IO exception, you may leave around zombies, > database corruption, missiles armed for launch, etc. I've already demonstrated how a library writer can solve that problem in: http://www.haskell.org/pipermail/libraries/2008-January/009034.html -Judah From gale at sefer.org Sat Feb 2 17:08:37 2008 From: gale at sefer.org (Yitzchak Gale) Date: Sat Feb 2 17:07:46 2008 Subject: Readline read_history and write_history addition In-Reply-To: <57526e770802021317i5038126bue53572e64d6131ae@mail.gmail.com> References: <57526e770801182310r2e44c662wd513465d71e67bda@mail.gmail.com> <2608b8a80801230435u6a18fb7bh1046cc446120d75@mail.gmail.com> <20080123125724.GA2912@matrix.chaos.earth.li> <2608b8a80801230519v72388283xf35f1de120571ca2@mail.gmail.com> <57526e770802021035u170e47cey77edea12eaa5c340@mail.gmail.com> <2608b8a80802021130i2b4486c3m74bc6ef7fdd2c425@mail.gmail.com> <6d74b0d20802021203x7ae35e0fjaee1a1c961731856@mail.gmail.com> <2608b8a80802021314k7bcbc643n22d4ee53e6506d73@mail.gmail.com> <57526e770802021317p1ebe5821y523e103963f311af@mail.gmail.com> <57526e770802021317i5038126bue53572e64d6131ae@mail.gmail.com> Message-ID: <2608b8a80802021408g71b7b57ev96542b88068c470c@mail.gmail.com> Alexander Dunlap wrote: > I don't understand. Why don't you compile the functions we are > suggesting _into the library_? The wrapper in either direction is a trivial one liner. The question is: what will be the standard advertised API? If we provide an exception-based idiom for this, we could indirectly cause a system-damaging crash in some seemingly unrelated part of someone's program. That is why I am suggesting that we not include any functions that raise exceptions in non-error conditions. The argument against the above might be as follows: The current limitations in the IO exception system just mean that Haskell is not quite completely ready yet for the monad transformer style. Perhaps. It would make me a bit sad to add one more way that its usefulness is limited, though. I don't think that the difference between raising an exception and other idioms is important enough in this case to make the readline library one of those ways. Thanks, Yitz From gale at sefer.org Sat Feb 2 17:58:45 2008 From: gale at sefer.org (Yitzchak Gale) Date: Sat Feb 2 17:57:56 2008 Subject: Readline read_history and write_history addition In-Reply-To: <6d74b0d20802021405p56c80f91gf806e2fbca4d4b65@mail.gmail.com> References: <57526e770801182310r2e44c662wd513465d71e67bda@mail.gmail.com> <20080123005111.GA25334@matrix.chaos.earth.li> <2608b8a80801230435u6a18fb7bh1046cc446120d75@mail.gmail.com> <20080123125724.GA2912@matrix.chaos.earth.li> <2608b8a80801230519v72388283xf35f1de120571ca2@mail.gmail.com> <57526e770802021035u170e47cey77edea12eaa5c340@mail.gmail.com> <2608b8a80802021130i2b4486c3m74bc6ef7fdd2c425@mail.gmail.com> <6d74b0d20802021203x7ae35e0fjaee1a1c961731856@mail.gmail.com> <2608b8a80802021314k7bcbc643n22d4ee53e6506d73@mail.gmail.com> <6d74b0d20802021405p56c80f91gf806e2fbca4d4b65@mail.gmail.com> Message-ID: <2608b8a80802021458o77015d47o3d72a3b9a23919c5@mail.gmail.com> Judah Jacobson wrote: > I've already demonstrated how a library writer can solve that problem in: > http://www.haskell.org/pipermail/libraries/2008-January/009034.html Yes, that is indeed very nice. But I don't think it is a practical solution right now. I'll explain why I think that under a different subject. Regards, Yitz From gale at sefer.org Sat Feb 2 18:27:44 2008 From: gale at sefer.org (Yitzchak Gale) Date: Sat Feb 2 18:26:53 2008 Subject: MonadIO and IO exceptions Message-ID: <2608b8a80802021527l107575cdya1a4e2dcfa8f9aa3@mail.gmail.com> Judah Jacobson wrote: > I've already demonstrated how a library writer can solve that problem in: > http://www.haskell.org/pipermail/libraries/2008-January/009034.html Yes, that is indeed very nice. But I don't think it is a practical solution right now, for the following reasons: It requires that users be in a special monad; it doesn't work for regular MonadIO. So it isn't really a practical solution until it gets into MTL and people start porting their code. Providing an instance for MonadIO1 (or whatever we would call it) is an extra step for monad writers that may often be skipped. Also, there are obviously many other more complex cases beyond a simple bracket. How general is this technique? As you point out, even for bracket it does not work unless the "after" action is IO. What other restrictions are there in the general case? Perhaps we could fix those problems by also providing liftIOk for all kinds k that occur in the signatures of various functions in Control.Exception. But that would make the new monad even more unwieldy. As I suggested before, I think the best solution would be to define the functions of Control.Exception in terms of lower-level primitives that could then be used to define the functions directly for other monads. Perhaps something like this would be general enough to cover everything: -- Delay any exception and put in buffer startDelayingExceptions :: IO () -- Stop delaying exceptions stopDelayingExceptions :: IO () -- Retrieve delayed exception and clear buffer getDelayedException :: IO (Maybe Exception) There would be one exception buffer per thread. New exceptions would replace old ones, so users of this mechanism would be required to catch as catch can. Based on Simon Marlow's observation in our previous discussion on this topic, we would still want to leave around the current primitives as a special case optimization for IO. Regards, Yitz From bertram.felgenhauer at googlemail.com Sat Feb 2 19:02:18 2008 From: bertram.felgenhauer at googlemail.com (Bertram Felgenhauer) Date: Sat Feb 2 19:01:34 2008 Subject: Readline read_history and write_history addition In-Reply-To: <2608b8a80802021314k7bcbc643n22d4ee53e6506d73@mail.gmail.com> References: <20080122221326.GA20619@matrix.chaos.earth.li> <2608b8a80801221549k41b193cq303a3847f98554e1@mail.gmail.com> <20080123005111.GA25334@matrix.chaos.earth.li> <2608b8a80801230435u6a18fb7bh1046cc446120d75@mail.gmail.com> <20080123125724.GA2912@matrix.chaos.earth.li> <2608b8a80801230519v72388283xf35f1de120571ca2@mail.gmail.com> <57526e770802021035u170e47cey77edea12eaa5c340@mail.gmail.com> <2608b8a80802021130i2b4486c3m74bc6ef7fdd2c425@mail.gmail.com> <6d74b0d20802021203x7ae35e0fjaee1a1c961731856@mail.gmail.com> <2608b8a80802021314k7bcbc643n22d4ee53e6506d73@mail.gmail.com> Message-ID: <20080203000218.GA5177@zombie.inf.tu-dresden.de> Yitzchak Gale wrote: > OK. Here's a simplified real-world example. Say you want to > write a simple library that interfaces the text-to-speech facilities > available on multiple platforms. To play nicely with programs > written in a monadic style, the interface might be something like: > > class MonadIO m => Speech m where > sayText :: String -> m () > runSpeech :: m a -> IO a You meant ma -> m a here, right? > instance Speech SomeSpeechSystem where > sayText t = ... > runSpeech x = do > liftIO startSomeSpeechSystem > ret <- x > liftIO stopSomeSpeechSystem > return ret I think MonadIO is the wrong type class here. For example, ListT IO is an instance of MonadIO, and may cause stopSomeSpeechSystem to be never called, or several times, per startSomeSpeechSytem call, which is clearly not what you wanted (this is still true for the 'ListT done right' versions of ListT). ContT should also be interesting. > But the proposal here is to raise the exception in a > common situation that will definitely occur in regular > usage. That may be fine in Java or Python, but it > is a bad idea for IO exceptions in Haskell. I agree with that though. regards, Bertram From ben.franksen at online.de Sun Feb 3 07:48:49 2008 From: ben.franksen at online.de (Ben Franksen) Date: Sun Feb 3 15:34:11 2008 Subject: Incremental parsing and left folds References: <478B90A4.4090807@gmail.com> <259254796.20080129225150@gmail.com> <47A1ADEE.80407@gmail.com> <90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com> <1508723353.20080131161308@gmail.com> <87r6fxazbx.fsf@nmd9999.imr.no> <125EACD0CAE4D24ABDB4D148C4593DA9049E9277@GBLONXMB02.corp.amvescap.net> <47A2F509.9020706@gmail.com> <90889fe70802010308i1a906087q3d3106197e877456@mail.gmail.com> <47A35856.8050106@serpentine.com> <396556a20802011706qecf6842we792616bd067dd4c@mail.gmail.com> Message-ID: Adam Langley wrote: > On Feb 1, 2008 9:35 AM, Bryan O'Sullivan wrote: >> It wouldn't be hard to take bytestringparser and perform the same >> transformation on it as Adam Langley did with his IncrementalGet parser >> for strict-binary. I've been skipping it due to lack of time, but it's >> an obviously right thing to do. > > I think the hurdle here would be that you can't easily rollback the > state. Normally, in a parser one can just take the current state and > revert to that if a parsing path fails. However, in an incremental > parser, of the style of IncrementalGet, rolling back the state would > mean that the additional data which has been supplied to the parser, > via continuations, will be lost and needs to be resupplied. That's a > non-solution because the caller shouldn't need to know anything about > the internals of the parser. > > I think one could get around this by having a couple of states, the > latter being a list of all the additional ByteStrings that the parser > has received. Then, after having prospectively failed a certain parse > path, the failure must include the list of additional data, which can > be merged into the new state for the next prospective path. This > failure value must be internal and, at the top level, translated into > a more user-friendly failure. > > Unless something special is done, this also means that the incremental > parser couldn't walk over huge streams of data, because it would still > be holding all the input in case it gets reverted. Of course, the top > level cannot be reverted, so maybe it's worth special casing this. Would 'Parallel Parsing Processes' help here? See http://www.haskell.org/haskellwiki/Research_papers/Functional_pearls For a version that is easy to understand and implement, see Chuan-kai Lin's Unimo paper available from the author's home page. Cheers Ben From bjorn at bringert.net Sun Feb 3 17:25:08 2008 From: bjorn at bringert.net (Bjorn Bringert) Date: Sun Feb 3 17:24:15 2008 Subject: darcs patch: Figure out timezone offset from timezone name In-Reply-To: References: <20080202193633.GC23937@scytale.galois.com> <1201981751.13130.168.camel@localhost> Message-ID: On Feb 2, 2008 9:17 PM, Bjorn Bringert wrote: > On Feb 2, 2008 8:49 PM, Duncan Coutts wrote: > > > > On Sat, 2008-02-02 at 11:36 -0800, Don Stewart wrote: > > > david: > > > > Sat Feb 2 12:33:17 CET 2008 David Leuschner > > > > * Figure out timezone offset from timezone name > > > > > > This should be forwarded to the time library maintainer, Bjorn Bringert. > > > > If that is the case then he should probably update the email address > > that darcs uses: > > > > http://darcs.haskell.org/packages/time/_darcs/prefs/email > > > > It is currently set to this list. > > > > Duncan > > I also thought that Ashley Yakeley was the maintainer. I have written > the code that this patch concerns though. The patch seems nice, but > there are some problems: > > - Time zone information is not static. > - Time zone names are sometimes ambiguous. > > Shouldn't we really use the OS time zone database for this? David and I have discussed this, and it seems like this hard-coded timezone database is in any case better than the current incorrect behavior. In the majority of cases it will do the right thing, instead of being almost always incorrect as it is now. I have pushed the patch now, but there are some improvements that could be made: - There are no test cases that test this. The Arbitrary TimeZone instance in test/TestParseTime.hs doesn't generate time zone names, so time zone name handling doesn't get tested. - The timezone table is rather long, and uses plain 'lookup'. OTOH, introducing a dependency on the 'containers' package seems excessive just to do faster lookup. /Bjorn From isaacdupree at charter.net Sun Feb 3 20:07:43 2008 From: isaacdupree at charter.net (Isaac Dupree) Date: Sun Feb 3 20:06:53 2008 Subject: darcs patch: Figure out timezone offset from timezone name In-Reply-To: References: <20080202193633.GC23937@scytale.galois.com> <1201981751.13130.168.camel@localhost> Message-ID: <47A6655F.2000407@charter.net> Bjorn Bringert wrote: > - The timezone table is rather long, and uses plain 'lookup'. OTOH, > introducing a dependency on the 'containers' package seems excessive > just to do faster lookup. it doesn't seem excessive to me -- one of the main things 'containers' implements is fast(ish) lookup. But you mean the way it's looking up amongst a fixed/hard-coded set of keys? -Isaac From rl at cse.unsw.edu.au Sun Feb 3 20:18:43 2008 From: rl at cse.unsw.edu.au (Roman Leshchinskiy) Date: Sun Feb 3 20:17:58 2008 Subject: Proposal: Add concatMapM function (#2042) In-Reply-To: References: <478B90A4.4090807@gmail.com> <479F1801.20801@gmail.com> <404396ef0801290418v4755f9f3n1ddd175c3e56d66e@mail.gmail.com> <20080129175243.GA18863@scytale.galois.com> <479F6CBD.3090009@imn.htwk-leipzig.de> <259254796.20080129225150@gmail.com> <47A1ADEE.80407@gmail.com> <90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com> <1508723353.20080131161308@gmail.com> <47A2D258.7050704@cse.unsw.edu.au> <47A2E9E6.6070208@cse.unsw.edu.au> Message-ID: <47A667F3.2020707@cse.unsw.edu.au> Aaron Denney wrote: > On 2008-02-01, Roman Leshchinskiy wrote: >> Aaron Denney wrote: >>> On 2008-02-01, Roman Leshchinskiy wrote: >>>> Bulat Ziganshin wrote: >>>>> the right way to deal with "modifiers" is to attach them to the Handle >>>>> itself like this: >>>>> >>>>> f <- openFile "name" >>= withLocking >>= withEncoding utf8 >>>> IMO, global state is never "the right way" if it can be avoided. It will >>>> always lead to problems. Especially in a functional language like Haskell. >>> This isn't global state, but local to the handle, and only affects where >>> the handle is passed in. It's just extending an opaque data type. >> If I can destructively change the encoding assocated with a Handle, then >> it's global state. > > Right. But the example given doesn't necessarily have that. > > x <- [5, 6] >>= (return .) (+ 1) > > No modification is going on, but return of new values. True, but that is a very obfuscated way of doing this. If the handle is not modified destructively, then there is no need for withLocking etc. to be monadic. Roman From s.clover at gmail.com Sun Feb 3 22:19:29 2008 From: s.clover at gmail.com (Sterling Clover) Date: Sun Feb 3 22:18:37 2008 Subject: Zombie sh instances in System.Process In-Reply-To: <47A667F3.2020707@cse.unsw.edu.au> References: <478B90A4.4090807@gmail.com> <479F1801.20801@gmail.com> <404396ef0801290418v4755f9f3n1ddd175c3e56d66e@mail.gmail.com> <20080129175243.GA18863@scytale.galois.com> <479F6CBD.3090009@imn.htwk-leipzig.de> <259254796.20080129225150@gmail.com> <47A1ADEE.80407@gmail.com> <90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com> <1508723353.20080131161308@gmail.com> <47A2D258.7050704@cse.unsw.edu.au> <47A2E9E6.6070208@cse.unsw.edu.au> <47A667F3.2020707@cse.unsw.edu.au> Message-ID: <384255A9-9192-45D1-9D05-7CCF4DF1D8C4@gmail.com> I was initially building strictify on top of System.Process.runInteractiveCommand. However, I soon ran into a fairly significant issue with the interface. Even once the process I was calling had terminated, and I had explicitly closed all its buffers, a zombie sh process was left around from it. As I was spawning, sequentially, lots of processes, this soon consumed too many resources and errored out. As I understand it, the sh process is used for redirection (in fact, I ended up implementing a variant of the same thing on top of System.Posix.Process eventually) and needs to stick around for a while, so that issues with lazyIO don't prevent the handles provided by command from terminating before we've read everything we want to. However, at the same time, it seems like a terrible idea to have these buffers stick around *forever*. I dug into the haskell code, but didn't look at the foreign C calls it was based on. This behavior seems pretty clearly broken to me, but I'm not sure what the exact solution should be. Possibly providing an explicit API method to shut the process down? Possibly blocking on polling its buffers and terminating the sh instance once all three buffers are explicitly or implicitly closed? --Sterl. From agl at imperialviolet.org Mon Feb 4 00:40:30 2008 From: agl at imperialviolet.org (Adam Langley) Date: Mon Feb 4 00:39:39 2008 Subject: Incremental parsing and left folds In-Reply-To: <396556a20802021334u1c79814dx36cf60f9dd6b0cf4@mail.gmail.com> References: <478B90A4.4090807@gmail.com> <90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com> <1508723353.20080131161308@gmail.com> <87r6fxazbx.fsf@nmd9999.imr.no> <125EACD0CAE4D24ABDB4D148C4593DA9049E9277@GBLONXMB02.corp.amvescap.net> <47A2F509.9020706@gmail.com> <90889fe70802010308i1a906087q3d3106197e877456@mail.gmail.com> <47A35856.8050106@serpentine.com> <396556a20802011706qecf6842we792616bd067dd4c@mail.gmail.com> <396556a20802021334u1c79814dx36cf60f9dd6b0cf4@mail.gmail.com> Message-ID: <396556a20802032140w4aafbc44o943e25ef12d73789@mail.gmail.com> On Feb 2, 2008 1:34 PM, Adam Langley wrote: > I'm pretty sure the cutContinuation is a terrible hack but, apart from > having continuations in both directions, it was the best that I could > come up with. However, I obvious don't understand Parsec because I > made the try operator redundant, and I'm pretty sure that shouldn't > have happened. Well, I still think that it's a pretty big hack, but since I'd worked out how to do choice in an incremental parser I added it to binary-strict in darcs. http://darcs.imperialviolet.org/darcsweb.cgi?r=binary-strict;a=summary specifically: http://darcs.imperialviolet.org/darcsweb.cgi?r=binary-strict;a=headblob;f=/src/Data/Binary/Strict/IncrementalGet.hs And since I had the choice operator, I added some other parsing stuff (many, <|> etc) to IncrementalGet and Get, than abstracted it out with a class http://darcs.imperialviolet.org/darcsweb.cgi?r=binary-strict;a=headblob;f=/src/Data/Binary/Strict/Class.hs Now you can write parsers which work in both strict and incremental modes. If you remove the monomorphism restriction, they can do both in the same module. As a test I'm writing an HTTP parser (one which handles all the RFC stuff that no one ever believes is valid - like newlines in lists) and it seems to be working pretty well. AGL -- Adam Langley agl@imperialviolet.org http://www.imperialviolet.org 650-283-9641 From gale at sefer.org Mon Feb 4 06:19:51 2008 From: gale at sefer.org (Yitzchak Gale) Date: Mon Feb 4 06:18:57 2008 Subject: Zombie sh instances in System.Process In-Reply-To: <384255A9-9192-45D1-9D05-7CCF4DF1D8C4@gmail.com> References: <478B90A4.4090807@gmail.com> <47A1ADEE.80407@gmail.com> <90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com> <1508723353.20080131161308@gmail.com> <47A2D258.7050704@cse.unsw.edu.au> <47A2E9E6.6070208@cse.unsw.edu.au> <47A667F3.2020707@cse.unsw.edu.au> <384255A9-9192-45D1-9D05-7CCF4DF1D8C4@gmail.com> Message-ID: <2608b8a80802040319j34c5052eye3d70fd6d94e2ec1@mail.gmail.com> Sterling Clover wrote: > Even once the process I > was calling had terminated, and I had explicitly closed all its > buffers, a zombie sh process was left around from it. Make sure to call waitForProcess on each process handle when you are finished with it. Regards, Yitz From simonmarhaskell at gmail.com Mon Feb 4 06:53:34 2008 From: simonmarhaskell at gmail.com (Simon Marlow) Date: Mon Feb 4 06:52:41 2008 Subject: Readline read_history and write_history addition In-Reply-To: <2608b8a80802021314k7bcbc643n22d4ee53e6506d73@mail.gmail.com> References: <57526e770801182310r2e44c662wd513465d71e67bda@mail.gmail.com> <20080122221326.GA20619@matrix.chaos.earth.li> <2608b8a80801221549k41b193cq303a3847f98554e1@mail.gmail.com> <20080123005111.GA25334@matrix.chaos.earth.li> <2608b8a80801230435u6a18fb7bh1046cc446120d75@mail.gmail.com> <20080123125724.GA2912@matrix.chaos.earth.li> <2608b8a80801230519v72388283xf35f1de120571ca2@mail.gmail.com> <57526e770802021035u170e47cey77edea12eaa5c340@mail.gmail.com> <2608b8a80802021130i2b4486c3m74bc6ef7fdd2c425@mail.gmail.com> <6d74b0d20802021203x7ae35e0fjaee1a1c961731856@mail.gmail.com> <2608b8a80802021314k7bcbc643n22d4ee53e6506d73@mail.gmail.com> Message-ID: <47A6FCBE.4090101@gmail.com> Yitzchak Gale wrote: > Alexander Dunlap wrote: >>>> For instances where an exception would be too intrusive, I don't see >>>> how it would be too hard to write a wrapper function > > I wrote: >>> In a library that does not have direct access to the IO >>> monad, it would be not just hard - it would be impossible. >>> That is because of type restrictions in the current versions >>> of catch, block, and friends. > > Judah Jacobson wrote: >> You haven't said why something like the following would not be sufficient: >> >> readHistoryM :: MonadIO m => String -> m Bool >> readHistoryM file = liftIO $ do >> result <- try (readHistory file) >> return (result == Right ()) > > Because a library - other than readline itself - can't > force its users to do that. > > OK. Here's a simplified real-world example. Say you want to > write a simple library that interfaces the text-to-speech facilities > available on multiple platforms. To play nicely with programs > written in a monadic style, the interface might be something like: > > class MonadIO m => Speech m where > sayText :: String -> m () > runSpeech :: m a -> IO a Here's my (slightly provocative) take on this: a MonadIO instance is not a complete wrapper around the IO monad, because it doesn't provide catch. It is not the responsibility of a library that provides IO functions to account for defficient wrappers of IO with no way to catch exceptions. The problem is in the IO wrapper, not the library that throws exceptions. However, I do agree that exceptions should generally be used for exceptional conditions, rather than for general control-flow. This is an example of a *good* reason to avoid an exception: because to use an exception for a non-exceptional condition is poor style. Avoiding exceptions because MonadIO has trouble with them is not a good enough reason, IMO. We should fix MonadIO instead. Cheers, Simon From gale at sefer.org Mon Feb 4 09:06:22 2008 From: gale at sefer.org (Yitzchak Gale) Date: Mon Feb 4 09:05:27 2008 Subject: Readline read_history and write_history addition In-Reply-To: <47A6FCBE.4090101@gmail.com> References: <57526e770801182310r2e44c662wd513465d71e67bda@mail.gmail.com> <20080123005111.GA25334@matrix.chaos.earth.li> <2608b8a80801230435u6a18fb7bh1046cc446120d75@mail.gmail.com> <20080123125724.GA2912@matrix.chaos.earth.li> <2608b8a80801230519v72388283xf35f1de120571ca2@mail.gmail.com> <57526e770802021035u170e47cey77edea12eaa5c340@mail.gmail.com> <2608b8a80802021130i2b4486c3m74bc6ef7fdd2c425@mail.gmail.com> <6d74b0d20802021203x7ae35e0fjaee1a1c961731856@mail.gmail.com> <2608b8a80802021314k7bcbc643n22d4ee53e6506d73@mail.gmail.com> <47A6FCBE.4090101@gmail.com> Message-ID: <2608b8a80802040606mdb73f20n6090d1b437d5202@mail.gmail.com> Simon Marlow wrote: > Here's my (slightly provocative) take on this: a MonadIO instance is not a > complete wrapper around the IO monad, because it doesn't provide catch. That's true. > It is not the responsibility of a library that provides IO functions to > account for defficient wrappers of IO with no way to catch exceptions. The > problem is in the IO wrapper, not the library that throws exceptions. Makes sense. > However, I do agree that exceptions should generally be used for > exceptional conditions, rather than for general control-flow. This is an > example of a *good* reason to avoid an exception: because to use an > exception for a non-exceptional condition is poor style. That is also my opinion. Some people have disagreed. So this should be the focus of the decision then. Thanks, Yitz From bulat.ziganshin at gmail.com Mon Feb 4 02:41:53 2008 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Mon Feb 4 09:53:04 2008 Subject: Proposal: Add concatMapM function (#2042) In-Reply-To: <47A667F3.2020707@cse.unsw.edu.au> References: <478B90A4.4090807@gmail.com> <479F1801.20801@gmail.com> <404396ef0801290418v4755f9f3n1ddd175c3e56d66e@mail.gmail.com> <20080129175243.GA18863@scytale.galois.com> <479F6CBD.3090009@imn.htwk-leipzig.de> <259254796.20080129225150@gmail.com> <47A1ADEE.80407@gmail.com> <90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com> <1508723353.20080131161308@gmail.com> <47A2D258.7050704@cse.unsw.edu.au> <47A2E9E6.6070208@cse.unsw.edu.au> <47A667F3.2020707@cse.unsw.edu.au> Message-ID: <1324598313.20080204104153@gmail.com> Hello Roman, Monday, February 4, 2008, 4:18:43 AM, you wrote: > True, but that is a very obfuscated way of doing this. If the handle is > not modified destructively, then there is no need for withLocking etc. > to be monadic. withLocking = fmap WithLocking newMVar -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From gale at sefer.org Mon Feb 4 09:59:07 2008 From: gale at sefer.org (Yitzchak Gale) Date: Mon Feb 4 09:58:11 2008 Subject: Fixing MonadIO Message-ID: <2608b8a80802040659wef2d357j537e601d0b1ad5bb@mail.gmail.com> Simon Marlow wrote: > Avoiding > exceptions because MonadIO has trouble with them is not a good enough > reason, IMO. We should fix MonadIO instead. I'm all for it! Below is a summary of the three approaches that have been proposed, as far as I can remember: 1. Make the functions in Control.Exception more polymorphic. This is part of the more general program of providing polymorphic IO described in Haskell' ticket 110. Brian Hulley attached to that ticket a version of Control.Exception that does this by introducing the MonadException subclass of MonadIO. http://hackage.haskell.org/trac/haskell-prime/attachment/ticket/110/Exception.txt 2. In another branch from this thread, I suggested adding only the following three low-level exception handling functions to Control.Exception: startDelayingExceptions stopDelayingExceptions getDelayedException This would allow exception handling to be extended arbitrarily in other libraries, with only a small addition to Control.Exception. Simon Marlow pointed out that this mechanism would lose certain optimizations that exist, e.g., for preserving tail-recursion in block. That would be a cost of this generality. (Obviously we would retain the current mechanism for IO itself.) http://www.haskell.org/pipermail/libraries/2008-February/009159.html 3. Earlier in this thread, Judah Jacobson proposed adding additional liftIO functions to MonadIO, or a subclass, that match the kinds of the exception handling functions of Control.Exception. The kinds that would be needed are: For block and unblock: * -> * For catch: * -> (* -> *) -> * For setUncaughtExceptionHandler: (* -> *) -> * The liftIO for catch is the most general, so it could be reused for the others, but that would look a little ad hoc. This approach has the advantage that it does not require any change at all to Control.Exception, but it puts more of a burden on monad authors. http://www.haskell.org/pipermail/libraries/2008-January/009034.html Any other approaches? Any opinions about which of these would be best? Thanks, Yitz From simonmarhaskell at gmail.com Mon Feb 4 11:25:18 2008 From: simonmarhaskell at gmail.com (Simon Marlow) Date: Mon Feb 4 11:24:58 2008 Subject: Fixing MonadIO In-Reply-To: <2608b8a80802040659wef2d357j537e601d0b1ad5bb@mail.gmail.com> References: <2608b8a80802040659wef2d357j537e601d0b1ad5bb@mail.gmail.com> Message-ID: <47A73C6E.1090600@gmail.com> Yitzchak Gale wrote: > Simon Marlow wrote: >> Avoiding >> exceptions because MonadIO has trouble with them is not a good enough >> reason, IMO. We should fix MonadIO instead. > > I'm all for it! > > Below is a summary of the three approaches > that have been proposed, as far as I can remember: > > 1. Make the functions in Control.Exception more polymorphic. > This is part of the more general program of providing polymorphic > IO described in Haskell' ticket 110. Brian Hulley attached to that > ticket a version of Control.Exception that does this by introducing > the MonadException subclass of MonadIO. > > http://hackage.haskell.org/trac/haskell-prime/attachment/ticket/110/Exception.txt Correct me if I'm wrong, but it doesn't seem to be necessary to modify Control.Exception directly in order to adopt this proposal. The new module could be provided as Control.Monad.IO.Exception (for example) in the mtl package. No changes to the base package are required to make this functionality available to everyone. Right? If so, this seems like the smoothest way to address the problem. Cheers, Simon From dons at galois.com Mon Feb 4 13:34:12 2008 From: dons at galois.com (Don Stewart) Date: Mon Feb 4 13:33:36 2008 Subject: Zombie sh instances in System.Process In-Reply-To: <2608b8a80802040319j34c5052eye3d70fd6d94e2ec1@mail.gmail.com> References: <47A1ADEE.80407@gmail.com> <90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com> <1508723353.20080131161308@gmail.com> <47A2D258.7050704@cse.unsw.edu.au> <47A2E9E6.6070208@cse.unsw.edu.au> <47A667F3.2020707@cse.unsw.edu.au> <384255A9-9192-45D1-9D05-7CCF4DF1D8C4@gmail.com> <2608b8a80802040319j34c5052eye3d70fd6d94e2ec1@mail.gmail.com> Message-ID: <20080204183412.GB32486@scytale.galois.com> gale: > Sterling Clover wrote: > > Even once the process I > > was calling had terminated, and I had explicitly closed all its > > buffers, a zombie sh process was left around from it. > > Make sure to call waitForProcess on each process handle > when you are finished with it. Or even consider using say, newpopen, which wraps this up for you, http://www.cse.unsw.edu.au/~dons/code/newpopen/ From judah.jacobson at gmail.com Mon Feb 4 16:49:18 2008 From: judah.jacobson at gmail.com (Judah Jacobson) Date: Mon Feb 4 16:48:22 2008 Subject: Readline read_history and write_history addition In-Reply-To: <2608b8a80802040606mdb73f20n6090d1b437d5202@mail.gmail.com> References: <57526e770801182310r2e44c662wd513465d71e67bda@mail.gmail.com> <2608b8a80801230435u6a18fb7bh1046cc446120d75@mail.gmail.com> <20080123125724.GA2912@matrix.chaos.earth.li> <2608b8a80801230519v72388283xf35f1de120571ca2@mail.gmail.com> <57526e770802021035u170e47cey77edea12eaa5c340@mail.gmail.com> <2608b8a80802021130i2b4486c3m74bc6ef7fdd2c425@mail.gmail.com> <6d74b0d20802021203x7ae35e0fjaee1a1c961731856@mail.gmail.com> <2608b8a80802021314k7bcbc643n22d4ee53e6506d73@mail.gmail.com> <47A6FCBE.4090101@gmail.com> <2608b8a80802040606mdb73f20n6090d1b437d5202@mail.gmail.com> Message-ID: <6d74b0d20802041349v1597c25cq4fdd55f4c9a9b904@mail.gmail.com> On Mon, Feb 4, 2008 at 6:06 AM, Yitzchak Gale wrote: > Simon Marlow wrote: > > However, I do agree that exceptions should generally be used for > > exceptional conditions, rather than for general control-flow. This is an > > example of a *good* reason to avoid an exception: because to use an > > exception for a non-exceptional condition is poor style. > > That is also my opinion. Some people have disagreed. > So this should be the focus of the decision then. I also agree that exceptions should only be used for exceptional conditions; but I do think that this is one of those situations. I'll try to explain why below. (Thanks, Yitzchak, for forking off the thread about fixing limitations of MonadIO.) I assume that the following conditions are already considered exceptional (I haven't ever heard anyone complain that they throw an exception): - readFile : read a nonexistent file - writeFile : write to a file in a nonexistent directory - getEnv: retrieve an unset environmental variable - System.Console.Readline.readInitFile: read a nonexistent .inputrc file I think of readHistory and writeHistory as analogues to the above functions. So calling writeHistory when the directory doesn't exist should produce an exception. And if you call readHistory, either check first that the file exists, or else expect that an exception will sometimes be thrown (just as is already the case for readFile). Packages like shellac-readline can wrap the two steps of "only readHistory if file exists" in a higher-level abstraction; but System.Console.Readline itself should just be a thin binding to the readline APIs. All that being said, this is a relatively minor issue, so if many people are strongly opposed to throwing an exception even after what I've said above, I'll accept the consensus decision. Barring that, however, I'm in favor of the interface already used by other, similar functions in the libraries. Thanks, -Judah From judah.jacobson at gmail.com Mon Feb 4 19:53:28 2008 From: judah.jacobson at gmail.com (Judah Jacobson) Date: Mon Feb 4 19:52:30 2008 Subject: Fixing MonadIO In-Reply-To: <47A73C6E.1090600@gmail.com> References: <2608b8a80802040659wef2d357j537e601d0b1ad5bb@mail.gmail.com> <47A73C6E.1090600@gmail.com> Message-ID: <6d74b0d20802041653ldb3c285o95b4158da4a0a4ac@mail.gmail.com> On Mon, Feb 4, 2008 at 8:25 AM, Simon Marlow wrote: > Yitzchak Gale wrote: > > Simon Marlow wrote: > >> Avoiding > >> exceptions because MonadIO has trouble with them is not a good enough > >> reason, IMO. We should fix MonadIO instead. > > > > I'm all for it! > > > > Below is a summary of the three approaches > > that have been proposed, as far as I can remember: > > > > 1. Make the functions in Control.Exception more polymorphic. > > This is part of the more general program of providing polymorphic > > IO described in Haskell' ticket 110. Brian Hulley attached to that > > ticket a version of Control.Exception that does this by introducing > > the MonadException subclass of MonadIO. > > > > http://hackage.haskell.org/trac/haskell-prime/attachment/ticket/110/Exception.txt > > Correct me if I'm wrong, but it doesn't seem to be necessary to modify > Control.Exception directly in order to adopt this proposal. The new module > could be provided as Control.Monad.IO.Exception (for example) in the mtl > package. No changes to the base package are required to make this > functionality available to everyone. Right? > > If so, this seems like the smoothest way to address the problem. Of the three possibilities listed by Yitzchak, I'm most in favor of adding Brian Hulley's module to the mtl package. (In particular, I've decided that I like it more than my own, earlier proposal.) The only change that I'd make would be to remove setUncaughtExceptionHandler from the MonadException class; it's GHC-specific, and I'm not sure how useful having it in arbitrary MonadIO would be anyway. Best, -Judah From ashley at semantic.org Mon Feb 4 23:28:56 2008 From: ashley at semantic.org (Ashley Yakeley) Date: Mon Feb 4 23:27:59 2008 Subject: darcs patch: Figure out timezone offset from timezone name In-Reply-To: References: <20080202193633.GC23937@scytale.galois.com> <1201981751.13130.168.camel@localhost> Message-ID: <47A7E608.2030402@semantic.org> Bjorn Bringert wrote: > David and I have discussed this, and it seems like this hard-coded > timezone database is in any case better than the current incorrect > behavior. In the majority of cases it will do the right thing, instead > of being almost always incorrect as it is now. I have pushed the patch > now, but there are some improvements that could be made: I think this is wrong. Time-zones change quite frequently, and now any program compiled with 'time' will be incorrect the next time some government changes its zone. It's for a similar reason that no leap-second table is included in the package. I always prefer not to provide information than provide misinformation. That said, this file is Bjorn's part of the package. Is there an alternative approach? Is there some way we can query the tz database? I looked into this earlier but didn't find an obvious way. -- Ashley Yakeley From s.clover at gmail.com Mon Feb 4 23:34:06 2008 From: s.clover at gmail.com (Sterling Clover) Date: Mon Feb 4 23:33:13 2008 Subject: Zombie sh instances in System.Process In-Reply-To: <20080204183412.GB32486@scytale.galois.com> References: <47A1ADEE.80407@gmail.com> <90889fe70801310335rffc281fof0cb4e4eddc9c346@mail.gmail.com> <1508723353.20080131161308@gmail.com> <47A2D258.7050704@cse.unsw.edu.au> <47A2E9E6.6070208@cse.unsw.edu.au> <47A667F3.2020707@cse.unsw.edu.au> <384255A9-9192-45D1-9D05-7CCF4DF1D8C4@gmail.com> <2608b8a80802040319j34c5052eye3d70fd6d94e2ec1@mail.gmail.com> <20080204183412.GB32486@scytale.galois.com> Message-ID: <7A6A58B4-3E79-432B-AA0F-890A2815488E@gmail.com> Hmm... I thought I had been doing everything right, but now trying to reproduce this issue, I find I can't. It must have been the waitForProcess issue. Thanks for the advice, and sorry to trouble the list with this. --Sterl On Feb 4, 2008, at 1:34 PM, Don Stewart wrote: > gale: >> Sterling Clover wrote: >>> Even once the process I >>> was calling had terminated, and I had explicitly closed all its >>> buffers, a zombie sh process was left around from it. >> >> Make sure to call waitForProcess on each process handle >> when you are finished with it. > > Or even consider using say, newpopen, which wraps this up > for you, > > http://www.cse.unsw.edu.au/~dons/code/newpopen/ From cgibbard at gmail.com Tue Feb 5 00:03:38 2008 From: cgibbard at gmail.com (Cale Gibbard) Date: Tue Feb 5 00:02:43 2008 Subject: Minor issue with mapAccumR Message-ID: <89ca3d1f0802042103m3e72f6f7y3ad5f5552093ef5e@mail.gmail.com> I'm not sure whether this would be considered worth fixing right away, or if we should wait until some other major compatibility breaking language change to fix it, but it appears that somehow the parameters to the function passed to mapAccumR are flipped relative to their natural order. To show what I mean, here is some code: Prelude Data.List> mapAccumR (\x y -> (concat ["(f ",x," ",y,")"], concat ["(g ",x," ",y,")"])) "z" ["1","2","3"] ("(f (f (f z 3) 2) 1)",["(g (f (f z 3) 2) 1)","(g (f z 3) 2)","(g z 3)"]) You can see here that the list is flipped over in the process, even though the right fold structure is there, it ends up looking like a left fold over the reverse of the list. One would want the law: fst . mapAccumR f z = foldr (fst . f) z to be true, but instead we have: fst . mapAccumR (flip f) z = foldr (fst . f) z You can see that structurally if we flip the parameters in the above example: Prelude Data.List> mapAccumR (\y x -> (concat ["(f ",x," ",y,")"], concat ["(g ",x," ",y,")"])) "z" ["1","2","3"] ("(f 1 (f 2 (f 3 z)))",["(g 1 (f 2 (f 3 z)))","(g 2 (f 3 z))","(g 3 z)"]) I also have some diagrams on http://cale.yi.org/index.php/Fold_Diagrams (near the end) displaying the difference, and that's where I first noticed it. Are many people using mapAccumR? How much would it hurt to change it? - Cale From david at loisch.de Tue Feb 5 03:05:19 2008 From: david at loisch.de (David Leuschner) Date: Tue Feb 5 03:04:30 2008 Subject: darcs patch: Figure out timezone offset from timezone name In-Reply-To: <47A7E608.2030402@semantic.org> References: <20080202193633.GC23937@scytale.galois.com> <1201981751.13130.168.camel@localhost> <47A7E608.2030402@semantic.org> Message-ID: <20080205080519.GA14096@dl.factis.vpn> >> David and I have discussed this, and it seems like this hard-coded >> timezone database is in any case better than the current incorrect >> behavior. In the majority of cases it will do the right thing, instead >> of being almost always incorrect as it is now. I have pushed the patch >> now, but there are some improvements that could be made: > > I think this is wrong. Time-zones change quite frequently, and now any > program compiled with 'time' will be incorrect the next time some > government changes its zone. Which time zone is used at what time indeed changes frequently but I am not aware of any case where the meaning of a time zone _name_ changed. CEST always refers to +0200 although the periods during which this time zone is used changes. The patch doesn't try to figure out which time zone should be used for a certain place at a certain time. It only maps the names that are typically used to refer to time zones to their time offset. > Is there an alternative approach? Is there some way we can query the tz > database? I looked into this earlier but didn't find an obvious way. Querying the time zone database doesn't help in this case. It only provides information which time zone was (or should be) used at a certain place at a certain time. This patch changes only the way time zone names including a time zone name are parsed. Ambiguity really is a problem (and for that reason it would be best to not use time zone names at all). Quoting from a mail to Bj?rn: > Ambiguity of names really is a problem because PST can refer to "Pacific > Standard Time" which is -07:00 as well as "Pakistan Standard Time" which > is +05:00. But even here detailed time zone information doesn't provide > any help as the meaning doesn't depend on where the computer doing the > decoding is located but where the formatted timestamp originated > from. (And in which context it appeared. For example RFC822 clearly > indicates that PST should mean -07:00). To accomodate for this all > parsing functions should probably return lists of valid interpretations > but that would break the library interface. > > At the moment the library doesn't even indicate, that it could not > interpret the time zone and silently returns nonsense like > > TimeZone 0 False "CEST" > > which is just wrong because "CEST" has an offset of 120 minutes. As a final note PostgreSQL has excellent time and time zone handling and uses exactly this approach. They deal with ambiguity by allowing the database administrator to use localised mapping tables, see http://www.postgresql.org/docs/8.1/static/datetime-keywords.html Cheers, David -- David Leuschner Meisenweg 7 79211 Denzlingen Tel. 07666/912466 From ashley at semantic.org Tue Feb 5 03:20:36 2008 From: ashley at semantic.org (Ashley Yakeley) Date: Tue Feb 5 03:19:39 2008 Subject: darcs patch: Figure out timezone offset from timezone name In-Reply-To: <20080205080519.GA14096@dl.factis.vpn> References: <20080202193633.GC23937@scytale.galois.com> <1201981751.13130.168.camel@localhost> <47A7E608.2030402@semantic.org> <20080205080519.GA14096@dl.factis.vpn> Message-ID: <47A81C54.2050502@semantic.org> David Leuschner wrote: > Which time zone is used at what time indeed changes frequently but I am > not aware of any case where the meaning of a time zone _name_ changed. What's your source for time-zone names? -- Ashley Yakeley From david at loisch.de Tue Feb 5 03:23:55 2008 From: david at loisch.de (David Leuschner) Date: Tue Feb 5 03:22:59 2008 Subject: darcs patch: Figure out timezone offset from timezone name In-Reply-To: <47A81C54.2050502@semantic.org> References: <20080202193633.GC23937@scytale.galois.com> <1201981751.13130.168.camel@localhost> <47A7E608.2030402@semantic.org> <20080205080519.GA14096@dl.factis.vpn> <47A81C54.2050502@semantic.org> Message-ID: <20080205082355.GB14096@dl.factis.vpn> >> Which time zone is used at what time indeed changes frequently but I am >> not aware of any case where the meaning of a time zone _name_ changed. > > What's your source for time-zone names? I just realised I forgot to add a comment in the patch. It's the table from the PostgreSQL manual http://www.postgresql.org/docs/8.1/static/datetime-keywords.html Cheers, David -- David Leuschner Meisenweg 7 79211 Denzlingen Tel. 07666/912466 From ashley at semantic.org Tue Feb 5 03:34:54 2008 From: ashley at semantic.org (Ashley Yakeley) Date: Tue Feb 5 03:33:57 2008 Subject: darcs patch: Figure out timezone offset from timezone name In-Reply-To: <20080205082355.GB14096@dl.factis.vpn> References: <20080202193633.GC23937@scytale.galois.com> <1201981751.13130.168.camel@localhost> <47A7E608.2030402@semantic.org> <20080205080519.GA14096@dl.factis.vpn> <47A81C54.2050502@semantic.org> <20080205082355.GB14096@dl.factis.vpn> Message-ID: <1202200494.6723.32.camel@glastonbury> On Tue, 2008-02-05 at 09:23 +0100, David Leuschner wrote: > >> Which time zone is used at what time indeed changes frequently but I am > >> not aware of any case where the meaning of a time zone _name_ changed. > > > > What's your source for time-zone names? > > I just realised I forgot to add a comment in the patch. It's the table > from the PostgreSQL manual > > http://www.postgresql.org/docs/8.1/static/datetime-keywords.html OK, we should certainly include a link in the source. But why this particular set? Where did PostgreSQL get them from? I Googled and found this: http://www.worldtimezone.com/wtz-names/timezonenames.html http://www.worldtimezone.com/wtz-names/wtz-vet.html Venezuela Time certainly has changed offset. The question is, is "VET" somehow less standard as an abbreviation than the ones in the PostgreSQL list? Alternatively, are the ones listed less liable to change? -- Ashley Yakeley From simonmarhaskell at gmail.com Tue Feb 5 04:38:14 2008 From: simonmarhaskell at gmail.com (Simon Marlow) Date: Tue Feb 5 04:37:19 2008 Subject: Readline read_history and write_history addition In-Reply-To: <6d74b0d20802041349v1597c25cq4fdd55f4c9a9b904@mail.gmail.com> References: <57526e770801182310r2e44c662wd513465d71e67bda@mail.gmail.com> <2608b8a80801230435u6a18fb7bh1046cc446120d75@mail.gmail.com> <20080123125724.GA2912@matrix.chaos.earth.li> <2608b8a80801230519v72388283xf35f1de120571ca2@mail.gmail.com> <57526e770802021035u170e47cey77edea12eaa5c340@mail.gmail.com> <2608b8a80802021130i2b4486c3m74bc6ef7fdd2c425@mail.gmail.com> <6d74b0d20802021203x7ae35e0fjaee1a1c961731856@mail.gmail.com> <2608b8a80802021314k7bcbc643n22d4ee53e6506d73@mail.gmail.com> <47A6FCBE.4090101@gmail.com> <2608b8a80802040606mdb73f20n6090d1b437d5202@mail.gmail.com> <6d74b0d20802041349v1597c25cq4fdd55f4c9a9b904@mail.gmail.com> Message-ID: <47A82E86.2080300@gmail.com> Judah Jacobson wrote: > On Mon, Feb 4, 2008 at 6:06 AM, Yitzchak Gale wrote: >> Simon Marlow wrote: >> > However, I do agree that exceptions should generally be used for >> > exceptional conditions, rather than for general control-flow. This is an >> > example of a *good* reason to avoid an exception: because to use an >> > exception for a non-exceptional condition is poor style. >> >> That is also my opinion. Some people have disagreed. >> So this should be the focus of the decision then. > > I also agree that exceptions should only be used for exceptional > conditions; but I do think that this is one of those situations. I'll > try to explain why below. (Thanks, Yitzchak, for forking off the > thread about fixing limitations of MonadIO.) > > I assume that the following conditions are already considered > exceptional (I haven't ever heard anyone complain that they throw an > exception): > - readFile : read a nonexistent file > - writeFile : write to a file in a nonexistent directory > - getEnv: retrieve an unset environmental variable FWIW, this was hotly debated at the time, and I do believe we made the wrong decision w.r.t. getEnv, mainly because I always end up writing "try $ getEnv", or I forget the try and have to fix the bug later. Cheers, Simon From david at loisch.de Tue Feb 5 07:26:25 2008 From: david at loisch.de (David Leuschner) Date: Tue Feb 5 07:25:30 2008 Subject: darcs patch: Figure out timezone offset from timezone name In-Reply-To: <1202200494.6723.32.camel@glastonbury> References: <20080202193633.GC23937@scytale.galois.com> <1201981751.13130.168.camel@localhost> <47A7E608.2030402@semantic.org> <20080205080519.GA14096@dl.factis.vpn> <47A81C54.2050502@semantic.org> <20080205082355.GB14096@dl.factis.vpn> <1202200494.6723.32.camel@glastonbury> Message-ID: <20080205122625.GC14096@dl.factis.vpn> > > I just realised I forgot to add a comment in the patch. It's the table > > from the PostgreSQL manual > > > > http://www.postgresql.org/docs/8.1/static/datetime-keywords.html > > OK, we should certainly include a link in the source. But why this > particular set? Where did PostgreSQL get them from? > > I Googled and found this: > http://www.worldtimezone.com/wtz-names/timezonenames.html > http://www.worldtimezone.com/wtz-names/wtz-vet.html > > Venezuela Time certainly has changed offset. The question is, is "VET" > somehow less standard as an abbreviation than the ones in the PostgreSQL > list? The meaning of some abbreviations in specified in RFCs (for example RFC822 defines EST,EDT,CST,CDT,MST,MDT,PST,PDT,GMT and UT). I think the important point is, that the patch doesn't break anything. Previously the time module returned wrong time offsets for EVERY timezone name except UT and GMT. The patch improves on this by returning a time zone offset that most probably is correct. Due to ambiguity and the obviously very seldom occuring changes in the meaning of time zone names (probably the ones in the list won't be affected anyway) the new code might also return a wrong value. But for all those cases the old code would have returned a wrong value anyway. I think it's better to get it right most of the times than to always return the wrong values. It would be even better if we would return lists of possible interpretations and let the user decide which interpretation to choose. But that would require a major API change. Cheers, David -- David Leuschner Meisenweg 7 79211 Denzlingen Tel. 07666/912466 From gale at sefer.org Tue Feb 5 08:56:09 2008 From: gale at sefer.org (Yitzchak Gale) Date: Tue Feb 5 08:55:11 2008 Subject: Fixing MonadIO In-Reply-To: <6d74b0d20802041653ldb3c285o95b4158da4a0a4ac@mail.gmail.com> References: <2608b8a80802040659wef2d357j537e601d0b1ad5bb@mail.gmail.com> <47A73C6E.1090600@gmail.com> <6d74b0d20802041653ldb3c285o95b4158da4a0a4ac@mail.gmail.com> Message-ID: <2608b8a80802050556t7b3e4eaejda2eb907769b67ef@mail.gmail.com> Simon Marlow wrote: >> The new module >> could be provided as Control.Monad.IO.Exception (for example) in the mtl >> package... this seems like the smoothest way to address the problem. Judah Jacobson wrote: > Of the three possibilities listed by Yitzchak, I'm most in favor of > adding Brian Hulley's module to the mtl package. (In particular, I've > decided that I like it more than my own, earlier proposal.) The comments in Brian Hulley's module warn that we need to address some issues raised by Oleg before actually adopting this proposal. I'll be out for a few days, I'll try to look at it after that if no one else gets to it. Thanks, Yitz From lemming at henning-thielemann.de Tue Feb 5 09:25:12 2008 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Tue Feb 5 09:24:19 2008 Subject: Minor issue with mapAccumR In-Reply-To: <89ca3d1f0802042103m3e72f6f7y3ad5f5552093ef5e@mail.gmail.com> References: <89ca3d1f0802042103m3e72f6f7y3ad5f5552093ef5e@mail.gmail.com> Message-ID: On Tue, 5 Feb 2008, Cale Gibbard wrote: > Are many people using mapAccumR? How much would it hurt to change it? I cannot remember having ever used mapAccumR, but I used mapAccumL where I used mapM on State monad before, in order to avoid dependency on MTL (and thus non-Haskell-98 features). From valery.vv at gmail.com Tue Feb 5 12:02:48 2008 From: valery.vv at gmail.com (Valery V. Vorotyntsev) Date: Tue Feb 5 12:01:51 2008 Subject: lambdabot setup Message-ID: Dear, lazy programmers, Please let me know the proper place to report lambdabot bugs, and feel free to ignore the rest of message. Are you still reading? In this case you may want to know that *** I've successfully installed lambdabot with GHC 6.9! :) *** Kudos to Cale & the IRC crowd for making my day [http://tunes.org/~nef/logs/haskell/08.02.04]. Boring part: $ darcs get http://code.haskell.org/lambdabot $ cd lambdabot $ runhaskell Setup configure --prefix=$HOME --user $ runhaskell Setup build $ touch LICENSE # see the patch attached $ runhaskell Setup install Interesting part: $ lambdabot -e 'hoogle map' Initialising plugins ...........Plugin.Djinn: couldn't find djinn binary ...........................sending message to bogus server: IrcMessage {msgServer = "freenode", msgLBName = "urk!", msgPrefix = "", msgCommand = "NAMES", msgParams = [""]} .................. done. A Hoogle error occured. Exception: all servers detached exception: State/seen: openBinaryFile: does not exist (No such file or directory) $ hoogle map Could not find hoogle database, looked for: hoogle.txt In order to make `hoogle' binary usable, one should copy `hoogle.txt' file to "$(dirname $(which hoogle))/" directory: $ cp State/hoogle.txt ~/bin/ # FIXME $ hoogle map [...success...] To my believe, it's a package's responsibility to copy data files to proper locations (during `runhaskell Setup install' step). And hoogle _plugin_ still doesn't work though. $ lambdabot Initialising plugins ...........Plugin.Djinn: couldn't find djinn binary ...........................sending message to bogus server: IrcMessage {msgServer = "freenode", msgLBName = "urk!", msgPrefix = "", msgCommand = "NAMES", msgParams = [""]} .................. done. lambdabot> hoogle map A Hoogle error occured. lambdabot> lambdabot: user error () Exception: all servers detached Thank you. -- vvv PS: Tue Feb 5 18:38:55 EET 2008 "Valery V. Vorotyntsev" * `LICENSE' file added Tue Feb 5 18:37:12 EET 2008 "Valery V. Vorotyntsev" * lambdabot.cabal: add `build-type' to make Cabal happy -------------- next part -------------- New patches: [lambdabot.cabal: add `build-type' to make Cabal happy "Valery V. Vorotyntsev" **20080205163712] { hunk ./lambdabot.cabal 19 +build-type: Simple } [`LICENSE' file added "Valery V. Vorotyntsev" **20080205163855] { addfile ./LICENSE hunk ./LICENSE 1 + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program