Re: Records in Haskell

2012-02-25 Thread Anthony Clayden

Wren/all

Please remember SPJ's request on the Records wiki to stick
to the namespace issue. We're trying to make something
better that H98's name clash. We are not trying to build
some ideal polymorphic record system.

To take the field labelled "name": in H98 you have to
declare each record in a different module and import every
module into your application and always refer to "name"
prefixed by the module.

DORF doesn't stop you doing any of that. So if you think of
each "name" being a different meaning, carry on using
multiple modules and module prefixes. That's as easy (or
difficult) as under H98.

You can declare fieldLabel "name" in one module, import it
unqualified into another and declare more records with a
"name" label -- contrary to what somebody was claiming.

Or you can import fieldLabel "name" qualified, and use it as
a selector function on all record types declared using it.
It's just a function like any other imported/qualified
function, for crying out loud!

So if there's 'your' "name" label and 'my' "name", then use
the module/qualification system as you would for any other
scoped name. Then trying to apply My.name to Your.record
will get an instance failure, as usual.

(And by the way, there's no "DORFistas", let's avoid
personalising this. There are people who don't seem to
understand DORF -- both those criticising and those
supporting.)

AntC

- Original Message Follows -
> On 2/25/12 10:18 AM, Gábor Lehel wrote:
> > On Sat, Feb 25, 2012 at 3:54 PM, Barney
> Hilken  wrote: >> After more
> pondering, I finally think I understand what the DORFistas
> want. Here is an example: >>
> >> You want to define records which describe people, and
> include (among other things) a field called "name". There
> might be several different record types with a name field,
> depending on whether the record refers to a customer, an
> employee, a business contact etc., but in each case "name"
> is the name of the person to which the record refers. You
> then write various functions which assume this, such as >>
> >>>spam :: Has r "name" String =>  r ->  String
> >>>spam r = "Dear " ++ r.name ++ "\nHave you
> heard..." >>
> >> Now I want to define records which describe products,
> and I also use a field "name" in the same way, except that
> it is the brand name of the product. I also define
> functions such as >>
> >>>offer :: Has r "name" String =>  r ->  String
> >>>offer r = "Reduced! " ++ r.name ++ " 50%
off!"
> >>
> >> It doesn't make any sense to apply your functions to my
> records or vice-versa, but because we both chose the same
> label, the compiler allows it. Putting the code in
> separate modules makes no difference, since labels are
> global. >
> > Exactly!
> 
> FWIW, this is the concern I alluded to earlier. Namely
> that we may want  to have two (or more), er, 'classes' of
> records--- where a field is  polymorphic over an
> individual class, but we don't want those classes to 
> merge simply because they happened to choose the same name
> and type for  the field.
> 
> I'm not sure it's a good proposal, but it seems like the
> only way to  handle this issue is to (1) introduce a new
> kind for  semantically-oriented field names, and (2) make
> the Has class use that  kind rather than a type-level
> string. By (1), what I mean is that rather  than referring
> to the field as "name", we would declare PersonalName and 
> BrandName and then use those in lieu of the string. And if
> we do that,  then (2) demands that we must somehow make
> explicit which one we mean,  should we want the `name`
> field to be polymorphic for some given record 
> declaration.
> 
> -- 
> Live well,
> ~wren
> 
> ___
> 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-02-25 Thread Anthony Clayden
Whoa! suddenly a deluge over the DORF proposal.

I don't have time to reply fully now, but I must say: Barney
you have got it all wrong.

No, DORF does not attach one class to each label. There is
only one class 'Has', with methods get and set. Each record
decl generates an instance for the combination of
record/field. You can't mix declared and free-standing
labels in the same record. The switch for DORF is at the
module level: in a module either all records and labels use
DORF, or none do (that is, they use H98 style with each
field name being unique).

AntC

- Original Message Follows -
> > My objection is that I'm not sure if there is ever a
> > case where "you really want things to be polymorphic
> over all records".
> 
> Well, I don't have a simple, really convincing example,
> but there are certainly things I want to play with. More
> importantly, DORF automatically attaches one class to each
> label, but this is often not what you want. For example,
> if you have two fields "firstname" and "lastname" the
> associated classes are less useful: what you really want
> is 
> 
> >  class (Has r "firstname" String, Has r "lastname"
> String) => HasPersonalName r
> 
> so that you can define
> 
> >fullname :: HasPersonalName r => r -> String
> >fullname r = r.firstname ++ " " ++ r.lastname
> 
> You may also want to define subclasses to express more
> specific conditions. In general, the compiler cannot
> automatically deduce what is semantically important: you
> need to define it yourself. The Has class is the base on
> which you can build.
> 
> > It doesn't seem like the
> > Haskell way to have the less safe thing as the one
> > that's default and convenient, and to allow the
> > programmer to layer a more-safe thing on top of it if he
> > or she wants to. It seems more like the Haskell way to
> have the safer thing be the default and to require extra
> > work if you want to do something less safe*.
> 
> I think you are using the word "safe" in a slightly
> misleading way. None of this is mathematically unsafe,
> because projections are natural (truly polymorphic). The
> "safety" that is broken here is nothing to do with the
> semantics of the language, it is to do with the semantics
> of the system being implemented, and that is something the
> compiler cannot infer. As my example above shows, it
> doesn't always correspond one to one with the labels.
>  
> The Haskel way is to make things as polymorphic as is
> mathematically safe, even when this goes beyond the
> programmers original intention. You can then restrict this
> polymorphism by giving explicit less general types in the
> same way as in my examples. I think my approach is more
> Haskel like.
> 
> Another important Haskel design consideration is to reuse
> parts of the language where possible, rather than
> introduce new structures. Type classes were originally
> introduced to deal with equality and numeric functions,
> but were reused for many things including monads. My
> approach achieves the same as DORF (and more), but using
> existing language features instead of introducing new
> ones.
> 
> Barney.
> 
> 
> ___
> 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: Increasing number of worker tasks in RTS (GHC 7.4.1) - how to debug?

