Re: Records in Haskell
Thank you Nils for those excellent links. Yitz would like Agda's module/record setup which allows for multiple modules in a single file. Records are yet another local module. The neat thing is, that like any module you can open it, or put it into the scope of your current module for convenient use that avoids the needs for qualifiers (see Record opening example). Johan, I think Agda's use of records might also be what you are getting at. On Tue, Jan 17, 2012 at 7:10 AM, Nils Anders Danielsson n...@chalmers.se wrote: On 2012-01-16 19:16, Yitzchak Gale wrote: Allow nested modules. [...] Perhaps Agda's module/record system can provide some inspiration: http://wiki.portal.chalmers.se/agda/pmwiki.php?n=ReferenceManual.Modules http://wiki.portal.chalmers.se/agda/pmwiki.php?n=ReferenceManual.Records (I don't think the wiki pages above are entirely complete/up to date, but for the purposes of this discussion they should do.) -- /NAD ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Records in Haskell
2012/1/18 Simon Peyton-Jones simo...@microsoft.com: | Has *is* a type class. It can be used and abused like any other. | Record members with the same key ought to have the same semantics; the | programmer must ensure this, not just call them all x or the like. | | Weak types these are not. The selector type is well-defined. The value | type is well-defined. The record type is well-defined, but of course | we define a type-class to let it be polymorphic. I want to mention that the issue Greg raises here is tackled under Representation hiding. The way we currently prevent random clients of a data type from selecting its foo field is by hiding the record selector foo. Similarly for its data constructors. This is Haskell's way of doing data abstraction; it may not be the best way, but it's Haskell's way. The trouble with instance declarations is that they are *always* exported. No hiding. Under Representation hiding I suggest that * If the record selector foo is in scope (by any name), then the corresponding Has instance is in scope too and vice versa. That would match up with Haskell's hiding mechanisms precisely, albeit at the cost of having an ad-hoc rule for Has instances. Simon I think these are separate issues. To use the analogy with functions again, imagine we could do this: module A where data Foo = Foo foo :: Foo - Int foo Foo = 9 module B where bar :: HasFunction a foo (a - Int) = a - Int bar a = foo a module Main where import A import B main = print $ bar Foo Would we like it? The problem isn't that you can access unexported functions (though that would also be a problem), the problem is that you're overloading functions based on only their name and type, and the foo you find might have a different meaning from the one you expected. With type classes, we have a mechanism to ensure that code at point A and code at point B are using the same assumptions. If you declare an instance and it doesn't match the assumptions set out for the class, it's a programmer error. But you can't realistically say don't declare a function with this name and type unless you mean the same thing by it that I mean by it. If we want similar safety for record fields, we could use a similar mechanism. (Again, without addressing the question of what we want, because I don't know.) ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Records in Haskell
2012/1/18 Simon Peyton-Jones simo...@microsoft.com: | Has *is* a type class. It can be used and abused like any other. | Record members with the same key ought to have the same semantics; the | programmer must ensure this, not just call them all x or the like. | | Weak types these are not. The selector type is well-defined. The value | type is well-defined. The record type is well-defined, but of course | we define a type-class to let it be polymorphic. I want to mention that the issue Greg raises here is tackled under Representation hiding. The way we currently prevent random clients of a data type from selecting its foo field is by hiding the record selector foo. Similarly for its data constructors. This is Haskell's way of doing data abstraction; it may not be the best way, but it's Haskell's way. The trouble with instance declarations is that they are *always* exported. No hiding. Under Representation hiding I suggest that * If the record selector foo is in scope (by any name), then the corresponding Has instance is in scope too and vice versa. That would match up with Haskell's hiding mechanisms precisely, albeit at the cost of having an ad-hoc rule for Has instances. Simon I am not just concerned about Has instances from modules not under my control. I am concerned there is a new implicit rule that must be explained to me and that I have no control over: that every record field in the same module with a given label must have the exact same semantics as all others with the same label. Currently we don't have this rule. Currently we have records with the essentialy the same field labels, but with prefixes so they can coexist, and they need not have the same semantics. There is an extra problem with adding this rule: it is common practice to put types that arguably should be spread across multiple modules into one (module often named Types). Some form of this must be done out of necessity in the case of circular references between types that will otherwise not resolve. By default in Yesod, we do this out of necessity for records representing database tables. We call the module Models and users are free to write functions there. Now we have to explain to them that they should not. What use case for abstraction over record fields is too burdensome to use a type class for? Lacking such a compelling use case we are adding implicit complexity that can result in weak-typing for the unwary user with no compelling benefit. The wiki page for overloaded records suggests that users are expected to write code like this for virtual selectors: instance Has Shape area Float where get = area This is a leaky abstraction forcing me to quote function names at the type level. I would rather not be writing this code - explaining this code to someone means delving into implementation details that I don't understand. The overloaded records proposal is vying for extensibility by supporting abstraction over record fields with the same name. For this dubious use case that type classes already satisfies we lose user-friendly implementation of obviously useful functionality like virtual selectors, and also explainability. There is something to be said for the fact that I can quickly comprehend explanations of module-based record systems. I have read over the Overloaded Records proposal several times now and I have the gist of it, but I am still confused on details and need another couple reads to look at all the details instead of glossing over them. So far I have found some details on record implementations in four FP languages. Every single one implements a module-like namespace for records, one after abandoning the abstraction over fields approach. There are differing good approaches to convenient access - I think that is where it is appropriate for Haskell to attempt to take a different approach. ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: strange behavior of let in ghci
On Thu, Jan 19, 2012 at 11:10:09PM -0600, Antoine Latter wrote: On Thu, Jan 19, 2012 at 10:55 PM, Kazu Yamamoto k...@iij.ad.jp wrote: Hello, I met strange behavior of let in ghci 7.0.4. The following works well. You're running into the monomorphism restriction: http://www.haskell.org/haskellwiki/Monomorphism_restriction To be more precise, it's the monomorphism restriction combined with ghci's extended type-defaulting rules: http://www.haskell.org/ghc/docs/7.2.2/html/users_guide/interactive-evaluation.html#extended-default-rules -Brent ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: named pipes
On 12-01-19 02:16 PM, Serge D. Mechveliani wrote: -- Main.hs - hPutStr h1 str hFlush h1 This fails to send a newline. --- fifo2.c - if (fgets(str, BOUND, toA) == NULL) { This refuses to finish until it sees a newline (or BOUND chars, or the eof condition, or an error condition). What really interests me is that if Main.hs is linked with -threaded, the deadlock is unlocked, and both programs proceed to completion. This is because the -threaded runtime goes through garbage collection when idling (such as waiting for hGetLine). Since there is no further reference to h1 by then, GC hCloses it. That unlocks the fgets side. This is fragile and not to be relied on. You will always have further references to h1 in practice. Comparison with C - C - If both programs are in C, then the whole loop of the string exchange (with fifo2.c rewritten into a loop) works as needed, both for the variants with fgets and with `read'. I am not convinced in the case of fgets. I cannot reproduce it. (Oh, I know read has a much better chance, it doesn't wait for a newline.) ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: Runtime performance degradation for multi-threaded C FFI callback
Hello Sanket, What happens if you run this experiment with 5 threads in the C function, and have GHC run RTS with -N7? (e.g. five C threads + seven GHC threads = 12 threads on your 12-core box.) Edward Excerpts from Sanket Agrawal's message of Tue Jan 17 23:31:38 -0500 2012: I posted this issue on StackOverflow today. A brief recap: In the case when C FFI calls back a Haskell function, I have observed sharp increase in total time when multi-threading is enabled in C code (even when total number of function calls to Haskell remain same). In my test, I called a Haskell function 5M times using two scenarios (GHC 7.0.4, RHEL5, 12-core box): - Single-threaded C function: call back Haskell function 5M times - Total time 1.32s - 5 threads in C function: each thread calls back the Haskell function 1M times - so, total is still 5M - Total time 7.79s - Verified that pthread didn't contribute much to the overhead by having the same code call a C function instead, and compared with single-threaded version. So, almost all of the increase in overhead seems to come from GHC runtime. What I want to ask is if this is a known issue for GHC runtime? If not, I will file a bug report for GHC team with code to reproduce it. I don't want to file a duplicate bug report if this is already known issue. I searched through GHC trac using some keywords but didn't see any bugs related to it. StackOverflow post link (has code and details on how to reproduce the issue): http://stackoverflow.com/questions/8902568/runtime-performance-degradation-for-c-ffi-callback-when-pthreads-are-enabled ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Straight-line single assignment in C--
Hello all, I was wondering if the following style of register assignment ever shows up in C-- code generated by GHC: a = R1 I32[a] = 1 a = R2 I32[a] = 2 That is to say, there are two disjoint live ranges of a: we could rename all instances of a in the first and second lines to something different without affecting the semantics (although maybe affecting register allocation and stack spilling.) asdf = R1 I32[asdf] = 1 a = R2 I32[a] = 2 But C-- is not in SSA form, and even when no loops are involved it seems that some naughty code generator could reuse a variable. This is pretty inconvenient, because I want to record this information a = R1 // used only once I32[a] = 1 a = R2 // used only once I32[a] = 2 in a map: a - used only once But since the register names go all the same place this may end in tears. If multiple assignment is rare enough in straight line code, I might be able to take the conservative approach and just say a - used multiple times Which I don't think will cause any problems in the inlining step later. But I don't have a good sense for this. Edward ___ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users