Re: Records in Haskell

2012-01-20 Thread Greg Weber
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-01-20 Thread Gábor Lehel
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-01-20 Thread Greg Weber
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

2012-01-20 Thread Brent Yorgey
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

2012-01-20 Thread Albert Y. C. Lai

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

2012-01-20 Thread Edward Z. Yang
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--

2012-01-20 Thread Edward Z. Yang
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