2012-02-25 Thread Sanket Agrawal
I have to take back what I said about the increase in worker tasks being
related to some Mac OS pthread bug. I can now reproduce the issue on Linux
(Redhat x86_64) too (and cause a segmentation fault once in a while). So,
now, it seems the issue might be due to either some kind of interaction
between GHC RTS, and C pthread mutexes, or a bug in my code.

What I have done is to create a simple test case that reproduces the
increase in number of worker threads with each run of Haskell timer thread
(that syncs with C pthreads). I have put up the code on github with
documentation on how to reproduce the issue:
https://github.com/sanketr/cffitest

I will appreciate feedback on whether it is a bug in my code, or a GHC bug
that needs to be reported.


On Sat, Feb 25, 2012 at 3:41 PM, Sanket Agrawal wrote:

> On further investigation, it seems to be very specific to Mac OS Lion (I
> am running 10.7.3) - all tests were with -N3 option:
>
> - I can reliably crash the code with seg fault or bus error if I create
> more than 8 threads in C FFI (each thread creates its own mutex, for 1-1
> coordination with Haskell timer thread). My iMac has 4 processors. In gdb,
> I can see that the crash happened in __psynch_cvsignal () which seems to be
> related to pthread mutex.
>
> - If I increase the number of C FFI threads (and hence, pthread mutexes)
> to >=7, the number of tasks starts increasing. 8 is the max number of FFI
> threads in my testing where the code runs without crashing. But, it seems
> that there is some kind of pthread mutex related leak. What the timer
> thread does is to fork 8 parallel haskell threads to acquire mutexes from
> each of the C FFI thread. Though the function returns after acquiring,
> collecting data, and releasing mutex, some of the threads seem to be marked
> as active by GC, because of mutex memory leak. Exactly how, I don't know.
>
> - If I keep the number of C FFI threads to <=6, there is no memory leak.
> The number of tasks stays steady.
>
> So, it seems to be pthread library issue (and not a GHC issue). Something
> to keep in mind when developing code on Mac that involves mutex
> coordination with C FFI.
>
>
> On Sat, Feb 25, 2012 at 2:59 PM, Sanket Agrawal 
> wrote:
>
>> I wrote a program that uses a timed thread to collect data from a C
>> producer (using FFI). The number of threads in C producer are fixed (and
>> created at init). One haskell timer thread uses threadDelay to run itself
>> on timed interval. When I look at RTS output after killing the program
>> after couple of timer iterations, I see number of worker tasks increasing
>> with time.
>>
>>  For example, below is an output after 20 iterations of timer event:
>>
>>   MUT time (elapsed)   GC time  (elapsed)
>>   Task  0 (worker) :0.00s(  0.00s)   0.00s(  0.00s)
>>   Task  1 (worker) :0.00s(  0.00s)   0.00s(  0.00s)
>>   ...output until task 37 snipped as it is same as task 1...
>>   Task 38 (worker) :0.07s(  0.09s)   0.00s(  0.00s)
>>   Task 39 (worker) :0.07s(  0.09s)   0.00s(  0.00s)
>>   Task 40 (worker) :0.18s( 10.20s)   0.00s(  0.00s)
>>   Task 41 (worker) :0.18s( 10.20s)   0.00s(  0.00s)
>>   Task 42 (worker) :0.18s( 10.20s)   0.00s(  0.00s)
>>   Task 43 (worker) :0.18s( 10.20s)   0.00s(  0.00s)
>>   Task 44 (worker) :0.52s( 10.74s)   0.00s(  0.00s)
>>   Task 45 (worker) :0.52s( 10.75s)   0.00s(  0.00s)
>>   Task 46 (worker) :0.52s( 10.75s)   0.00s(  0.00s)
>>   Task 47 (bound)  :0.00s(  0.00s)   0.00s(  0.00s)
>>
>>
>> After two iterations of timer event:
>>
>>MUT time (elapsed)   GC time  (elapsed)
>>   Task  0 (worker) :0.00s(  0.00s)   0.00s(  0.00s)
>>   Task  1 (worker) :0.00s(  0.00s)   0.00s(  0.00s)
>>   Task  2 (worker) :0.07s(  0.09s)   0.00s(  0.00s)
>>   Task  3 (worker) :0.07s(  0.09s)   0.00s(  0.00s)
>>   Task  4 (worker) :0.16s(  1.21s)   0.00s(  0.00s)
>>   Task  5 (worker) :0.16s(  1.21s)   0.00s(  0.00s)
>>   Task  6 (worker) :0.16s(  1.21s)   0.00s(  0.00s)
>>   Task  7 (worker) :0.16s(  1.21s)   0.00s(  0.00s)
>>   Task  8 (worker) :0.48s(  1.80s)   0.00s(  0.00s)
>>   Task  9 (worker) :0.48s(  1.81s)   0.00s(  0.00s)
>>   Task 10 (worker) :0.48s(  1.81s)   0.00s(  0.00s)
>>   Task 11 (bound)  :0.00s(  0.00s)   0.00s(  0.00s)
>>
>>
>> Haskell code has one forkIO call to kick off C FFI - C FFI creates 8
>> threads. Runtime options are "-N3 +RTS -s". timer event is kicked off after
>> forkIO. It is for the form (pseudo-code):
>>
>> timerevent  time = run where run = do threadDelay time
>> >> do some work >> run where 
>>
>> I also wrote a simpler code using just

