[Haskell-cafe] POSIX AIO (asych I/O) ...
Hello, I am also testing my aio support. The aio_write binding seems to work ok .. as well as aio_error, Aio_return is a problem child. I think I wrote a really simple binding. I always receive nbytes as 0. I have been staring at the code hoping to catch a stupid mistake. I put putStrLn's in the code. .Here is the code ... aioReturn :: AIOCB -> IO (AIOCB, ByteCount) aioReturn aiocb = do allocaBytes (#const sizeof(struct aiocb)) $ \ p_aiocb -> do poke p_aiocb aiocb count <- throwErrnoIfMinus1 "aioReturn" (c_aio_return p_aiocb) aiocb <- peek p_aiocb return (aiocb, fromIntegral count) foreign import ccall safe "aio.h aio_return" c_aio_return :: Ptr AIOCB -> IO CInt Maybe someone can spot something that I haven't. Thanks, Vasili ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] POSIX AIO (asych I/O) ...
Hello Vasili, Tuesday, July 1, 2008, 11:42:26 AM, you wrote: looks ok, show us your peek/poke code > Hello, > I am also testing my aio support. The aio_write binding > seems to work ok .. as well as aio_error, Aio_return is a problem > child. I think I wrote a really simple binding. I always receive > nbytes as 0. I have been staring at the code hoping to catch a > stupid mistake. I put putStrLn's in the code. .Here is the code ... > > aioReturn :: AIOCB -> IO (AIOCB, ByteCount) > aioReturn aiocb = do > allocaBytes (#const sizeof(struct aiocb)) $ \ p_aiocb -> do > poke p_aiocb aiocb > count <- throwErrnoIfMinus1 "aioReturn" (c_aio_return p_aiocb) > aiocb <- peek p_aiocb > return (aiocb, fromIntegral count) > foreign import ccall safe "aio.h aio_return" > c_aio_return :: Ptr AIOCB -> IO CInt > Maybe someone can spot something that I haven't. > > Thanks, Vasili > -- Best regards, Bulatmailto:[EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] The ping method in HDBC
On Mon, Jun 30, 2008 at 9:31 PM, John Goerzen <[EMAIL PROTECTED]> wrote: > > run dbh "SELECT 1" [] > > I note from the Perl DBI documentation that it is not guaranteed that > its ping function actually does anything. Okay, thanks :) > > I am pondering connection pools in HDBC for the future, if I have the > need for it. > That'll be great ;) Best, -agentzh ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] A Monad for on-demand file generation?
Hi, thanks for your comments. Am Montag, den 30.06.2008, 16:54 -0700 schrieb Ryan Ingram: > 1) unsafeInterleaveIO seems like a big hammer to use for this problem, > and there are a lot of gotchas involved that you may not have fully > thought out. But you do meet the main criteria (file being read is > assumed to be constant for a single run of the program). Any other gotcha? Anyways, is this really worse than the similary lazy readFile? Using that would not safe the call to open, but at least the reading and processing, in the same situations. > If you have the ability to store metadata about the computation along > with the computation results, maybe that would be a better solution? Not sure what you mean here, sorry. Can you elaborate? > 2) I agree with Luke that this "smells" more like an applicative > functor. But getting to monad syntax is quite nice if you can do so. > As an applicative functor you would have "writeFileOD :: Filename -> > ODIO ByteString -> ODIO ()"; then writeFile can handle all the > necessary figuring out of timestamps itself, and you get the bonus > guarantee that the contents of the files read by the "ODIO ByteString" > argument won't affect the filename you are going to output to. I thought about this (without having the applicative abstraction in mind). This would then look like: main = do f1 <- readFileOD "infile1" f2 <- readFileOD "infile2" writeFileOD "outfile1" $ someFunc <$> f1 <*> f2 writeFileOD "outfile2" $ someOtherFunc <$> f1 right? Will it still work so that if both outfiles need to be generated, f1 is read only once? > 3) Instead of (Read,Show), look into Data.Binary instead, if you > actually care about efficiency. Parsing text at read time will almost > never be faster than just performing the computation on the source > data again. I assume it’s still faster than, e.g., running an external program to read the exif tags, but you are right, Data.Binary is nicer for this. Thanks, Joachim -- Joachim "nomeata" Breitner mail: [EMAIL PROTECTED] | ICQ# 74513189 | GPG-Key: 4743206C JID: [EMAIL PROTECTED] | http://www.joachim-breitner.de/ Debian Developer: [EMAIL PROTECTED] signature.asc Description: Dies ist ein digital signierter Nachrichtenteil ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] POSIX AIO (asych I/O) ...
instance Storable AIOCB where sizeOf _ = (#const sizeof (struct aiocb)) alignment _ = 1 poke p_AIOCB (AIOCB aioFd aioLioOpcode aioReqPrio aioOffset aioBuf aioBytes aioSigevent) = do (#poke struct aiocb, aio_fildes) p_AIOCB aioFd (#poke struct aiocb, aio_lio_opcode) p_AIOCB aioLioOpcode (#poke struct aiocb, aio_reqprio) p_AIOCB aioReqPrio (#poke struct aiocb, aio_offset) p_AIOCB aioOffset (#poke struct aiocb, aio_buf) p_AIOCB aioBuf (#poke struct aiocb, aio_nbytes) p_AIOCB aioBytes (#poke struct aiocb, aio_sigevent) p_AIOCB aioSigevent peek p_AIOCB = do aioFd <- (#peek struct aiocb, aio_fildes) p_AIOCB aioLioOpcode <- (#peek struct aiocb, aio_lio_opcode) p_AIOCB aioReqPrio <- (#peek struct aiocb, aio_reqprio) p_AIOCB aioOffset <- (#peek struct aiocb, aio_offset) p_AIOCB aioBuf <- (#peek struct aiocb, aio_buf) p_AIOCB aioBytes <- (#peek struct aiocb, aio_nbytes) p_AIOCB aioSigevent <- (#peek struct aiocb, aio_sigevent) p_AIOCB return (AIOCB aioFd aioLioOpcode aioReqPrio aioOffset aioBuf aioBytes aioSigevent) On Tue, Jul 1, 2008 at 2:48 AM, Bulat Ziganshin <[EMAIL PROTECTED]> wrote: > Hello Vasili, > > Tuesday, July 1, 2008, 11:42:26 AM, you wrote: > > looks ok, show us your peek/poke code > > > > Hello, > > >I am also testing my aio support. The aio_write binding > > seems to work ok .. as well as aio_error, Aio_return is a problem > > child. I think I wrote a really simple binding. I always receive > > nbytes as 0. I have been staring at the code hoping to catch a > > stupid mistake. I put putStrLn's in the code. .Here is the code ... > > > > aioReturn :: AIOCB -> IO (AIOCB, ByteCount) > > aioReturn aiocb = do > >allocaBytes (#const sizeof(struct aiocb)) $ \ p_aiocb -> do > > poke p_aiocb aiocb > > count <- throwErrnoIfMinus1 "aioReturn" (c_aio_return p_aiocb) > >aiocb <- peek p_aiocb > > return (aiocb, fromIntegral count) > > > foreign import ccall safe "aio.h aio_return" > > c_aio_return :: Ptr AIOCB -> IO CInt > > > Maybe someone can spot something that I haven't. > > > > Thanks, Vasili > > > > > -- > Best regards, > Bulatmailto:[EMAIL PROTECTED] > > ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] A Monad for on-demand file generation?
Joachim Breitner <[EMAIL PROTECTED]> writes: >> 1) unsafeInterleaveIO seems like a big hammer to use for this problem, >> and there are a lot of gotchas involved that you may not have fully >> thought out. But you do meet the main criteria (file being read is >> assumed to be constant for a single run of the program). > Any other gotcha? The one that springs to mind is that you might run out of file handles. At least on Linux, that's a precious resource. -k -- If I haven't seen further, it is by standing in the footprints of giants ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] A Monad for on-demand file generation?
Hi, Am Dienstag, den 01.07.2008, 11:53 +0200 schrieb Ketil Malde: > Joachim Breitner <[EMAIL PROTECTED]> writes: > > >> 1) unsafeInterleaveIO seems like a big hammer to use for this problem, > >> and there are a lot of gotchas involved that you may not have fully > >> thought out. But you do meet the main criteria (file being read is > >> assumed to be constant for a single run of the program). > > > Any other gotcha? > > The one that springs to mind is that you might run out of file > handles. At least on Linux, that's a precious resource. but at least then, (unsafeInterleaveIO readFile) is actually better than (readFile), because if I consume the files in sequence and complete, they will be opened and closed in sequence with the first one, but be opened all at once with the second. At least it won’t be worse, because the file will not be closed later, and possibly opened later. Greetings, Joachim -- Joachim "nomeata" Breitner mail: [EMAIL PROTECTED] | ICQ# 74513189 | GPG-Key: 4743206C JID: [EMAIL PROTECTED] | http://www.joachim-breitner.de/ Debian Developer: [EMAIL PROTECTED] signature.asc Description: Dies ist ein digital signierter Nachrichtenteil ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Anglo Haskell 2008
Anglo Haskell is a gathering of all people Haskell-related from beginners, to seasoned hackers to academic giants. All and more are welcomed by large fuzzy green lambdas. Anglo Haskell has happened for the last two years and we see no reason why it should not happen again this year. For the last two years they've tended to have talks on Fridays and then Other Things on the Saturday (including Punting and Group Hacking, some or more of which may have happened in Pubs). We're proposing the same general format this year. In contrast to the last two years which have been held at MSR Cambridge (UK), we're this year proposing to hold the event at Imperial College, London. London is probably easier to get to and from (though more tedious to get across) than Cambridge and we hope this will attract people who previously have not been able to get out to Cambridge. The proposed dates are Friday the 8th and Saturday the 9th of August. More details are available on the wikipage: http://www.haskell.org/haskellwiki/AngloHaskell/2008 Please feel free to add to this page. If you're at all interested in coming along then please add your name to the wikipage. If you're interested in giving a talk - on literally anything Haskell related: this is not a solely theory day or solely a practical day; anything goes which is Haskell related - then similarly add yourself to the list of speakers. Schedule and other details will be confirmed soon. Lodging, travel and all other related matters will be discussed on the irc channel (and will eventually migrate to the wikipage) #anglohaskell. If you're free that weekend then please come along! Also, if you'd really like to come but can't make those dates and there are many of you then please shout loudly and things could potentially be moved, though with the lack of time left before the event, we'd prefer to avoid this. Matthew ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] lhs syntax highlighting in vim
On 11 jun 2008, at 12:29, Ian Lynagh wrote: On Wed, Jun 11, 2008 at 01:23:58AM +0100, Eric Stansifer wrote: The syntax highlighting file for literate haskell in vim says that its maintainer is haskell-cafe@haskell.org, so hopefully one of you will find this relevant. In literate haskell files, vim optionally highlights the non-code text according to TeX markup. The syntax highlighting file looks for key phrases (e.g., "\documentclass") to decide whether to use TeX markup highlighting; but it (erroneously, in my opinion, and at variance with the documentation) will use TeX markup highlighting on any lhs file that contains the '%' character anywhere in it. The bug is in line 74 of version 1.01 of the lhaskell.vim syntax highlighting file. I agree that this is wrong. It used to only look at the first 20 lines, so we were covering the case where a TeX file began with some TeX comments. We'd also look for ^\s*%, rather than a % anywhere. If we are going to look at the whole file then checking for comments isn't necessary. Unfortunately that scan is not necesarily compatible with people dynamically turning on syntax highlighting. But just searching for % is *dead* wrong, I fully agree. I've modified the search code and submitted a patch to the Vim maintainers. With kind regards, Arthur van Leeuwen. -- /\/ | [EMAIL PROTECTED] | Work like you don't need the money /__\ / | A friend is someone with whom | Love like you have never been hurt /\/__ | you can dare to be yourself | Dance like there's nobody watching ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] A Monad for on-demand file generation?
On Tue, Jul 01, 2008 at 10:22:35AM +, Joachim Breitner wrote: > Hi, > > Am Dienstag, den 01.07.2008, 11:53 +0200 schrieb Ketil Malde: > > Joachim Breitner <[EMAIL PROTECTED]> writes: > > > > >> 1) unsafeInterleaveIO seems like a big hammer to use for this problem, > > >> and there are a lot of gotchas involved that you may not have fully > > >> thought out. But you do meet the main criteria (file being read is > > >> assumed to be constant for a single run of the program). > > > > > Any other gotcha? > > > > The one that springs to mind is that you might run out of file > > handles. At least on Linux, that's a precious resource. > > but at least then, (unsafeInterleaveIO readFile) is actually better than > (readFile), because if I consume the files in sequence and complete, > they will be opened and closed in sequence with the first one, but be > opened all at once with the second. At least it won’t be worse, because > the file will not be closed later, and possibly opened later. Indeed, the best option (in my opinion) would be unsafeInterleaveIO readFileStrict (where you might need to write readFileStrict). In darcs, we use lazy IO a lot, but never lazily read a file, precisely due to the open file handle issue. This works pretty well, and your scenario is precisely the one in which unsafeInterleaveIO shines. David signature.asc Description: Digital signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] A Monad for on-demand file generation?
On Tue, 1 Jul 2008, David Roundy wrote: > Indeed, the best option (in my opinion) would be > > unsafeInterleaveIO readFileStrict How about ByteString.readFile ? This is strict and efficient. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] gcc as a portable assembler: tail calls vs trampoline
Hello, everyone, I'm not sure this is the good list for this posting: I plan to write yet another lazy graph reduction machine, using gcc, mainly for fun. My concern right now is about one particular aspect of gcc: the tail calls vs trampoline deathmatch. First some clarifications: -> By tail call, I mean a properly optimized one, which doesn't grow the stack. Basically a jump. -> By trampoline, I mean the infinite loop referred to as a "tiny interpreter" in the STG paper [1]. Instead of (tail) calling a function, we return its pointer, which will then be used for the actual call. I've read that trampoline calls are about 3 times as expensive as tail calls. Instead of a (direct) jump, you have a return, followed by an indirect call. However, testing this with gcc, I didn't manage to show any measurable difference. What am I missing? I used -O2 on both benchmarks, and turned off inlining (using the __noinline__ attribute). I'm running the program on a core2Duo in 32 bits mode, using GNU/Linux Ubuntu. Should I also make separate modules to prevent whole program analysis from gcc? Anyway, I send you the code below, so you can test and review it. Enjoy! [1]: http://research.microsoft.com/Users/simonpj/Papers/spineless-tagless-gmachine.ps.gz /* This program tests the performance difference between trampoline * calls and tail calls. (In the STG and related papers, trampoline * is referred to as "tiny interpreter") * * depending on the mode (tail call or trampoline), some code changes: * the return type of the code blocks, and the calls to other blocks * (direct tail calls or return to trampoline). Hence the macros ENTER * and RETURN. * * To compile it,type one of the two following commands: * gcc -O2 sibcall.c -D SIBCALL * gcc -O2 sibcall.c * * The first one will make the program use sibling calls (enabled at * O2), and the second one will fall back to trampoline calls */ #ifdef SIBCALL // tail call mode #define ENTER(f) (f()) #define RETURN void #define MAIN(start) start() #else // trampoline call mode #define ENTER(f) return f #define RETURN void* #define MAIN(start) do{ void * (*f)(void) = start; \ while (1) \ f = (*f)(); \ } while (0) #endif // Now, we can begin the generic code #include #define LIMIT 10 // one billion int counter = 0; RETURN closure0(void); RETURN closure1(void); int main(int argc, char ** argv) { MAIN(closure0); return 0; } __attribute__ ((__noinline__)) RETURN closure0(void) { if (counter >= LIMIT) exit(0); counter++; ENTER(closure1); } __attribute__ ((__noinline__)) RETURN closure1(void) { if (counter >= LIMIT) exit(0); counter++; ENTER(closure0); } ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] gcc as a portable assembler: tail calls vs trampoline
2008/7/1 Robin Green <[EMAIL PROTECTED]>: > I think you should use the -march flag to gcc. Otherwise you are tying > the compiler to an ancient version of the x86 instruction set (386). OK, let's try... Done. I used -march=nocona. I couldn't do core2 (not available on my gcc 4.1.2 yet). Did not notice any difference... > On Tue, 1 Jul 2008 16:57:38 +0200 > "Loup Vaillant" <[EMAIL PROTECTED]> wrote: > >> Hello, everyone, >> I'm not sure this is the good list for this posting: I plan to write >> yet another lazy graph reduction machine, using gcc, mainly for fun. >> My concern right now is about one particular aspect of gcc: the tail >> calls vs trampoline deathmatch. >> >> First some clarifications: >> -> By tail call, I mean a properly optimized one, which doesn't grow >> the stack. Basically a jump. >> -> By trampoline, I mean the infinite loop referred to as a "tiny >> interpreter" in the STG paper [1]. Instead of (tail) calling a >> function, we return its pointer, which will then be used for the >> actual call. >> >> I've read that trampoline calls are about 3 times as expensive as tail >> calls. Instead of a (direct) jump, you have a return, followed by an >> indirect call. However, testing this with gcc, I didn't manage to show >> any measurable difference. What am I missing? I used -O2 on both >> benchmarks, and turned off inlining (using the __noinline__ >> attribute). I'm running the program on a core2Duo in 32 bits mode, >> using GNU/Linux Ubuntu. Should I also make separate modules to prevent >> whole program analysis from gcc? >> >> Anyway, I send you the code below, so you can test and review it. >> Enjoy! >> >> [1]: >> http://research.microsoft.com/Users/simonpj/Papers/spineless-tagless-gmachine.ps.gz >> >> >> >> /* This program tests the performance difference between trampoline >> * calls and tail calls. (In the STG and related papers, trampoline >> * is referred to as "tiny interpreter") >> * >> * depending on the mode (tail call or trampoline), some code changes: >> * the return type of the code blocks, and the calls to other blocks >> * (direct tail calls or return to trampoline). Hence the macros ENTER >> * and RETURN. >> * >> * To compile it,type one of the two following commands: >> * gcc -O2 sibcall.c -D SIBCALL >> * gcc -O2 sibcall.c >> * >> * The first one will make the program use sibling calls (enabled at >> * O2), and the second one will fall back to trampoline calls >> */ >> >> #ifdef SIBCALL // tail call mode >> >> #define ENTER(f) (f()) >> #define RETURN void >> #define MAIN(start) start() >> >> #else // trampoline call mode >> >> #define ENTER(f) return f >> #define RETURN void* >> #define MAIN(start) do{ void * (*f)(void) = start; \ >> while (1) \ >>f = (*f)(); \ >>} while (0) >> #endif >> >> // Now, we can begin the generic code >> #include >> #define LIMIT 10 // one billion >> >> int counter = 0; >> >> RETURN closure0(void); >> RETURN closure1(void); >> >> >> int main(int argc, char ** argv) >> { >> MAIN(closure0); >> return 0; >> } >> >> __attribute__ ((__noinline__)) >> RETURN closure0(void) >> { >> if (counter >= LIMIT) exit(0); >> counter++; >> ENTER(closure1); >> } >> __attribute__ ((__noinline__)) >> RETURN closure1(void) >> { >> if (counter >= LIMIT) exit(0); >> counter++; >> ENTER(closure0); >> } >> ___ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe > ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] gcc as a portable assembler: tail calls vs trampoline
Did you look at the generated assembly code? Although I don't know anything about GCC, I believe it's easy to let it generate an assembly listing file. Loup Vaillant wrote: 2008/7/1 Robin Green <[EMAIL PROTECTED]>: I think you should use the -march flag to gcc. Otherwise you are tying the compiler to an ancient version of the x86 instruction set (386). OK, let's try... Done. I used -march=nocona. I couldn't do core2 (not available on my gcc 4.1.2 yet). Did not notice any difference... On Tue, 1 Jul 2008 16:57:38 +0200 "Loup Vaillant" <[EMAIL PROTECTED]> wrote: Hello, everyone, I'm not sure this is the good list for this posting: I plan to write yet another lazy graph reduction machine, using gcc, mainly for fun. My concern right now is about one particular aspect of gcc: the tail calls vs trampoline deathmatch. First some clarifications: -> By tail call, I mean a properly optimized one, which doesn't grow the stack. Basically a jump. -> By trampoline, I mean the infinite loop referred to as a "tiny interpreter" in the STG paper [1]. Instead of (tail) calling a function, we return its pointer, which will then be used for the actual call. I've read that trampoline calls are about 3 times as expensive as tail calls. Instead of a (direct) jump, you have a return, followed by an indirect call. However, testing this with gcc, I didn't manage to show any measurable difference. What am I missing? I used -O2 on both benchmarks, and turned off inlining (using the __noinline__ attribute). I'm running the program on a core2Duo in 32 bits mode, using GNU/Linux Ubuntu. Should I also make separate modules to prevent whole program analysis from gcc? Anyway, I send you the code below, so you can test and review it. Enjoy! [1]: http://research.microsoft.com/Users/simonpj/Papers/spineless-tagless-gmachine.ps.gz /* This program tests the performance difference between trampoline * calls and tail calls. (In the STG and related papers, trampoline * is referred to as "tiny interpreter") * * depending on the mode (tail call or trampoline), some code changes: * the return type of the code blocks, and the calls to other blocks * (direct tail calls or return to trampoline). Hence the macros ENTER * and RETURN. * * To compile it,type one of the two following commands: * gcc -O2 sibcall.c -D SIBCALL * gcc -O2 sibcall.c * * The first one will make the program use sibling calls (enabled at * O2), and the second one will fall back to trampoline calls */ #ifdef SIBCALL // tail call mode #define ENTER(f) (f()) #define RETURN void #define MAIN(start) start() #else // trampoline call mode #define ENTER(f) return f #define RETURN void* #define MAIN(start) do{ void * (*f)(void) = start; \ while (1) \ f = (*f)(); \ } while (0) #endif // Now, we can begin the generic code #include #define LIMIT 10 // one billion int counter = 0; RETURN closure0(void); RETURN closure1(void); int main(int argc, char ** argv) { MAIN(closure0); return 0; } __attribute__ ((__noinline__)) RETURN closure0(void) { if (counter >= LIMIT) exit(0); counter++; ENTER(closure1); } __attribute__ ((__noinline__)) RETURN closure1(void) { if (counter >= LIMIT) exit(0); counter++; ENTER(closure0); } ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] A Monad for on-demand file generation?
On 7/1/08, Joachim Breitner <[EMAIL PROTECTED]> wrote: > Hi, > > thanks for your comments. > > Am Montag, den 30.06.2008, 16:54 -0700 schrieb Ryan Ingram: > > 1) unsafeInterleaveIO seems like a big hammer to use for this problem, > > and there are a lot of gotchas involved that you may not have fully > > thought out. But you do meet the main criteria (file being read is > > assumed to be constant for a single run of the program). > > Any other gotcha? Anyways, is this really worse than the similary lazy > readFile? Using that would not safe the call to open, but at least the > reading and processing, in the same situations. Well, you're also (from your description) probably writing some tracking information to an IORef of some sort. That can happen in the middle of an otherwise pure computation, and it's difficult to know exactly when it'll get triggered, due to laziness. You can probably make it work :) > > If you have the ability to store metadata about the computation along > > with the computation results, maybe that would be a better solution? > > Not sure what you mean here, sorry. Can you elaborate? Well, while doing the computation the first time, you can track what depends on what. Then you save *that* information out. Here's an example: main = runODIO $ do do bar <- readFileOD "bar.txt" baz <- readFileOD "baz.txt" let result = expensiveComputation bar baz writeFileOD "foo.bin" result do hat <- readFileOD "hat.txt" let result = otherComputation hat writeFileOD "foo2.bin" result Now, as you mentioned before, you know that the RHS of >> doesn't depend on the files read on the LHS. So the two "do" blocks here are independent. Now, if you run with no information, you run the whole computation, and you write out in your metadata "First we are going to build foo.bin from bar.txt and baz.txt, and then we build foo2.bin from hat.txt". Now when you get to the first "do" block, you know what computation is about to happen (since you've recorded it before), and can check the timestamps of foo.bin, bar.txt, and baz.txt, and potentially skip the whole thing. Of course now the metadata depends on the script itself, but you already had to deal with that problem :) > > 2) I agree with Luke that this "smells" more like an applicative > > functor. But getting to monad syntax is quite nice if you can do so. > > As an applicative functor you would have "writeFileOD :: Filename -> > > ODIO ByteString -> ODIO ()"; then writeFile can handle all the > > necessary figuring out of timestamps itself, and you get the bonus > > guarantee that the contents of the files read by the "ODIO ByteString" > > argument won't affect the filename you are going to output to. > > I thought about this (without having the applicative abstraction in > mind). This would then look like: > > main = do > f1 <- readFileOD "infile1" > f2 <- readFileOD "infile2" > writeFileOD "outfile1" $ someFunc <$> f1 <*> f2 > writeFileOD "outfile2" $ someOtherFunc <$> f1 > > right? Not exactly. Try this: writeFileOD "outfile1" (someFunc <$> readFileOD "infile1" <*> readFileOD "infile2") writeFileOD "outfile2" (someOtherFunc <$> readFIleOD "infile1") (or, equivalently, replace the "<-" with "let .. in" in your data). > Will it still work so that if both outfiles need to be generated, > f1 is read only once? That depends how you write it! Remember that you can write your applicative functor to just build up a graph of what computation might need to be done. You can then analyze that graph and look for sharing if necessary. If you want the sharing to be explicit, you need something a bit more monad-ish. If the type of "readFileOD" is "Filename -> ODIO (ODIO ByteString)" then your original syntax works and gives you a chance to pick up on the explicit sharing by labelling the result of "f1 <- ...". -- ryan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] A Monad for on-demand file generation?
Hi, thanks again for you input. Just one small remark: Am Dienstag, den 01.07.2008, 14:52 -0700 schrieb Ryan Ingram: > On 7/1/08, Joachim Breitner <[EMAIL PROTECTED]> wrote: > > Am Montag, den 30.06.2008, 16:54 -0700 schrieb Ryan Ingram: > > > 1) unsafeInterleaveIO seems like a big hammer to use for this problem, > > > and there are a lot of gotchas involved that you may not have fully > > > thought out. But you do meet the main criteria (file being read is > > > assumed to be constant for a single run of the program). > > > > Any other gotcha? Anyways, is this really worse than the similary lazy > > readFile? Using that would not safe the call to open, but at least the > > reading and processing, in the same situations. > > Well, you're also (from your description) probably writing some > tracking information to an IORef of some sort. That can happen in the > middle of an otherwise pure computation, and it's difficult to know > exactly when it'll get triggered, due to laziness. You can probably > make it work :) Well, for the tracking information, I can do it purely, by copying code from StateT (or WriterT or ReaderT, I’m not sure :-)), and adapting slightly (e.g. the (>>) optimization). So besides unsafeInterleaveIO, no “bad, unpure stuff” should be necessary. I think I’ll put my ideas to code soon and post it here. Greetings, Joachim -- Joachim Breitner e-Mail: [EMAIL PROTECTED] Homepage: http://www.joachim-breitner.de ICQ#: 74513189 Jabber-ID: [EMAIL PROTECTED] signature.asc Description: Dies ist ein digital signierter Nachrichtenteil ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] A Monad for on-demand file generation?
On 2008 Jul 1, at 17:52, Ryan Ingram wrote: Well, you're also (from your description) probably writing some tracking information to an IORef of some sort. That can happen in the middle of an otherwise pure computation, and it's difficult to know exactly when it'll get triggered, due to laziness. You can probably make it work :) If you have the ability to store metadata about the computation along with the computation results, maybe that would be a better solution? Not sure what you mean here, sorry. Can you elaborate? Well, while doing the computation the first time, you can track what depends on what. Then you save *that* information out. Here's an This sounds suspiciously like Writer to me. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED] system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED] electrical and computer engineering, carnegie mellon universityKF8NH ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: POSIX AIO (asych I/O) ...
Hello, Haskell 101 question! I discovered that aio_error returns "errno" rather -1. Of course, my aio_error binding is called before my aio_return binding (aio calling sequence "protocol"). I have worked on Posix OS's for quite a while but am unhappy with non-consistent errno handling ;^(. In any case, I modified my aio_error binding implementation to have a "AIOCB -> IO Errno" signature: aioError :: AIOCB -> IO Errno aioError aiocb = do allocaBytes (#const sizeof(struct aiocb)) $ \ p_aiocb -> do poke p_aiocb aiocb errno <- throwErrnoIfMinus1 "aioError" (c_aio_error p_aiocb) return (errno) foreign import ccall safe "aio.h aio_error" c_aio_error :: Ptr AIOCB -> IO Errno "ghc" thinks that "Errno" should be an instance of "Num": System/Posix/Aio.hsc:117:15: No instance for (Num Errno) Why? Vasili On Tue, Jul 1, 2008 at 2:42 AM, Galchin, Vasili <[EMAIL PROTECTED]> wrote: > Hello, > >I am also testing my aio support. The aio_write binding seems to > work ok .. as well as aio_error, Aio_return is a problem child. I think I > wrote a really simple binding. I always receive nbytes as 0. I have been > staring at the code hoping to catch a stupid mistake. I put putStrLn's in > the code. .Here is the code ... > > aioReturn :: AIOCB -> IO (AIOCB, ByteCount) > aioReturn aiocb = do >allocaBytes (#const sizeof(struct aiocb)) $ \ p_aiocb -> do > poke p_aiocb aiocb > count <- throwErrnoIfMinus1 "aioReturn" (c_aio_return p_aiocb) > aiocb <- peek p_aiocb > return (aiocb, fromIntegral count) > > foreign import ccall safe "aio.h aio_return" > c_aio_return :: Ptr AIOCB -> IO CInt > > Maybe someone can spot something that I haven't. > > Thanks, Vasili > ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: POSIX AIO (asych I/O) ...
On 2008 Jul 2, at 1:42, Galchin, Vasili wrote: errno <- throwErrnoIfMinus1 "aioError" (c_aio_error p_aiocb) "ghc" thinks that "Errno" should be an instance of "Num": System/Posix/Aio.hsc:117:15: No instance for (Num Errno) I expect so it can compare it to -1(throwErrnoIfMinusOne). But if the return value is actually an errno and not -1 to indicate error (which it is if I read the manpage correctly), you don't want throwErrnoIfMinus1 anyway; I suspect you want to wrap the return value of c_aio_return (which should be IO CInt) in an Errno constructor, then use errnoToIOError if you really want to raise an IOError. (What were you expecting for "count"? I see none, just an errno.) Note that it *never* returns -1; it returns 0 for successful completion for the aiocb, EINPROGRESS if it's still working, and the appropriate errno if it failed. You might want to decide if you want to use the aio_return style interface or something more Haskell-ish before designing this part of the API. If you want to stick close to the C interface: aioReturn :: AIOCB -> IO (AIOCB, Errno) aioReturn aiocb = do allocaBytes (#const sizeof(struct aiocb)) $ \ p_aiocb -> do poke p_aiocb aiocb err <- c_aio_return p_aiocb aiocb <- peek p_aiocb return (aiocb, Errno err) I'd actually consider something more Haskellish, e.g. a variant of StateT IO where the state is the aiocb and errno, the errno initialized to eINPROGRESS and set by aioReturn and aioError (and once aioReturn is called, it can't be called again so return the cached value if needed). -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED] system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED] electrical and computer engineering, carnegie mellon universityKF8NH ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: POSIX AIO (asych I/O) ...
On Wed, 2008-07-02 at 02:07 -0400, Brandon S. Allbery KF8NH wrote: > > On 2008 Jul 2, at 1:42, Galchin, Vasili wrote: > > > errno <- throwErrnoIfMinus1 "aioError" (c_aio_error p_aiocb) > > > > "ghc" thinks that "Errno" should be an instance of "Num": > > > > System/Posix/Aio.hsc:117:15: > > No instance for (Num Errno) > > > I expect so it can compare it to -1(throwErrnoIfMinusOne). But if the > return value is actually an errno and not -1 to indicate error (which > it is if I read the manpage correctly), you don't want > throwErrnoIfMinus1 anyway; I suspect you want to wrap the return value > of c_aio_return (which should be IO CInt) in an Errno constructor, > then use errnoToIOError if you really want to raise an IOError. > > > (What were you expecting for "count"? I see none, just an errno.) > > > Note that it *never* returns -1; it returns 0 for successful > completion for the aiocb, EINPROGRESS if it's still working, and the > appropriate errno if it failed. It seems as though it can return -1 if given non-sensical input. But in that case, the nicely type-correct thing to do would still be to have the C binding return a CInt, and wrap that after the call to throwErrnoIfMinus1 (in this case, `errno' still refers to the global errno, set to EINVAL). jcc ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: POSIX AIO (asych I/O) ...
On 2008 Jul 2, at 2:15, Jonathan Cast wrote: It seems as though it can return -1 if given non-sensical input. But in The POSIX spec says it returns EINVAL in that case. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED] system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED] electrical and computer engineering, carnegie mellon universityKF8NH ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: POSIX AIO (asych I/O) ...
On Wed, 2008-07-02 at 02:17 -0400, Brandon S. Allbery KF8NH wrote: > On 2008 Jul 2, at 2:15, Jonathan Cast wrote: > > > It seems as though it can return -1 if given non-sensical input. > > But in > > The POSIX spec says it returns EINVAL in that case. Are you sure? A little googling picks up e.g. HP docs [1] that state RETURN VALUE If the aiocb is invalid or if no asynchronous I/O operation is enqueued for the aiocb, aio_error() returns -1 and errno is set to indicate the error It may be non-POSIX, but I'd like to see some verbiage for which HP/UX's behavior isn't the most natural interpretation. jcc [1] http://docs.hp.com/en/B9106-90009/aio_error.2.html ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: POSIX AIO (asych I/O) ...
Thanks, Brandon!! I understand most of what you say but let me ponder! Kind regards, Vasili On Wed, Jul 2, 2008 at 1:07 AM, Brandon S. Allbery KF8NH < [EMAIL PROTECTED]> wrote: > > On 2008 Jul 2, at 1:42, Galchin, Vasili wrote: > > errno <- throwErrnoIfMinus1 "aioError" (c_aio_error p_aiocb) > > "ghc" thinks that "Errno" should be an instance of "Num": > > System/Posix/Aio.hsc:117:15: > No instance for (Num Errno) > > > I expect so it can compare it to -1(throwErrnoIfMinusOne). But if the > return value is actually an errno and not -1 to indicate error (which it is > if I read the manpage correctly), you don't want throwErrnoIfMinus1 anyway; > I suspect you want to wrap the return value of c_aio_return (which should be > IO CInt) in an Errno constructor, then use errnoToIOError if you really want > to raise an IOError. > > (What were you expecting for "count"? I see none, just an errno.) > > Note that it *never* returns -1; it returns 0 for successful completion for > the aiocb, EINPROGRESS if it's still working, and the appropriate errno if > it failed. > > You might want to decide if you want to use the aio_return style interface > or something more Haskell-ish before designing this part of the API. If you > want to stick close to the C interface: > > aioReturn :: AIOCB -> IO (AIOCB, Errno) > aioReturn aiocb = do >allocaBytes (#const sizeof(struct aiocb)) $ \ p_aiocb -> do > poke p_aiocb aiocb > err <- c_aio_return p_aiocb > aiocb <- peek p_aiocb > return (aiocb, Errno err) > I'd actually consider something more Haskellish, e.g. a variant of StateT > IO where the state is the aiocb and errno, the errno initialized to > eINPROGRESS and set by aioReturn and aioError (and once aioReturn is called, > it can't be called again so return the cached value if needed). > > -- > brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED] > system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED] > electrical and computer engineering, carnegie mellon universityKF8NH > > > ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe