Ian Lynagh | 2 Aug 2010 17:18
Picon
Gravatar

Re: [Haskell-cafe] Weird behavior with arrow commands

On Sat, Jul 24, 2010 at 12:45:27PM +0100, Ross Paterson wrote:
> On Sat, Jul 24, 2010 at 01:10:56PM +0200, Jürgen Doser wrote:
> > This seems to be a bug in ghc.
> 
> You're right: it's getting the argument order wrong, so -dcore-lint
> fails on this example and all bets are off.  Definitely a bug.

Filed here: http://hackage.haskell.org/trac/ghc/ticket/4236

Thanks
Ian
Corey O'Connor | 6 Aug 2010 22:15
Picon

Re: FFI, signals and exceptions

On Fri, Jul 30, 2010 at 8:19 PM, Edward Z. Yang <ezyang <at> mit.edu> wrote:
> Hello all,

Hi!

> Ignoring the problems of cleaning up the unceremoniously terminated C
> computation, I'm having difficulty getting the FFI to /stop/ running
> when I get the signal.  I currently have some code like this:
>
>    http://hpaste.org/fastcgi/hpaste.fcgi/view?id=28422#a28422

In your test cases that fail are your C computations foreign unsafe imports?

-Corey O'Connor
coreyoconnor <at> gmail.com
http://www.coreyoconnor.com
Edward Z. Yang | 6 Aug 2010 22:16
Picon
Favicon

Re: FFI, signals and exceptions

Excerpts from Corey O'Connor's message of Fri Aug 06 16:15:21 -0400 2010:
> In your test cases that fail are your C computations foreign unsafe imports?

First thing I checked. :-) They were safe imports, and the Haskell code
did get called--just the C code kept marching on.

Cheers,
Edward
Simon Marlow | 9 Aug 2010 17:23
Picon

Re: FFI, signals and exceptions

On 06/08/2010 21:16, Edward Z. Yang wrote:
> Excerpts from Corey O'Connor's message of Fri Aug 06 16:15:21 -0400 2010:
>> In your test cases that fail are your C computations foreign unsafe imports?
>
> First thing I checked. :-) They were safe imports, and the Haskell code
> did get called--just the C code kept marching on.

Right, the RTS won't try to interrupt a foreign call even when there's a 
pending throwTo for the thread making the call.  The reason is that, 
well, there's no way to interrupt C calls.  You could try pthread_cancel 
I suppose, but only if the thread making the call is not a bound thread 
(because pthread_cancel kills the thread, it's not an exception 
mechanism).  That might be quite interesting to try, actually.  You'll 
need to modify the RTS: the place where we decide what to do when a 
throwTo is received for a thread involved in a foreign call is around 
line 396 of rts/RaiseAsync.c (in the HEAD):

     case BlockedOnCCall:
     case BlockedOnCCall_NoUnblockExc:
	blockedThrowTo(cap,target,msg);
	return THROWTO_BLOCKED;

this is where you would call pthread_cancel (after checking for a bound 
thread).  You should look into pthread_setcancelstate and 
pthread_setcanceltype, and call these appropriately for worker threads.

Cheers,
	Simon
Johan Tibell | 11 Aug 2010 18:03
Picon
Gravatar

Using associated data types to create unpacked data structures

Hi all,

Inspired by the generic maps example at

    http://www.haskell.org/haskellwiki/GHC/Indexed_types

I tried to use associated data types to create a generic finite map that unpacks both the key and value into the leaf data constructor.

This makes functions such as lookup faster as the key can be accessed directly instead than via an indirection. It also makes the data structure more space efficient (4 words less per key/value pair for weight balanced trees), which makes it possible to fit more data in main memory (and cache). Memory overhead is important when working with "Big Data" processing, where fitting as much data in memory as possible is important. Working with big data sets is something done daily at companies like Google, Microsoft, Yahoo, Twitter, Facebook, etc.

We can achieve the above goals using an associated data type like so:

    {-# LANGUAGE MultiParamTypeClasses, TypeFamilies #-}
    module Ex where

    class Unbox k v where
        data Map k v :: *
        empty       :: Map k v
        lookup      :: k -> Map k v -> Maybe v
        insert      :: k -> v -> Map k v -> Map k v

and an instance

    instance Unbox Int Double where
        data Map Int Double = TipIntDouble
                            | BinIntDouble {-# UNPACK #-} !Size
                                           {-# UNPACK #-} !Int
                                           {-# UNPACK #-} !Double
                                           !(Map Int Double)
                                           !(Map Int Double)
                                          
        -- implementation elided
        empty = undefined
        lookup k m = undefined
        insert k v m = undefined
     
    type Size = Int

However, if we try to apply this method to large programs we run into problems: we need to defined instances for a large number of combinations of keys/values. We could generate a large number of instances, hoping that these will be enough for most users' needs, using Template Haskell or CPP. However, the potential number of instances is very large, about a hundred if you consider only Prelude types and tens of thousands if you include tuples. We cannot add instances for types not defined in base without adding a dependency on all libraries which data types we want to add instances for.

Since we cannot define all instances up-front we'll have to rely on the user to create instances for the combinations she needs. This is tedious work for the user; most of the time the instance is an exact copy of the above instance for Int/Double, modulo renaming of the type arguments and the constructor names.

Unfortunately our problems don't end here. If we assume for a second that the user writes the necessary boilerplate (perhaps using a Template Haskell function that generates it) there are still more problems ahead. It's quite likely that two different libraries wants an instance for the same types, and each declare one locally. However, now the poor user can't use both libraries as there are conflicting instances (or can she using some extension?) and imports always bring in instances. This problem exists for type classes in general but we only use ten or so type classes in most Haskell programs (e.g Functor, Monad, Eq, Ord, and Show) so it doesn't seem to be a big problem so far.

What to do? It seems that associated data types might not be right tool for this problem. Could it be extended to work well for this use case? Can it be made to *scale* to large programs.

Here's an idea: allow default implementations of associated data types, just like for methods

    class Unbox k v where
        data Map k v :: *
        empty       :: Map k v
        lookup      :: k -> Map k v -> Maybe v
        insert      :: k -> v -> Map k v -> Map k v

        data Map Int Double = Tip
                            | Bin {-# UNPACK #-} !Size
                                  {-# UNPACK #-} !k
                                  {-# UNPACK #-} !v
                                  !(Map k v)
                                  !(Map k v)

        -- implementation elided
        empty = undefined
        lookup k m = undefined
        insert k v m = undefined

and export the definition in the interface file. This would allow instantiation of the type class without boilerplate

    instance Unbox Int Double  -- no "body"

The compiler would perhaps have to generate unique names for the constructors for this to work.

This is not enough. We still have two problems left:

    * boilerplate instance declarations (but less so that before), and
    * instance collisions.

Could we automatic create instances whenever the user mentions a type class? For example, if a program mentions

    f :: Map Int Double -> ...

we know we need an instance for Int/Double and if we can't find one we derive one using the default definition. It is all the user needs to do when using the classic containers package. This would completely remove the boilerplate instance declarations.

We could still use OverlappingInstances to allow the user to provide more specific instances (with a different implementation), if needed. This is akin to C++ template specialization.

The compiler will need to help us with the instance collision problem in that it only generates on instance even if the same type parameters are used with the Map type in several different modules.

Summary: While associated data types in theory allows us to create more efficient data structures, the feature doesn't seem to scale to large programs, for this use case.

Cheers,
Johan

_______________________________________________
Glasgow-haskell-users mailing list
Glasgow-haskell-users <at> haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Bryan O'Sullivan | 11 Aug 2010 18:25
Gravatar

Re: Using associated data types to create unpacked data structures

On Wed, Aug 11, 2010 at 9:03 AM, Johan Tibell <johan.tibell <at> gmail.com> wrote:
 
However, if we try to apply this method to large programs we run into problems: we need to defined instances for a large number of combinations of keys/values. We could generate a large number of instances, hoping that these will be enough for most users' needs, using Template Haskell or CPP. However, the potential number of instances is very large, about a hundred if you consider only Prelude types and tens of thousands if you include tuples. We cannot add instances for types not defined in base without adding a dependency on all libraries which data types we want to add instances for.

This is more or less the type-level version of the "I have to write how many boilerplate instances?" problem that dogs typeclasses. I agree that it's quite painful, and that it effectively keeps type families from being nearly as practically useful as they could be. Like you, I'd love to see an effective solution.
_______________________________________________
Glasgow-haskell-users mailing list
Glasgow-haskell-users <at> haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Greg Fitzgerald | 11 Aug 2010 23:31
Picon
Gravatar

how to link a minimal executable?

Is there any documentation or examples available that shows what needs to be linked to get a haskell executable to print "hello world"?  Instead of using GHC to link, I'm interested in using gcc, ar, or link directly.  For starters, what implements the entry point? 

$ cat Main.hs
main = print "hello world"
$ ghc -c Main.hs
$ Vs8/VC/bin/link.exe -NOLOGO Main.o
LINK : fatal error LNK1561: entry point must be defined


I see using ghc -v, it links all sorts of stuff:

$ ghc -v Main.hs
...
*** Linker:
...
 -lHSrtsmain -lHShaskell98-1.0.1.1 -lHSrandom-1.0.0.2 -lHStime-1.1.4 -lHSprocess-1.0.1.2 -lHSdirectory-1.0.1.0 -lHSold-time-1.0.0.3 -lHSold-locale-1.0.0.2 -lHSfilepath-1.1.0.3 -lHSWin32-2.2.0.1 -luser32 -lgdi32 -lwinmm -ladvapi32 -lshell32 -lshfolder -lHSbytestring-0.9.1.5 -lHSarray-0.3.0.0 -lHSbase-4.2.0.0 -lwsock32 -luser32 -lshell32 -lHSinteger-simple-0.1.0.0 -lHSghc-prim-0.2.0.0 -lHSrts -lm -lwsock32 -u _ghczmprim_GHCziTypes_Izh_static_info -u _ghczmprim_GHCziTypes_Czh_static_info -u _ghczmprim_GHCziTypes_Fzh_static_info -u _ghczmprim_GHCziTypes_Dzh_static_info -u _base_GHCziPtr_Ptr_static_info -u _base_GHCziWord_Wzh_static_info -u _base_GHCziInt_I8zh_static_info -u _base_GHCziInt_I16zh_static_info -u _base_GHCziInt_I32zh_static_info -u _base_GHCziInt_I64zh_static_info -u _base_GHCziWord_W8zh_static_info -u _base_GHCziWord_W16zh_static_info -u _base_GHCziWord_W32zh_static_info -u _base_GHCziWord_W64zh_static_info -u _base_GHCziStable_StablePtr_static_info -u _ghczmprim_GHCziTypes_Izh_con_info -u _ghczmprim_GHCziTypes_Czh_con_info -u _ghczmprim_GHCziTypes_Fzh_con_info -u _ghczmprim_GHCziTypes_Dzh_con_info -u _base_GHCziPtr_Ptr_con_info -u _base_GHCziPtr_FunPtr_con_info -u _base_GHCziStable_StablePtr_con_info -u _ghczmprim_GHCziBool_False_closure -u _ghczmprim_GHCziBool_True_closure -u _base_GHCziPack_unpackCString_closure -u _base_GHCziIOziException_stackOverflow_closure -u _base_GHCziIOziException_heapOverflow_closure -u _base_ControlziExceptionziBase_nonTermination_closure -u _base_GHCziIOziException_blockedIndefinitelyOnMVar_closure -u _base_GHCziIOziException_blockedIndefinitelyOnSTM_closure -u _base_ControlziExceptionziBase_nestedAtomically_closure -u _base_GHCziWeak_runFinalizzerBatch_closure -u _base_GHCziTopHandler_runIO_closure -u _base_GHCziTopHandler_runNonIO_closure -u _base_GHCziConc_ensureIOManagerIsRunning_closure -u _base_GHCziConc_runSparks_closure -u _base_GHCziConc_runHandlers_closure -lHSffiReading

Any insight would be greatly appreciated.

Thanks,
Greg
_______________________________________________
Glasgow-haskell-users mailing list
Glasgow-haskell-users <at> haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Krzysztof Skrzętnicki | 12 Aug 2010 01:25
Picon

Re: how to link a minimal executable?

As far as I know *it is* the minimal set of libraries. Each and every
package comes with another library. And if it depends on any other
library it will be included as well. Additionally there will be some
system libraries like the one which defines main entry point.

This will result in huge executables if you use many libraries. A way
around it is using dynamic libraries, which does decrease the size of
executable, but can increase the complexity of deployment.

Perhaps someone will know the details better than me.

Best regards,
Krzysztof Skrzętnicki

On Wed, Aug 11, 2010 at 23:31, Greg Fitzgerald <garious <at> gmail.com> wrote:
> Is there any documentation or examples available that shows what needs to be
> linked to get a haskell executable to print "hello world"?  Instead of using
> GHC to link, I'm interested in using gcc, ar, or link directly.  For
> starters, what implements the entry point?
> $ cat Main.hs
> main = print "hello world"
> $ ghc -c Main.hs
> $ Vs8/VC/bin/link.exe -NOLOGO Main.o
> LINK : fatal error LNK1561: entry point must be defined
>
> I see using ghc -v, it links all sorts of stuff:
> $ ghc -v Main.hs
> ...
> *** Linker:
> ...
>  -lHSrtsmain -lHShaskell98-1.0.1.1 -lHSrandom-1.0.0.2 -lHStime-1.1.4
> -lHSprocess-1.0.1.2 -lHSdirectory-1.0.1.0 -lHSold-time-1.0.0.3
> -lHSold-locale-1.0.0.2 -lHSfilepath-1.1.0.3 -lHSWin32-2.2.0.1 -luser32
> -lgdi32 -lwinmm -ladvapi32 -lshell32 -lshfolder -lHSbytestring-0.9.1.5
> -lHSarray-0.3.0.0 -lHSbase-4.2.0.0 -lwsock32 -luser32
> -lshell32 -lHSinteger-simple-0.1.0.0 -lHSghc-prim-0.2.0.0 -lHSrts -lm
> -lwsock32 -u _ghczmprim_GHCziTypes_Izh_static_info -u
> _ghczmprim_GHCziTypes_Czh_static_info -u
> _ghczmprim_GHCziTypes_Fzh_static_info -u
> _ghczmprim_GHCziTypes_Dzh_static_info -u _base_GHCziPtr_Ptr_static_info -u
> _base_GHCziWord_Wzh_static_info -u _base_GHCziInt_I8zh_static_info -u
> _base_GHCziInt_I16zh_static_info -u _base_GHCziInt_I32zh_static_info -u
> _base_GHCziInt_I64zh_static_info -u _base_GHCziWord_W8zh_static_info -u
> _base_GHCziWord_W16zh_static_info -u _base_GHCziWord_W32zh_static_info -u
> _base_GHCziWord_W64zh_static_info -u _base_GHCziStable_StablePtr_static_info
> -u _ghczmprim_GHCziTypes_Izh_con_info -u _ghczmprim_GHCziTypes_Czh_con_info
> -u _ghczmprim_GHCziTypes_Fzh_con_info -u _ghczmprim_GHCziTypes_Dzh_con_info
> -u _base_GHCziPtr_Ptr_con_info -u _base_GHCziPtr_FunPtr_con_info -u
> _base_GHCziStable_StablePtr_con_info -u _ghczmprim_GHCziBool_False_closure
> -u _ghczmprim_GHCziBool_True_closure -u
> _base_GHCziPack_unpackCString_closure -u
> _base_GHCziIOziException_stackOverflow_closure -u
> _base_GHCziIOziException_heapOverflow_closure -u
> _base_ControlziExceptionziBase_nonTermination_closure -u
> _base_GHCziIOziException_blockedIndefinitelyOnMVar_closure -u
> _base_GHCziIOziException_blockedIndefinitelyOnSTM_closure -u
> _base_ControlziExceptionziBase_nestedAtomically_closure -u
> _base_GHCziWeak_runFinalizzerBatch_closure -u
> _base_GHCziTopHandler_runIO_closure -u
> _base_GHCziTopHandler_runNonIO_closure -u
> _base_GHCziConc_ensureIOManagerIsRunning_closure -u
> _base_GHCziConc_runSparks_closure -u _base_GHCziConc_runHandlers_closure
> -lHSffiReading
> Any insight would be greatly appreciated.
> Thanks,
> Greg
> _______________________________________________
> Glasgow-haskell-users mailing list
> Glasgow-haskell-users <at> haskell.org
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>
>
Greg Fitzgerald | 12 Aug 2010 03:20
Picon
Gravatar

$thisdir for package.conf?

Is there a way for a package.conf file to contain paths that are relative to the directory containing the .conf file?  GHC 6.12.1 chokes on relative paths.  I see the problem is solved for GHC's core libraries with the $topdir variable.  Is there something like a $thisdir we could use in inplace .conf files?


Thanks,
Greg
_______________________________________________
Glasgow-haskell-users mailing list
Glasgow-haskell-users <at> haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Simon Marlow | 12 Aug 2010 11:28
Picon

Re: Using associated data types to create unpacked data structures

On 11/08/2010 17:03, Johan Tibell wrote:
> Inspired by the generic maps example at
>
> http://www.haskell.org/haskellwiki/GHC/Indexed_types
>
> I tried to use associated data types to create a generic finite map that
> unpacks both the key and value into the leaf data constructor.

What you're trying to do is have the compiler generate a whole module 
for you, including a datatype specialised to certain type paramters, and 
operations over that type.  Just defining a few of the operations isn't 
enough: they need to be inlined everywhere, essentially you need to 
recompile Data.Map for each instance.

So I agree it would be nice if this happened automatically, behind the 
scenes, by virtue of just mentioning "Map Int Double" (though it would 
still have to be a typeclass of course, so that you can write 
polymorphic functions over Maps).  Automatic specialisation of this kind 
can be done by JIT runtimes (e.g. the .NET CLR), because there the code 
generation and caching of instances can be put under control of the 
runtime.  Here we would have to do it in the compiler, and the 
difficulty is that the compiler needs to support separate compilation.

Rather than try to solve this problem in one go, I would go for a 
low-tech approach for now: write a TH library to generate the code, and 
ask the user to declare the versions they need.  To make a particular 
version, the user would say something like

   module MapIntDouble (module MapIntDouble) where
   import TibbeMagicMapGenerator
   make_me_a_map ...

there's no type class of course, so you can't write functions that work 
over all specialised Maps.  But this at least lets you generate 
optimised maps for only a little boilerplate, and get the performance 
boost you were after.

Cheers,
	Simon

Gmane