Re: Records in Haskell

2012-02-25 Thread wren ng thornton

On 2/25/12 10:18 AM, Gábor Lehel wrote:

On Sat, Feb 25, 2012 at 3:54 PM, Barney Hilken  wrote:

After more pondering, I finally think I understand what the DORFistas want. 
Here is an example:

You want to define records which describe people, and include (among other things) a field called 
"name". There might be several different record types with a name field, depending on 
whether the record refers to a customer, an employee, a business contact etc., but in each case 
"name" is the name of the person to which the record refers. You then write various 
functions which assume this, such as


   spam :: Has r "name" String =>  r ->  String
   spam r = "Dear " ++ r.name ++ "\nHave you heard..."


Now I want to define records which describe products, and I also use a field 
"name" in the same way, except that it is the brand name of the product. I also 
define functions such as


   offer :: Has r "name" String =>  r ->  String
   offer r = "Reduced! " ++ r.name ++ " 50% off!"


It doesn't make any sense to apply your functions to my records or vice-versa, 
but because we both chose the same label, the compiler allows it. Putting the 
code in separate modules makes no difference, since labels are global.


Exactly!


FWIW, this is the concern I alluded to earlier. Namely that we may want 
to have two (or more), er, 'classes' of records--- where a field is 
polymorphic over an individual class, but we don't want those classes to 
merge simply because they happened to choose the same name and type for 
the field.


I'm not sure it's a good proposal, but it seems like the only way to 
handle this issue is to (1) introduce a new kind for 
semantically-oriented field names, and (2) make the Has class use that 
kind rather than a type-level string. By (1), what I mean is that rather 
than referring to the field as "name", we would declare PersonalName and 
BrandName and then use those in lieu of the string. And if we do that, 
then (2) demands that we must somehow make explicit which one we mean, 
should we want the `name` field to be polymorphic for some given record 
declaration.


--
Live well,
~wren

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Records in Haskell

2012-02-25 Thread wren ng thornton

On 2/24/12 5:40 PM, Johan Tibell wrote:

I share Greg's concerns about polymorphic projections. For example,
given a function

 sort :: Ord a =>  ...

we don't allow any 'a' that happens to export a operator that's
spelled<= to be passed to 'sort'. We have the user explicitly create
an instance and thereby defining that their<= is e.g. a strict weak
ordering and thus make sense when used with 'sort'. This explicitness
is useful, it communicates the contract of the function to the reader
and lets us catch mistakes in a way that automatically polymorphic
projections don't.

Automatically polymorphic projections feels like Go's structural
polymorphism, C++'s templates or C's automatic numeric coercions, and
I'm worried it'll lead to problems when used at scale. They're not
required to solve the problem we're trying to solve, so lets hurry
slowly and don't bake them in together with the namespacing problem.
At the very least use two different LANGUAGE pragmas so users can have
one without the other.


+1.

I'm not sure that I like the current proposals for how to control the 
non/automatic-ness of polymorphism (for reasons I can spell out later, 
if desired). But we definitely want to have something that's a bit more 
cultured than simply making all record projectors polymorphic over records.


--
Live well,
~wren

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Understanding the -A and the -H flags

2012-02-25 Thread wren ng thornton

On 2/25/12 11:51 AM, Johan Tibell wrote:

Perhaps it would make sense to document the actual algorithm used to
set -A given -H (with and without argument.)


+1. I've always been a bit hazy on how the two are related.

--
Live well,
~wren

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Records in Haskell

2012-02-25 Thread Isaac Dupree

On 02/25/2012 05:10 PM, Gábor Lehel wrote:

Could you elaborate on this? (What's the way I don't want? What do you
mean by field-name-prefixes versus new-style overloading?) With DORF I
have control over which fields are polymorphic over which records,
very much like how I have control over which classes are polymorphic
over which types. That's what I want.


Darn, I misinterpreted DORF.  There was too much text and too many options.

Tell me if I'm correct:
A. Every declaration with record syntax creates Has instances for all 
fields [1].
B. "Has", "get" and "set" may not be written by users (guessing due to 
representation-hiding fail).

C. You create functions using "fieldLabel name [...]"
D. which have the magical effect of, when in scope unqualified, causing 
data types defined with record syntax to be accessible through that 
particular fieldLabel function (and no other way).
E. (When two fieldLabels of the same name are in scope unqualified, 
declaring a record containing that name is an error.)
F. So adding an import (for some other reason for your code) that 
happens to include a fieldLabel can make your records accidentally be 
more visible, rather than be compile-error or no-effect.


I feel weird about record fields having an option that depends on 
whether something's in scope and cannot be controlled syntactically. 
Maybe we can fix that without making the syntax worse.


G. It is possible (but rather ugly) to use dot-notation when there are 
multiple fieldNames of the same name in scope. [2]


Hmm.  Maybe this is Haskelly as well as convenient enough.  Did I get 
everything right?  What do you think about my concern about F?


[1] 
http://hackage.haskell.org/trac/ghc/wiki/Records/DeclaredOverloadedRecordFields/ImplementorsView
[2] 
http://hackage.haskell.org/trac/ghc/wiki/Records/DeclaredOverloadedRecordFields/DotPostfix#UsingDotnotationamongstqualifiednames


___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Records in Haskell

2012-02-25 Thread Barney Hilken
> My objection is that I'm not sure if there is ever a case where "you
> really want things to be polymorphic over all records".

Well, I don't have a simple, really convincing example, but there are certainly 
things I want to play with.
More importantly, DORF automatically attaches one class to each label, but this 
is often not what you want. For example, if you have two fields "firstname" and 
"lastname" the associated classes are less useful: what you really want is 

>  class (Has r "firstname" String, Has r "lastname" String) => 
> HasPersonalName r

so that you can define

>   fullname :: HasPersonalName r => r -> String
>   fullname r = r.firstname ++ " " ++ r.lastname

You may also want to define subclasses to express more specific conditions. In 
general, the compiler cannot automatically deduce what is semantically 
important: you need to define it yourself. The Has class is the base on which 
you can build.

> It doesn't seem like the
> Haskell way to have the less safe thing as the one that's default and
> convenient, and to allow the programmer to layer a more-safe thing on
> top of it if he or she wants to. It seems more like the Haskell way to
> have the safer thing be the default and to require extra work if you
> want to do something less safe*.

I think you are using the word "safe" in a slightly misleading way. None of 
this is mathematically unsafe, because projections are natural (truly 
polymorphic). The "safety" that is broken here is nothing to do with the 
semantics of the language, it is to do with the semantics of the system being 
implemented, and that is something the compiler cannot infer. As my example 
above shows, it doesn't always correspond one to one with the labels.
 
The Haskel way is to make things as polymorphic as is mathematically safe, even 
when this goes beyond the programmers original intention. You can then restrict 
this polymorphism by giving explicit less general types in the same way as in 
my examples. I think my approach is more Haskel like.

Another important Haskel design consideration is to reuse parts of the language 
where possible, rather than introduce new structures. Type classes were 
originally introduced to deal with equality and numeric functions, but were 
reused for many things including monads. My approach achieves the same as DORF 
(and more), but using existing language features instead of introducing new 
ones.

Barney.


___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Records in Haskell

2012-02-25 Thread Gábor Lehel
On Sat, Feb 25, 2012 at 10:09 PM, Isaac Dupree
 wrote:
> On 02/25/2012 10:18 AM, Gábor Lehel wrote:
>>>
>>> This seems to me a much simpler approach than building the mechanism in
>>> to the language as DORF does, and it's also more general, because it isn't
>>> hard linked to the module system. Does it have any disadvantages?
>>
>>
>> I can't tell offhand whether it has any drawbacks with respect to
>> expressiveness. It seems to be a good solution to the stated problem,
>> so thank you for proposing it.
>>
>> My objection is that I'm not sure if there is ever a case where "you
>> really want things to be polymorphic over all records". There is
>> nothing (as far as I know) analogous to this kind of implicit
>> name-based polymorphism anywhere in Haskell. [...]
>
>
> True enough.  But DORF doesn't, IMHO, really solve this concern.  If you
> choose to use DORF, then your PersonalName and BrandNames will still be
> overloaded in just the way you don't want.  The only way to avoid this is a
> pretty arbitrary stylistic decision whether to use Haskell98-style
> field-name-prefixes or use new-style overloading.

Could you elaborate on this? (What's the way I don't want? What do you
mean by field-name-prefixes versus new-style overloading?) With DORF I
have control over which fields are polymorphic over which records,
very much like how I have control over which classes are polymorphic
over which types. That's what I want.

>
> Even SORF is better than, say, C++ overloading in the sense that adding
> another overload in SORF cannot cause code not to compile, nor change its
> behaviour.

Sure.

>
> Convince me otherwise.
>

Your position seems to be that unless there is some kind of grave
blocking problem with SORF, then we should go with SORF. I don't
really understand this. I think we should go with the best solution
available. I think DORF is a better solution than SORF, so we should
rather go with DORF than SORF. You've just admitted that there is no
actual use case for the behaviour of SORF, as opposed to that of DORF.
What am I missing?

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Records in Haskell

2012-02-25 Thread Isaac Dupree

On 02/25/2012 10:18 AM, Gábor Lehel wrote:

This seems to me a much simpler approach than building the mechanism in to the 
language as DORF does, and it's also more general, because it isn't hard linked 
to the module system. Does it have any disadvantages?


I can't tell offhand whether it has any drawbacks with respect to
expressiveness. It seems to be a good solution to the stated problem,
so thank you for proposing it.

My objection is that I'm not sure if there is ever a case where "you
really want things to be polymorphic over all records". There is
nothing (as far as I know) analogous to this kind of implicit
name-based polymorphism anywhere in Haskell. [...]


True enough.  But DORF doesn't, IMHO, really solve this concern.  If you 
choose to use DORF, then your PersonalName and BrandNames will still be 
overloaded in just the way you don't want.  The only way to avoid this 
is a pretty arbitrary stylistic decision whether to use Haskell98-style 
field-name-prefixes or use new-style overloading.


Even SORF is better than, say, C++ overloading in the sense that adding 
another overload in SORF cannot cause code not to compile, nor change 
its behaviour.


Convince me otherwise.

-Isaac

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Increasing number of worker tasks in RTS (GHC 7.4.1) - how to debug?

2012-02-25 Thread Sanket Agrawal
On further investigation, it seems to be very specific to Mac OS Lion (I am
running 10.7.3) - all tests were with -N3 option:

- I can reliably crash the code with seg fault or bus error if I create
more than 8 threads in C FFI (each thread creates its own mutex, for 1-1
coordination with Haskell timer thread). My iMac has 4 processors. In gdb,
I can see that the crash happened in __psynch_cvsignal () which seems to be
related to pthread mutex.

- If I increase the number of C FFI threads (and hence, pthread mutexes) to
>=7, the number of tasks starts increasing. 8 is the max number of FFI
threads in my testing where the code runs without crashing. But, it seems
that there is some kind of pthread mutex related leak. What the timer
thread does is to fork 8 parallel haskell threads to acquire mutexes from
each of the C FFI thread. Though the function returns after acquiring,
collecting data, and releasing mutex, some of the threads seem to be marked
as active by GC, because of mutex memory leak. Exactly how, I don't know.

- If I keep the number of C FFI threads to <=6, there is no memory leak.
The number of tasks stays steady.

So, it seems to be pthread library issue (and not a GHC issue). Something
to keep in mind when developing code on Mac that involves mutex
coordination with C FFI.


On Sat, Feb 25, 2012 at 2:59 PM, Sanket Agrawal wrote:

> I wrote a program that uses a timed thread to collect data from a C
> producer (using FFI). The number of threads in C producer are fixed (and
> created at init). One haskell timer thread uses threadDelay to run itself
> on timed interval. When I look at RTS output after killing the program
> after couple of timer iterations, I see number of worker tasks increasing
> with time.
>
>  For example, below is an output after 20 iterations of timer event:
>
>   MUT time (elapsed)   GC time  (elapsed)
>   Task  0 (worker) :0.00s(  0.00s)   0.00s(  0.00s)
>   Task  1 (worker) :0.00s(  0.00s)   0.00s(  0.00s)
>   ...output until task 37 snipped as it is same as task 1...
>   Task 38 (worker) :0.07s(  0.09s)   0.00s(  0.00s)
>   Task 39 (worker) :0.07s(  0.09s)   0.00s(  0.00s)
>   Task 40 (worker) :0.18s( 10.20s)   0.00s(  0.00s)
>   Task 41 (worker) :0.18s( 10.20s)   0.00s(  0.00s)
>   Task 42 (worker) :0.18s( 10.20s)   0.00s(  0.00s)
>   Task 43 (worker) :0.18s( 10.20s)   0.00s(  0.00s)
>   Task 44 (worker) :0.52s( 10.74s)   0.00s(  0.00s)
>   Task 45 (worker) :0.52s( 10.75s)   0.00s(  0.00s)
>   Task 46 (worker) :0.52s( 10.75s)   0.00s(  0.00s)
>   Task 47 (bound)  :0.00s(  0.00s)   0.00s(  0.00s)
>
>
> After two iterations of timer event:
>
>MUT time (elapsed)   GC time  (elapsed)
>   Task  0 (worker) :0.00s(  0.00s)   0.00s(  0.00s)
>   Task  1 (worker) :0.00s(  0.00s)   0.00s(  0.00s)
>   Task  2 (worker) :0.07s(  0.09s)   0.00s(  0.00s)
>   Task  3 (worker) :0.07s(  0.09s)   0.00s(  0.00s)
>   Task  4 (worker) :0.16s(  1.21s)   0.00s(  0.00s)
>   Task  5 (worker) :0.16s(  1.21s)   0.00s(  0.00s)
>   Task  6 (worker) :0.16s(  1.21s)   0.00s(  0.00s)
>   Task  7 (worker) :0.16s(  1.21s)   0.00s(  0.00s)
>   Task  8 (worker) :0.48s(  1.80s)   0.00s(  0.00s)
>   Task  9 (worker) :0.48s(  1.81s)   0.00s(  0.00s)
>   Task 10 (worker) :0.48s(  1.81s)   0.00s(  0.00s)
>   Task 11 (bound)  :0.00s(  0.00s)   0.00s(  0.00s)
>
>
> Haskell code has one forkIO call to kick off C FFI - C FFI creates 8
> threads. Runtime options are "-N3 +RTS -s". timer event is kicked off after
> forkIO. It is for the form (pseudo-code):
>
> timerevent  time = run where run = do threadDelay time >>
> do some work >> run where 
>
> I also wrote a simpler code using just timer event (fork one timer event,
> and run another timer event after that), but didn't see any tasks in RTS
> output.
>
> I tried searching GHC page for documentation on RTS output, but didn't
> find anything that could help me debug above issue. I suspect that timer
> event is the root cause of increasing number of tasks (with all but last 9
> tasks idle -  I guess 8 tasks belong to C FFI, and one task to timerevent
> thread), and hence, memory leak.
>
> I will appreciate pointers on how to debug it. The timerevent does forkIO
> a call to send collected data from C FFI to a db server, but disabling that
> fork still results in the issue of increasing number of tasks. So, it seems
> strongly correlated with timer event though I am unable to reproduce it
> with a simpler version of timer event (which removes mvar sync/callback
> from C FFI).
>
___
Glasgo

Increasing number of worker tasks in RTS (GHC 7.4.1) - how to debug?

2012-02-25 Thread Sanket Agrawal
I wrote a program that uses a timed thread to collect data from a C
producer (using FFI). The number of threads in C producer are fixed (and
created at init). One haskell timer thread uses threadDelay to run itself
on timed interval. When I look at RTS output after killing the program
after couple of timer iterations, I see number of worker tasks increasing
with time.

 For example, below is an output after 20 iterations of timer event:

  MUT time (elapsed)   GC time  (elapsed)
  Task  0 (worker) :0.00s(  0.00s)   0.00s(  0.00s)
  Task  1 (worker) :0.00s(  0.00s)   0.00s(  0.00s)
  ...output until task 37 snipped as it is same as task 1...
  Task 38 (worker) :0.07s(  0.09s)   0.00s(  0.00s)
  Task 39 (worker) :0.07s(  0.09s)   0.00s(  0.00s)
  Task 40 (worker) :0.18s( 10.20s)   0.00s(  0.00s)
  Task 41 (worker) :0.18s( 10.20s)   0.00s(  0.00s)
  Task 42 (worker) :0.18s( 10.20s)   0.00s(  0.00s)
  Task 43 (worker) :0.18s( 10.20s)   0.00s(  0.00s)
  Task 44 (worker) :0.52s( 10.74s)   0.00s(  0.00s)
  Task 45 (worker) :0.52s( 10.75s)   0.00s(  0.00s)
  Task 46 (worker) :0.52s( 10.75s)   0.00s(  0.00s)
  Task 47 (bound)  :0.00s(  0.00s)   0.00s(  0.00s)


After two iterations of timer event:

   MUT time (elapsed)   GC time  (elapsed)
  Task  0 (worker) :0.00s(  0.00s)   0.00s(  0.00s)
  Task  1 (worker) :0.00s(  0.00s)   0.00s(  0.00s)
  Task  2 (worker) :0.07s(  0.09s)   0.00s(  0.00s)
  Task  3 (worker) :0.07s(  0.09s)   0.00s(  0.00s)
  Task  4 (worker) :0.16s(  1.21s)   0.00s(  0.00s)
  Task  5 (worker) :0.16s(  1.21s)   0.00s(  0.00s)
  Task  6 (worker) :0.16s(  1.21s)   0.00s(  0.00s)
  Task  7 (worker) :0.16s(  1.21s)   0.00s(  0.00s)
  Task  8 (worker) :0.48s(  1.80s)   0.00s(  0.00s)
  Task  9 (worker) :0.48s(  1.81s)   0.00s(  0.00s)
  Task 10 (worker) :0.48s(  1.81s)   0.00s(  0.00s)
  Task 11 (bound)  :0.00s(  0.00s)   0.00s(  0.00s)


Haskell code has one forkIO call to kick off C FFI - C FFI creates 8
threads. Runtime options are "-N3 +RTS -s". timer event is kicked off after
forkIO. It is for the form (pseudo-code):

timerevent  time = run where run = do threadDelay time >>
do some work >> run where 

I also wrote a simpler code using just timer event (fork one timer event,
and run another timer event after that), but didn't see any tasks in RTS
output.

I tried searching GHC page for documentation on RTS output, but didn't find
anything that could help me debug above issue. I suspect that timer event
is the root cause of increasing number of tasks (with all but last 9 tasks
idle -  I guess 8 tasks belong to C FFI, and one task to timerevent
thread), and hence, memory leak.

I will appreciate pointers on how to debug it. The timerevent does forkIO a
call to send collected data from C FFI to a db server, but disabling that
fork still results in the issue of increasing number of tasks. So, it seems
strongly correlated with timer event though I am unable to reproduce it
with a simpler version of timer event (which removes mvar sync/callback
from C FFI).
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Understanding the -A and the -H flags

2012-02-25 Thread Johan Tibell
Hi!

I'm trying to understand the interaction between the -A and -H RTS
flags. The documentation at

  http://www.haskell.org/ghc/docs/7.4.1/html/users_guide/runtime-control.html

says that if you use -H (with or without an argument) it implicitly
implies some value of -A. However, it's not clear to me what value -A
will get and how that value is related to the value of -H. For
example, if I set the suggested heap size to 1G, using -H1G, surely
the size of the nursery (-A) won't be "whatever is left over," but
something more reasonable e.g. the size of the L2 cache?

Perhaps it would make sense to document the actual algorithm used to
set -A given -H (with and without argument.)

Cheers,
Johan

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Records in Haskell

2012-02-25 Thread Gábor Lehel
On Sat, Feb 25, 2012 at 3:54 PM, Barney Hilken  wrote:
> After more pondering, I finally think I understand what the DORFistas want. 
> Here is an example:
>
> You want to define records which describe people, and include (among other 
> things) a field called "name". There might be several different record types 
> with a name field, depending on whether the record refers to a customer, an 
> employee, a business contact etc., but in each case "name" is the name of the 
> person to which the record refers. You then write various functions which 
> assume this, such as
>
>>       spam :: Has r "name" String => r -> String
>>       spam r = "Dear " ++ r.name ++ "\nHave you heard..."
>
> Now I want to define records which describe products, and I also use a field 
> "name" in the same way, except that it is the brand name of the product. I 
> also define functions such as
>
>>       offer :: Has r "name" String => r -> String
>>       offer r = "Reduced! " ++ r.name ++ " 50% off!"
>
> It doesn't make any sense to apply your functions to my records or 
> vice-versa, but because we both chose the same label, the compiler allows it. 
> Putting the code in separate modules makes no difference, since labels are 
> global.

Exactly!

>
>
> Here is a simple solution, using SORF:
>
> The real problem is that the polymorphism of spam and offer is too general. 
> We should each define new classes
>
>>       class Has r "name" String => HasPersonalName r
>>       class Has r "name" String => HasBrandName r
>
> and make  each of our record types an instance of this class
>
>>       instance HasPersonalName EmployeeRecord
>>       instance HasPersonalName CustomerRecord
>>       instance HasBrandName FoodRecord
>
> then we can define functions with a more specific polymorphism
>
>>       spam :: HasPersonalName r => r -> String
>>       spam r = "Dear " ++ r.name ++ "\nHave you heard..."
>
>>       offer :: HasBrandName r => r -> String
>>       offer r = "Reduced! " ++ r.name ++ " 50% off!"
>
> Now there is no danger of confusing the two uses of "name", because my 
> records are not instances of HasPersonalName, they are instances of 
> HasBrandName. You only use the class Has if you really want things to be 
> polymorphic over all records, otherwise you use the more specific class.
>
>
> This seems to me a much simpler approach than building the mechanism in to 
> the language as DORF does, and it's also more general, because it isn't hard 
> linked to the module system. Does it have any disadvantages?

I can't tell offhand whether it has any drawbacks with respect to
expressiveness. It seems to be a good solution to the stated problem,
so thank you for proposing it.

My objection is that I'm not sure if there is ever a case where "you
really want things to be polymorphic over all records". There is
nothing (as far as I know) analogous to this kind of implicit
name-based polymorphism anywhere in Haskell. It doesn't seem like the
Haskell way to have the less safe thing as the one that's default and
convenient, and to allow the programmer to layer a more-safe thing on
top of it if he or she wants to. It seems more like the Haskell way to
have the safer thing be the default and to require extra work if you
want to do something less safe*. In this specific case, is there any
actual use case for global implicitly-polymorphic-by-name record
fields, where that is actually what you want, and where the DORFish
way which is analogous to classes-and-instances wouldn't be
appropriate?

* (Now granted, if pure code versus unsafePerformIO is white versus
black, then this is shade-of-gray versus
slightly-darker-shade-of-gray, but the principle is the same.)

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Records in Haskell

2012-02-25 Thread Barney Hilken
After more pondering, I finally think I understand what the DORFistas want. 
Here is an example:

You want to define records which describe people, and include (among other 
things) a field called "name". There might be several different record types 
with a name field, depending on whether the record refers to a customer, an 
employee, a business contact etc., but in each case "name" is the name of the 
person to which the record refers. You then write various functions which 
assume this, such as

>   spam :: Has r "name" String => r -> String
>   spam r = "Dear " ++ r.name ++ "\nHave you heard..."

Now I want to define records which describe products, and I also use a field 
"name" in the same way, except that it is the brand name of the product. I also 
define functions such as

>   offer :: Has r "name" String => r -> String
>   offer r = "Reduced! " ++ r.name ++ " 50% off!"

It doesn't make any sense to apply your functions to my records or vice-versa, 
but because we both chose the same label, the compiler allows it. Putting the 
code in separate modules makes no difference, since labels are global.


Here is a simple solution, using SORF:

The real problem is that the polymorphism of spam and offer is too general. We 
should each define new classes

>   class Has r "name" String => HasPersonalName r
>   class Has r "name" String => HasBrandName r

and make  each of our record types an instance of this class

>   instance HasPersonalName EmployeeRecord
>   instance HasPersonalName CustomerRecord
>   instance HasBrandName FoodRecord

then we can define functions with a more specific polymorphism

>   spam :: HasPersonalName r => r -> String
>   spam r = "Dear " ++ r.name ++ "\nHave you heard..."

>   offer :: HasBrandName r => r -> String
>   offer r = "Reduced! " ++ r.name ++ " 50% off!"

Now there is no danger of confusing the two uses of "name", because my records 
are not instances of HasPersonalName, they are instances of HasBrandName. You 
only use the class Has if you really want things to be polymorphic over all 
records, otherwise you use the more specific class.


This seems to me a much simpler approach than building the mechanism in to the 
language as DORF does, and it's also more general, because it isn't hard linked 
to the module system. Does it have any disadvantages?

Barney.


___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Records in Haskell

2012-02-25 Thread Gábor Lehel
2012/2/25 Gábor Lehel :
> Please correct me if I've misunderstood or mischaracterized any aspect of 
> DORF.

Okay, I did end up misunderstanding and mischaracterizing at least two
aspects of DORF.

Re-reading the wiki page:

http://hackage.haskell.org/trac/ghc/wiki/Records/DeclaredOverloadedRecordFields

it's clear that you would not have to write fieldLabel declarations
for every single field of every single record, only for the ones you
wish to be shared and usable polymorphically. By default, fields of
individual records would be specific to that record (monomorphic in
the type of the record), except if there is a fieldLabel declaration
for them in scope in which case they would be considered instances of
it. (I hope I have it right this time...)

So the difference between DORF and my variant would be:

DORF: Fields are record-specific (monomorphic in the record type) by
default; having a field be polymorphic requires writing a fieldLabel
declaration and having it in scope when the record is declared; if a
matching fieldLabel is in scope the field is automatically considered
shared and polymorphic in the record type. In other words, you have to
write the "classes" explicitly, but the "instances" are inferred
automatically.

Me: Declaring a record always implies fieldLabel declarations for each
of its fields (record-specific, monomorphic-in-the-record-type fields
are not possible); these are always *new* fieldLabels, which are not
considered to be the same as previous ones and cannot be used
interchangeably with them; to re-use an existing fieldLabel for a
field of your record you must use explicit syntax. In other words,
here the "classes" are automatic, but the "instances" are explicit.

It wasn't clear to me before that DORF retains record-monomorphic
fields, while my variant does away with them. In DORF you can
presumably still use a record-monomorphic field selector to help infer
the concrete type of the record (whereas with polymorphic fields
inference goes in the other direction). Also, while in both variants
it is possible to avoid re-using an existing "field class" for your
record, in my variant it's not possible to prevent a downstream record
from re-using your "field class" (whereas record-monomorphic fields by
definition can't have further instances). So in effect in DORF inside
of record declarations you can have two types of fields,
record-polymorphic and record-monomorphic, along with separate
top-level fieldLabel declarations to declare which ones are the
polymorphic fields; while in my variant inside of records you can have
two types of fields, "classes" and "instances", with explicit syntax
to indicate which ones are the instances. Retaining record-monomorphic
fields seems like a flexibility-versus-consistency tradeoff: in DORF
you have two types of fields with opposite behaviour with respect to
type inference, whereas with my variant you only have one.

One troubling consequence of DORF -- again, if I'm understanding
things correctly -- is that due to implicit field instances a module
import can change the meaning of your program: a record field which
was considered record-monomorphic for lack of a matching fieldLabel
declaration will be considered polymorphic is one is imported. My
variant avoids this.

The other aspect of DORF which I mischaracterized in my previous email
is that fieldLabel declarations don't look like

fieldLabel name :: Text

rather, they look like

fieldLabel name :: r -> Text

where r stands for the type of the record. The implications of this
are not clear to me. As Henrik's email helped me realize, I'm
completely clueless with regards to how type variables are scoped and
handled in DORF. I also don't know how my proposed modifications would
affect it. So I'll go back to reading the wiki some more and let
Anthony field Henrik's questions in the meantime, if he wants to. (One
thing that's obvious is that universally quantified polymorphic fields
*are* allowed in DORF, because a specific example is listed which uses
one. It's completely inconceivable to me that any record system
proposal could be adopted which required doing away with them.
Complete show-stopper.)

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Records in Haskell

2012-02-25 Thread Henrik Nilsson

Hi,

Just checking my understanding here as I have not followed this thread
in all its details.

Gabor Lehel wrote:

> I agree completely. This is what I like about DORF: the D stands for
> "Declared", which is referring to the fact that the contracts are
> explicit. Record fields aren't automatically polymorphic based on
> their name and type, as with SORF, rather they are scoped and
> disambiguated in the same way as classes.

So, with both DORF and your variant of it, am I correct in understanding
that polymorphic fields, be it universally quantified as in

   data ARecordType a =
C1 {
...,
fieldX :: a,
...,
fieldY :: a -> a,
...
}

or existentially quantified as in:

   data AnotherRecordType =
forall a . C2 {
...,
fieldU :: a,
...,
fieldV :: a -> Int,
...
}

would no longer be possible?

Note that the type variable a in both cases scope just over the
constructor(s) of the data type in question. So any attempt at
declaring the types of the fields outside of this context,
be it explicitly with the fieldLabel notation, or implicitly as
per your proposal, would not be possible. E.g.

   fieldLabel fieldY :: a -> a

would presumably mean

   fieldLabel fieldY :: forall a . a -> a

resulting in ARecordType becoming second-order polymorphic
where the value of fieldY would *have* to be a polymorphic function,
which is very different from the original definition.

Similarly, the whole point with the existentially quantification is
to allow a number of fields to share some specific but arbitrary type,
which again means that any attempt to type these fields outside of the
context of the datatype to which they belong would result in something
different.

Note that fieldU and fieldV cannot be used as projection functions
due to escaped type variables, but that field selection by pattern
matching is perfectly fine.

Both constructions above are very useful and, I'd argue that a design
that rules them out actually is a rather poor fit for a language like
Haskell.

To be completely honest, I, at least, would be much happier keeping
working around the present limitations of Haskell's named fields by
picking my field names carefully, than losing the above.

Or am I missing something? E.g. is the idea that sharing of fields
only applies to fields of monomorphic type, i.e. whose type can be
declared globally?

Best,

/Henrik

--
Henrik Nilsson
School of Computer Science
The University of Nottingham
n...@cs.nott.ac.uk

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users