
I am currently in the middle of a reasonably large software simulation of a wireless network that I'm programming in Haskell and in C. Progress has been slower than anticipated and I occasionally (probably because of looming deadlines) ask myself did I take the right approach? Here are the reasons why I chose Haskell initially 1) It's mathematical elegance, I thought would lend itself to the complex mathematical expressions I am implementing. 2) It rates reasonably high in performance comparisons with other languages http://shootout.alioth.debian.org/gp4sandbox/benchmark.php?test=all&lang=all 3) It has a very active community who are courteous and quite helpful 4) It has an interactive shell. 5) It integrates easily with C. The idea would be to implement hooks to some fast matrix libraries and some plotting routines in C and then develop the higher level logic in Haskell. Since marshalling arrays and such, is a bit of a pain I structured my C matrix library in the form of stack based machine, using reference counting to handle memory management and to minimize the amount of actual data I need to pass between C and Haskell. This seems to work fairly well. However I have been somewhat disabused of my original thought about how development would proceed. I had hoped that I could get within a factor of two or so of the fast prototyping, development times of a good scripting language such as Matlab, Python or Lua, but I don't think I'm achieving this unfortunately. Here are some reasons why 1) Lack of debugging support. Yes there are print statements and trace, but I would like to set a breakpoint. It would be nice to do so and launch the GHCi interpreter with all the variable context supported. A google search revealed that there is current work on this, but unfortunately the package is in cabal, which has spotty support in windows it seems. 2) Recompiling binaries (necessary in order to link in foreign object code into GHCi) is slow using GHC. Moreover I have to restart GHCi if I want to reload a changed DLL (unless there is a way to unload a DLL in GHCi). It also requires jumping around between several console windows to get the job done. (I'm not using an IDE does one exist?) 3) Lack of automatic type coercion for closely related types. In particular I have to use CInt and CDouble to go into and out of C. Unfortunately only a small subset of library functions will actually support CInt so I have to explicitly coerce this values. I usually have a host of compile errors initially because of this silly issue and it makes the code ugly. What would help would be an automatic type conversion from CInt to Int and CDouble to Double. Perhaps some warning level could flag these if this were 'too dangerous'. 4) GHCi is really not as useful as I'd hoped. You can not just cut and paste Haskell code from a text file and run it in the interpreter. There is also this context issue concerning what modules are actually in scope. So although in Haskell once I import a module, all of its functions are in scope, in GHCi, if I load this module only the exported functions from that module are in scope. The result, again, is that I can not get an apples to apples idea of what is happening in my code. Thus I have been using GHCi primarily as a syntax checker for Haskell constructs. 5) Learning new programming patterns may have a role to play, but sometimes things like iteration is cleaner than recursion. I worry about performance issues however. I had to create a 50 Mbyte matrix and I used what I thought, initially was an elegant contruction technique in Haskell. Something like this do ... sequence $ [ reffill b s | s <- [0..(fi temits)-1], b <- [0..(fi nc)-1]] ...(push list on to matrix stack) The refill function generates a matrix based on basestation index b and SU index s and pushes it on the Matrix stack in C, inside an IO monad. So it returns IO(). The list comprehension ends up doing a cartesian product of all (b,s) pairs which in this case is a large number. fi is my shorthand for doing an annoying CInt to Int conversion. The problem with this code is that it takes about 500 Mbytes in memory instead of 50 Mb. Apparently it loads up all the potential IO actions into the huge list before executing it, taking the factor of 10 or so hit. There is probably a nice space saving way of doing this, that executes each IO action before generating the next one, but I was in too much of a hurry to figure it out. This also makes me wonder about the efficiency of the C interface. Each IO action calls a C function (using the unsafe specifier in the import declaration). I hope there isn't too much overhead with this. In my case I do almost no marshalling. Most calls have no arguments and no returns, or at most require a handful of CInts or CDoubles. My application has 60-70% of it's statements in an IO monad calling lots of C code. I begin to wonder if all those statements shouldn't in fact just be in C to begin with. Thus I begin to wonder why I'm using Haskell. Maybe I just need some encouragement that my choice will pay off in the end.

Hi,
1) Lack of debugging support. See Hat http://www.haskell.org/hat - it might give you the debugging stuff you want, provided you have stuck mainly to Haskell 98.
2) Recompiling binaries (necessary in order to link in foreign object code into GHCi) is slow using GHC. Moreover I have to restart GHCi if I want to reload a changed DLL (unless there is a way to unload a DLL in GHCi). It also requires jumping around between several console windows to get the job done. (I'm not using an IDE does one exist?) Have you seen Hugs/WinHugs? Its a lot faster to load files, by a massive factor (one particular project I use is 5 seconds in Hugs vs 8 minutes in GHC). http://haskell.org/hugs - its also much slower at runtime :)
3) Lack of automatic type coercion for closely related types. In particular I have to use CInt and CDouble to go into and out of C. You can probably play with type classes and get something doing this automatically in some way, for some cases.
4) GHCi is really not as useful as I'd hoped. You can not just cut and paste Haskell code from a text file and run it in the interpreter. There is also this context issue concerning what modules are actually in scope. So although in Haskell once I import a module, all of its functions are in scope, in GHCi, if I load this module only the exported functions from that module are in scope. It does seem to work when I do it, not quite sure, but if you give an exact example of what doesn't work then perhaps people can look at it. Also :m+ is useful, in addition to :l.
Thus I have been using GHCi primarily as a syntax checker for Haskell constructs. If that is all you are using GHCi for, and you aren't using any GHC specific features, Hugs will be much much quicker, and if you use WinHugs you'll get auto-reload and hyperlinks to error locations as well.
Thus I begin to wonder why I'm using Haskell. If you are writing most of your code in C, then maybe you should be using C instead of Haskell - interfacing between two languages always has a cost.
Of course, you probably don't realise how much advantage you are getting from Haskell. How many lines of Haskell code do you have in this project? Think how painful that would be to code in C. Thanks Neil

1) Hat looks really interesting thanks. Hopefully it will run on windows. 2) I have downloaded the latest version of WinHugs. In the end I need my Haskell to compile under GHC for performance reasons. I am concerned about portability, especially as concerns the ffi. I got scared off by the need for a separate compilation to support it. Perhaps it wouldn't be so bad after I get used to it or try to configure a script or something to make it easier. I might give it a try after my current deadlines. 3) The problem here is existing code. I don't want to add every function that I use into a class just to maintain simple polymorphism over closely related numeric types. This would take longer than just calling the coercion routines. It's funny how trivial stuff likes this gets irritating when you are writing a lot of code. Maybe I'm just in a bad mood or something. 4) Hmm, a simple example I tried actually worked, however I have a file that has this header module Parsefile where import System.IO import System.IO.Unsafe import Text.ParserCombinators.Parsec import Data.HashTable ... For some reason it requires that I use the fully qualified name Data.HashTable.lookup instead of just lookup to get the correct functionality. I think I understand my issue now with this (other than the anomaly of the above example). I've been using the make option with ghc to compile all the dependent sources, creating binaries for all of them. Those binaries can be loaded into GHCi, but if you do so it will not make the imports available to you for use. Thus my main.hs has the header import Matrix import Parsefile import Array import NetPrams import System.IO.Unsafe ..... If main.hs has not been brought up to date, I can load main.hs into the interpreter and the functions defined in Matrix for example will be in scope and usable. If on the other hand I've just run ghc on main, I can load main.hs in, but the functions in Matrix will not be available. Perhaps the solution is to create a script file that loads all the modules in and adds them to the current scope. I do want to understand the advantages of Haskell. My approach has been to consign the heavy imperative, state manipulating code to C and leave the higher end stuff to Haskell. The nature of my problem (a simulation) necessitates holding state for efficiency reasons. (e.g. I don't want to copy a 500 MB matrix every time I change an entry.) I assumed that Haskell would be easier to write and perhaps maintain than the horrors of pure C. At this point there is no turning back. I will probably answer this question soon enough. Neil Mitchell wrote:
Hi,
1) Lack of debugging support. See Hat http://www.haskell.org/hat - it might give you the debugging stuff you want, provided you have stuck mainly to Haskell 98.
2) Recompiling binaries (necessary in order to link in foreign object code into GHCi) is slow using GHC. Moreover I have to restart GHCi if I want to reload a changed DLL (unless there is a way to unload a DLL in GHCi). It also requires jumping around between several console windows to get the job done. (I'm not using an IDE does one exist?) Have you seen Hugs/WinHugs? Its a lot faster to load files, by a massive factor (one particular project I use is 5 seconds in Hugs vs 8 minutes in GHC). http://haskell.org/hugs - its also much slower at runtime :)
3) Lack of automatic type coercion for closely related types. In particular I have to use CInt and CDouble to go into and out of C. You can probably play with type classes and get something doing this automatically in some way, for some cases.
4) GHCi is really not as useful as I'd hoped. You can not just cut and paste Haskell code from a text file and run it in the interpreter. There is also this context issue concerning what modules are actually in scope. So although in Haskell once I import a module, all of its functions are in scope, in GHCi, if I load this module only the exported functions from that module are in scope. It does seem to work when I do it, not quite sure, but if you give an exact example of what doesn't work then perhaps people can look at it. Also :m+ is useful, in addition to :l.
Thus I have been using GHCi primarily as a syntax checker for Haskell constructs. If that is all you are using GHCi for, and you aren't using any GHC specific features, Hugs will be much much quicker, and if you use WinHugs you'll get auto-reload and hyperlinks to error locations as well.
Thus I begin to wonder why I'm using Haskell. If you are writing most of your code in C, then maybe you should be using C instead of Haskell - interfacing between two languages always has a cost.
Of course, you probably don't realise how much advantage you are getting from Haskell. How many lines of Haskell code do you have in this project? Think how painful that would be to code in C.
Thanks
Neil

Matthew Bromberg wrote:
4) Hmm, a simple example I tried actually worked, however I have a file that has this header module Parsefile where import System.IO import System.IO.Unsafe import Text.ParserCombinators.Parsec import Data.HashTable ...
For some reason it requires that I use the fully qualified name Data.HashTable.lookup instead of just lookup to get the correct functionality.
The reason is that the standard Prelude also provides function called 'lookup'. [*] You could hide it by explicitely importing the Prelude: import Prelude hiding (lookup) Another solution is to import the HashTable module with a shorter name to save typing (and avoid noise) in the Code: import Data.HashTable as H allows you to use H.lookup for the lookup. If you make the import qualified, import qualified Data.HashTable as H you are forced to use that prefix, but you can use the Prelude's lookup without any prefix again. By specifying the names to import you can create any mix of prefixed and non-prefixed functions you want. Another useful thing to know is that you can import different modules with the same name (beware of conflicting symbols though). For example, adding import Data.HashTable (HashTable) to the qualified import allows you to use the type 'HashTable' without the 'H.' prefix. regards, Bertram [*] it'd be nice if the name resolution could be guided by the type checker - but that's probably hard. Has anyone tried that?

Matthew Bromberg
1) Hat looks really interesting thanks. Hopefully it will run on windows.
Under mingw or cygwin, possibly. Natively, not.
3) The problem here is existing code. I don't want to add every function that I use into a class just to maintain simple polymorphism over closely related numeric types. This would take longer than just calling the coercion routines.
Possibly you just need to move the coercions to a single more manageable location. e.g. you could rename the FFI calls, then wrap them with a simple coercion function, and call it by the original name. inject :: CInt -> Int eject :: Int -> CInt foreign import ccall "blah" prim_blah :: CInt -> CInt blah x = inject (prim_blah (eject x)) By the way, there are tools for generating FFI bindings that can create code like this (e.g. GreenCard). Regards, Malcolm

Hi
1) Hat looks really interesting thanks. Hopefully it will run on windows. Under mingw or cygwin, possibly. Natively, not.
http://www.haskell.org//pipermail/hat/2006-July/000288.html - I ported Hat to Windows natively last week. No mingw or cygwin required. Thanks Neil

Matthew Bromberg wrote:
3) The problem here is existing code. I don't want to add every function that I use into a class just to maintain simple polymorphism over closely related numeric types. This would take longer than just calling the coercion routines. It's funny how trivial stuff likes this gets irritating when you are writing a lot of code. Maybe I'm just in a bad mood or something.
It would be better to just use the Haskell numeric types in the first place ie replace all CInt, CDouble etc by Int, Double etc and change your C code accordingly to use HsInt, HsDouble instead of plain int, double etc. Hopefully this should just be a trivial matter of changing a few typedefs in a C header as long as the C functions don't refer to 'int' 'double' etc directly. Regards, Brian. -- Logic empowers us and Love gives us purpose. Yet still phantoms restless for eras long past, congealed in the present in unthought forms, strive mightily unseen to destroy us. http://www.metamilk.com

I agree that this would be the cleaner solution. In fact.... I already have a typedef for the Double type in anticipation of using different sized floating point. Unfortunately I rely heavily on the BLAS linear algebra libraries. As long as I can type cast the haskell types in C to double or int where appropriate, I'm OK, at the expense of making some global changes to the code. Fortunately all my Blas interfaces are performed through typedefs. I'll have to look into this. Thanks again for the tip. Given that I'm making a lot of C calls through Haskell, with the unsafe tag in the import statement, does anyone have an idea of what kind of overhead I might still be incurring? I'm assuming that it's fairly minimal. The one call that has to be safe has a callback to a numerical Haskell function that is called repeatedly over every element in a potentially large matrix. I am also concerned about the performance of that procedure. Brian Hulley wrote:
Matthew Bromberg wrote:
3) The problem here is existing code. I don't want to add every function that I use into a class just to maintain simple polymorphism over closely related numeric types. This would take longer than just calling the coercion routines. It's funny how trivial stuff likes this gets irritating when you are writing a lot of code. Maybe I'm just in a bad mood or something.
It would be better to just use the Haskell numeric types in the first place ie replace all CInt, CDouble etc by Int, Double etc and change your C code accordingly to use HsInt, HsDouble instead of plain int, double etc. Hopefully this should just be a trivial matter of changing a few typedefs in a C header as long as the C functions don't refer to 'int' 'double' etc directly.
Regards, Brian.

On Jul 23, 2006, at 1:20 AM, Matthew Bromberg wrote:
I do want to understand the advantages of Haskell. My approach has been to consign the heavy imperative, state manipulating code to C and leave the higher end stuff to Haskell. The nature of my problem (a simulation) necessitates holding state for efficiency reasons. (e.g. I don't want to copy a 500 MB matrix every time I change an entry.) I assumed that Haskell would be easier to write and perhaps maintain than the horrors of pure C. At this point there is no turning back. I will probably answer this question soon enough.
Hi Matthew, It seems that a lot of your issues stem from the design decision to implement a good chunk of your program in C. There are certainly ways to implement an indexed data-structure in Haskell with good performance for persistent functional updates. Alternatively, you could write imperative code in Haskell to update the array in place non-persistently. So, the decision not to use Haskell for that part may be a case of premature optimization. Cheers, David -------------------------------- David F. Place mailto:d@vidplace.com

David F. Place wrote:
On Jul 23, 2006, at 1:20 AM, Matthew Bromberg wrote:
I do want to understand the advantages of Haskell. My approach has been to consign the heavy imperative, state manipulating code to C and leave the higher end stuff to Haskell. The nature of my problem (a simulation) necessitates holding state for efficiency reasons. (e.g. I don't want to copy a 500 MB matrix every time I change an entry.) I assumed that Haskell would be easier to write and perhaps maintain than the horrors of pure C. At this point there is no turning back. I will probably answer this question soon enough.
Hi Matthew,
It seems that a lot of your issues stem from the design decision to implement a good chunk of your program in C. There are certainly ways to implement an indexed data-structure in Haskell with good performance for persistent functional updates. Alternatively, you could write imperative code in Haskell to update the array in place non-persistently. So, the decision not to use Haskell for that part may be a case of premature optimization.
Cheers, David
-------------------------------- David F. Place mailto:d@vidplace.com
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
You make a good point and the decision was by no means cut and dry. However I made a point of developing some test code using some the newer array data types and looked at maintaining the array in Haskell and then directly calling Blas etc. I even had a nice polymorphic matrix class going. However I found the array interface just a bit too 'clunky' to use a technical term. The withArray interface is not very appealing. The layers of lambda notation was giving me a headache. The idea of separating the imperative code into an imperative language was appealing to me. Moreover using a stack based architecture for matrix operations makes the C end of things very easy to implement. The big bugaboo of memory management issues pretty much disappears, and thinking of the world state in the IO monad as a stack of matrices has a nice intuitive appeal for me. It seems to work well so far as I said earlier. I'm not sure all my issues would have gone away if I had tried to do more of the matrix op.s in Haskell. It is pretty much a given that I need to interface to external optimized libraries, that's where the big number crunching is occuring and those libraries have had teams of Ph.D.s working on them for years. I want to leverage that. My approach actually minimizes the amount of marshalling I have to do between C and Haskell. The stack manipulations are simply scripted in a do clause, with nary an argument being passed. -- View this message in context: http://www.nabble.com/Why-Haskell--tf1986013.html#a5458965 Sent from the Haskell - Haskell-Cafe forum at Nabble.com.

You make a good point and the decision was by no means cut and dry. However I made a point of developing some test code using some the newer array data types and looked at maintaining the array in Haskell and then directly calling Blas etc. I even had a nice polymorphic matrix class going. However I found the array interface just a bit too 'clunky' to use a technical term. The withArray interface is not very appealing. The layers of lambda notation was giving me a headache.
The idea of separating the imperative code into an imperative language was appealing to me. Moreover using a stack based architecture for matrix operations makes the C end of things very easy to implement. The big bugaboo of memory management issues pretty much disappears, and thinking of the world state in the IO monad as a stack of matrices has a nice intuitive appeal for me. It seems to work well so far as I said earlier. I'm not sure all my issues would have gone away if I had tried to do more of the matrix op.s in Haskell. It is pretty much a given that I need to interface to external optimized libraries, that's where the big number crunching is occuring and those libraries have had teams of Ph.D.s working on them for years. I want to leverage that. My approach actually minimizes the amount of marshalling I have to do between C and Haskell. The stack manipulations are simply scripted in a do clause, with nary an argument being passed.
Has any one created binding for the numarray library ala Python Numarray? I've heard it's a very good and fast array interface. Perhaps it would be useful for this sort of task. Jason

GSL Haskell bindings: http://dis.um.es/~alberto/GSLHaskell/ http://dis.um.es/~alberto/GSLHaskell/doc/ Specifically for Linary Algebra: http://dis.um.es/~alberto/GSLHaskell/doc/GSL-Base.html
You make a good point and the decision was by no means cut and dry. However I made a point of developing some test code using some the newer array data types and looked at maintaining the array in Haskell and then directly calling Blas etc. I even had a nice polymorphic matrix class going. However I found the array interface just a bit too 'clunky' to use a technical term. The withArray interface is not very appealing. The layers of lambda notation was giving me a headache.
I think part of the problem here is not necessarily C or Haskell's fault, but rather that what you were trying to do was write a library (or needed the right library). Library writing is hard enough on its own, much less when one is relatively new to Haskell! Hopefully you will find the right tool for the job and things will go well! Jared. -- http://www.updike.org/~jared/ reverse ")-:"

Jared Updike wrote:
GSL Haskell bindings:
http://dis.um.es/~alberto/GSLHaskell/ http://dis.um.es/~alberto/GSLHaskell/doc/
Specifically for Linary Algebra: http://dis.um.es/~alberto/GSLHaskell/doc/GSL-Base.html
You make a good point and the decision was by no means cut and dry. However I made a point of developing some test code using some the newer array data types and looked at maintaining the array in Haskell and then directly calling Blas etc. I even had a nice polymorphic matrix class going. However I found the array interface just a bit too 'clunky' to use a technical term. The withArray interface is not very appealing. The layers of lambda notation was giving me a headache.
I think part of the problem here is not necessarily C or Haskell's fault, but rather that what you were trying to do was write a library (or needed the right library). Library writing is hard enough on its own, much less when one is relatively new to Haskell! Hopefully you will find the right tool for the job and things will go well!
Jared. -- http://www.updike.org/~jared/ reverse ")-:" _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
I looked at that. It would have been nice to use it however it seems to have issues on Windows. Although my windows requirement probably could have been relaxed, at the beginning of the project our network was entirely windows based. -- View this message in context: http://www.nabble.com/Why-Haskell--tf1986013.html#a5460683 Sent from the Haskell - Haskell-Cafe forum at Nabble.com.

The GSL has been ported to Windows: http://gnuwin32.sourceforge.net/packages/gsl.htm so I think that GSLHaskell could also be adapted to work in Windows... I will try to do it. Alberto On Monday 24 July 2006 02:56, SevenThunders wrote:
Jared Updike wrote:
GSL Haskell bindings:
http://dis.um.es/~alberto/GSLHaskell/ http://dis.um.es/~alberto/GSLHaskell/doc/
Specifically for Linary Algebra: http://dis.um.es/~alberto/GSLHaskell/doc/GSL-Base.html
You make a good point and the decision was by no means cut and dry.
However
I made a point of developing some test code using some the newer array
data
types and looked at maintaining the array in Haskell and then directly calling Blas etc. I even had a nice polymorphic matrix class going. However I found the array interface just a bit too 'clunky' to use a technical term. The withArray interface is not very appealing. The
layers
of lambda notation was giving me a headache.
I think part of the problem here is not necessarily C or Haskell's fault, but rather that what you were trying to do was write a library (or needed the right library). Library writing is hard enough on its own, much less when one is relatively new to Haskell! Hopefully you will find the right tool for the job and things will go well!
Jared. -- http://www.updike.org/~jared/ reverse ")-:" _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
I looked at that. It would have been nice to use it however it seems to have issues on Windows. Although my windows requirement probably could have been relaxed, at the beginning of the project our network was entirely windows based.

Alberto Ruiz-2 wrote:
The GSL has been ported to Windows:
http://gnuwin32.sourceforge.net/packages/gsl.htm
so I think that GSLHaskell could also be adapted to work in Windows... I will try to do it.
Alberto
On Monday 24 July 2006 02:56, SevenThunders wrote:
GSL Haskell bindings:
http://dis.um.es/~alberto/GSLHaskell/ http://dis.um.es/~alberto/GSLHaskell/doc/
Specifically for Linary Algebra: http://dis.um.es/~alberto/GSLHaskell/doc/GSL-Base.html
You make a good point and the decision was by no means cut and dry.
However
I made a point of developing some test code using some the newer array
data
types and looked at maintaining the array in Haskell and then
Jared Updike wrote: directly
calling Blas etc. I even had a nice polymorphic matrix class going. However I found the array interface just a bit too 'clunky' to use a technical term. The withArray interface is not very appealing. The
layers
of lambda notation was giving me a headache.
I think part of the problem here is not necessarily C or Haskell's fault, but rather that what you were trying to do was write a library (or needed the right library). Library writing is hard enough on its own, much less when one is relatively new to Haskell! Hopefully you will find the right tool for the job and things will go well!
Jared. -- http://www.updike.org/~jared/ reverse ")-:" _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
I looked at that. It would have been nice to use it however it seems to have issues on Windows. Although my windows requirement probably could have been relaxed, at the beginning of the project our network was entirely windows based.
Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Fantastic, this is significant news. Of course its a bit late in my case, but it will still probably be very helpful for follow on work. I'll try to make it possible to interchange data between my engine and GSL. It might be interesting to compare performance. -- View this message in context: http://www.nabble.com/Why-Haskell--tf1986013.html#a5463325 Sent from the Haskell - Haskell-Cafe forum at Nabble.com.

| I think I understand my issue now with this (other than the anomaly of | the above example). I've been using the make option with ghc to compile | all the dependent sources, creating binaries for all of them. Those | binaries can be loaded into GHCi, but if you do so it will not make the | imports available to you for use. Thus my main.hs has the header | import Matrix | import Parsefile | import Array | import NetPrams | import System.IO.Unsafe | | ..... | | If main.hs has not been brought up to date, I can load main.hs into the | interpreter and the functions defined in Matrix for example will be in | scope and usable. If on the other hand I've just run ghc on main, I can | load main.hs in, but the functions in Matrix will not be available. | Perhaps the solution is to create a script file that loads all the | modules in and adds them to the current scope. The GHC user manual discusses this point: http://www.haskell.org/ghc/docs/latest/html/users_guide/ch03s04.html#ghc i-scope When you *compile* a module, GHC does a whole lot of inlining, and functions that are exported may not even exist any more. That's why you can't necessarily see the full top-level scope of a compiled module (the :m *M form described in the manual). If you *interpret* a module, GHC is careful never to discard any top-level definition, so that you can see the full top-level scope, just as you wrote it. Maybe there should be a way to tell GHC to retain top level defns even when compiling; but currently the story is that you must interpret the .hs files if you want to see the top level defns. Simon

Well now that I understand how it works, I'm perfectly happy with the current functionality. As long as I put all my FFI imports into one module and compile that, then I can load the other modules into GHCi at will during development and testing. I was going to do some FFI imports into another module but will forgo that. I did run into an amusing problem where my matrices were not being updated after a :reload operation (or was it a :load?) and a re-evalution of main in GHCi. I view the matrices as constant globals, and therefore do an unsafePerformIO to get their indices. Another evaluation of main left the indices unchanged pointing to the old matrices. At least that what appears to have happen. I should probably take a closer look when I have a second. Simon Peyton-Jones wrote:
| I think I understand my issue now with this (other than the anomaly of | the above example). I've been using the make option with ghc to compile | all the dependent sources, creating binaries for all of them. Those | binaries can be loaded into GHCi, but if you do so it will not make the | imports available to you for use. Thus my main.hs has the header | import Matrix | import Parsefile | import Array | import NetPrams | import System.IO.Unsafe | | ..... | | If main.hs has not been brought up to date, I can load main.hs into the | interpreter and the functions defined in Matrix for example will be in | scope and usable. If on the other hand I've just run ghc on main, I can | load main.hs in, but the functions in Matrix will not be available. | Perhaps the solution is to create a script file that loads all the | modules in and adds them to the current scope.
The GHC user manual discusses this point:
http://www.haskell.org/ghc/docs/latest/html/users_guide/ch03s04.html#ghc i-scope
When you *compile* a module, GHC does a whole lot of inlining, and functions that are exported may not even exist any more. That's why you can't necessarily see the full top-level scope of a compiled module (the :m *M form described in the manual). If you *interpret* a module, GHC is careful never to discard any top-level definition, so that you can see the full top-level scope, just as you wrote it.
Maybe there should be a way to tell GHC to retain top level defns even when compiling; but currently the story is that you must interpret the .hs files if you want to see the top level defns.
Simon

On 7/22/06, Matthew Bromberg
I used what I thought, initially was an elegant contruction technique in Haskell. Something like this do ... sequence $ [ reffill b s | s <- [0..(fi temits)-1], b <- [0..(fi nc)-1]] ...(push list on to matrix stack)
Try the sequence_ (note the underscore) function, it should be a big win here. Cheers, Spencer Janssen

1) Lack of debugging support. Yes there are print statements and trace, but I would like to set a breakpoint. It would be nice to do so and launch the GHCi interpreter with all the variable context supported. A google search revealed that there is current work on this, but unfortunately the package is in cabal, which has spotty support in windows it seems.
You can find more info about this project in the Haskell wiki at: http://haskell.org/haskellwiki/Ghci/Debugger All you'd need to do is to compile ghc-6.5 with a few patches (if you are in Windows you can use MinGW). But I am afraid you are right, this is a work in progress and we are in the process of polishing some serious issues right now. I can't really recommend it for now. Cheers pepe

Hello Pepe, Sunday, July 23, 2006, 5:23:18 PM, you wrote:
1) Lack of debugging support. Yes there are print statements and trace,
You can find more info about this project in the Haskell wiki at: http://haskell.org/haskellwiki/Ghci/Debugger
All you'd need to do is to compile ghc-6.5 with a few patches (if you are in Windows you can use MinGW). But I am afraid you are right, this is a work in progress and we are in the process of polishing some serious issues right now. I can't really recommend it for now.
is this will be really usable without gui support? your project is really great, but i think it's too early to recommend it for real work (as opposite to hacking/integration with IDEs) -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

Bulat, now that Krasimir has resumed work on Visual Haskell, I have
planned to pursue an integration of the ghc-api debugger with Visual
Haskell as soon as possible.
But as we get closer to having dynamic breakpoints working 100%, the
plain ghci debugging support starts to look as a fairly nice addition
to anyone's ghc toolkit.
Of course, I agree with you that it's too early to recommend it for real work.
On 23/07/06, Bulat Ziganshin
Hello Pepe,
Sunday, July 23, 2006, 5:23:18 PM, you wrote:
1) Lack of debugging support. Yes there are print statements and trace,
You can find more info about this project in the Haskell wiki at: http://haskell.org/haskellwiki/Ghci/Debugger
All you'd need to do is to compile ghc-6.5 with a few patches (if you are in Windows you can use MinGW). But I am afraid you are right, this is a work in progress and we are in the process of polishing some serious issues right now. I can't really recommend it for now.
is this will be really usable without gui support? your project is really great, but i think it's too early to recommend it for real work (as opposite to hacking/integration with IDEs)
-- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

Bulat Ziganshin wrote:
Hello Pepe,
Sunday, July 23, 2006, 5:23:18 PM, you wrote:
1) Lack of debugging support. Yes there are print statements and trace,
You can find more info about this project in the Haskell wiki at: http://haskell.org/haskellwiki/Ghci/Debugger
All you'd need to do is to compile ghc-6.5 with a few patches (if you are in Windows you can use MinGW). But I am afraid you are right, this is a work in progress and we are in the process of polishing some serious issues right now. I can't really recommend it for now.
is this will be really usable without gui support? your project is really great, but i think it's too early to recommend it for real work (as opposite to hacking/integration with IDEs)
I'm pretty excited about the GHCi debugger work. The reasons are all to do with practicality - there is very little that is a technical improvement over other soltions in this work (although there are some difficult engineering issues which Pepe has done some great work on solving). I think this work is important because it gives everyone access to debugging facilities with the minimum of hassle. If you're already using GHCi, then you can set breakpoints - with no side conditions, no extra packages to install, no need to recompile your program, and no restrictions on what your program can do or what language it is written in. It Just Works, all the time, everywhere that GHCi is supported. (ok, so you have to use the interpreter for modules with breakpoints, but that's not a serious problem). Sure, it doesn't have all the cool features of Hat, but it wins on immediacy, and that's why I think it will succeed. Furthermore, because the functionality will be exposed by the GHC API, it is available to the IDE developers too. Cheers, Simon

Hello Simon, Monday, July 24, 2006, 2:53:21 PM, you wrote:
is this will be really usable without gui support? your project is
I think this work is important because it gives everyone access to debugging facilities with the minimum of hassle. If you're already using GHCi, then you can set breakpoints - with no side conditions, no extra packages to install, no
i don't have any gdb experience and wonder whether console debugger (without GUI to browse sources debugged) may be useful in real life. integration of debugger with visual haskell or eclipse will, imho, bring Haskell to the next level of usefulness - when it can be used by average application programmers, who are need RAD tools to develop and debug their code -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

What's different about this kind of console debugger is that you have the power of the entire language at your disposal via the interpreter at a given breakpoint. This is a bit more powerful than typical debugging capabilities. It goes beyond just inspecting the values of variables, one can actually execute commands and process data at any given point of the program with the full context of the program at the breakpoint. That's pretty powerful and is often used in scripting languages and is probably one of the reasons why Matlab is so incredibly productive for science and engineering problems. Yes it's nice to have a graphical link to the source, but given a choice I'd take the GHCi breakpoint capability over the visual link to source code. Bulat Ziganshin wrote:
Hello Simon,
Monday, July 24, 2006, 2:53:21 PM, you wrote:
is this will be really usable without gui support? your project is
I think this work is important because it gives everyone access to debugging facilities with the minimum of hassle. If you're already using GHCi, then you can set breakpoints - with no side conditions, no extra packages to install, no
i don't have any gdb experience and wonder whether console debugger (without GUI to browse sources debugged) may be useful in real life. integration of debugger with visual haskell or eclipse will, imho, bring Haskell to the next level of usefulness - when it can be used by average application programmers, who are need RAD tools to develop and debug their code

Matthew,
On 7/22/06, Matthew Bromberg
I'm not using an IDE does one exist?
You may want to use EclipseFP for your Haskell work. It is still a work in progress, but it may be worth to give it a try. http://eclipsefp.sourceforge.net Cheers, Thiago Arrais

2) Recompiling binaries (necessary in order to link in foreign object code into GHCi) is slow using GHC. Moreover I have to restart GHCi if I want to reload a changed DLL (unless there is a way to unload a DLL in GHCi). It also requires jumping around between several console windows to get the job done. (I'm not using an IDE does one exist?) There are several. (I know of one using visual studio and eclipsefp).. It should|nt be a problem to find them.. But I still prefer vim :)
Concerning switching between several console windows... Perhaps try something like mrxvt which has several tabs to run more than one shell. You can then use key combinations to switch.. (I haven't used mrxvt on cygwin yet but I've read that it runs there) Marc

marco-oweber:
2) Recompiling binaries (necessary in order to link in foreign object code into GHCi) is slow using GHC. Moreover I have to restart GHCi if I want to reload a changed DLL (unless there is a way to unload a DLL in GHCi). It also requires jumping around between several console windows to get the job done. (I'm not using an IDE does one exist?) There are several. (I know of one using visual studio and eclipsefp).. It should|nt be a problem to find them.. But I still prefer vim :)
Concerning switching between several console windows... Perhaps try something like mrxvt which has several tabs to run more than one shell. You can then use key combinations to switch.. (I haven't used mrxvt on cygwin yet but I've read that it runs there)
Marc
Or use a more efficient window manager, i.e. ion or wmii let you navigate entirely from the keyboard, as if you were inside an editor. -- Don

vim has been my choice as well. Now that vim 7.0 has tabbed windows it's better than ever. All they need now is a way to integrate it with a console window.... I guess you can find scite/scintilla settings for Haskell as well http://www4.in.tum.de/~haftmann/resources/haskell.properties Marc Weber wrote:
2) Recompiling binaries (necessary in order to link in foreign object code into GHCi) is slow using GHC. Moreover I have to restart GHCi if I want to reload a changed DLL (unless there is a way to unload a DLL in GHCi). It also requires jumping around between several console windows to get the job done. (I'm not using an IDE does one exist?)
There are several. (I know of one using visual studio and eclipsefp).. It should|nt be a problem to find them.. But I still prefer vim :)
Concerning switching between several console windows... Perhaps try something like mrxvt which has several tabs to run more than one shell. You can then use key combinations to switch.. (I haven't used mrxvt on cygwin yet but I've read that it runs there)
Marc _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Matthew Bromberg wrote:
Here are some reasons why 1) Lack of debugging support. Yes there are print statements and trace, but I would like to set a breakpoint. It would be nice to do so and launch the GHCi interpreter with all the variable context supported. A google search revealed that there is current work on this, but unfortunately the package is in cabal, which has spotty support in windows it seems. 2) Recompiling binaries (necessary in order to link in foreign object code into GHCi) is slow using GHC. Moreover I have to restart GHCi if I want to reload a changed DLL (unless there is a way to unload a DLL in GHCi). It also requires jumping around between several console windows to get the job done. (I'm not using an IDE does one exist?)
The reloading DLLs issue has come up before in the context of wxHaskell. Please submit a task to GHC's tracker at http://hackage.haskell.org/trac/ghc. This is something we could work on at the Hackathon, perhaps.
4) GHCi is really not as useful as I'd hoped. You can not just cut and paste Haskell code from a text file and run it in the interpreter.
Here's a bit of GHCi macro hacking that lets you type in source file declarations: Prelude> let loop = do l <- getLine; if l == "\^D" then return () else do appendFile "foo.hs" (l++"\n"); loop Prelude> :def foo (\_ -> loop >> return ":load foo.hs") Prelude> :foo x = 42 ^D Compiling Main ( foo.hs, interpreted ) Ok, modules loaded: Main. *Main> x 42 *Main> Type ":foo" to start entering declarations, and "^D" (followed by enter, unfortunatly) to stop and load the file. This is just a quick hack, but it could be improved in lots of ways: add a :reset to unload the file, use :add instead of :load so you can use it in the context of a larger program, etc. etc. You get the idea. Cheers, Simon
participants (18)
-
Alberto Ruiz
-
Bertram Felgenhauer
-
Brian Hulley
-
Bulat Ziganshin
-
David F. Place
-
dons@cse.unsw.edu.au
-
Jared Updike
-
Jason Dagit
-
Malcolm Wallace
-
Marc Weber
-
Matthew Bromberg
-
Neil Mitchell
-
Pepe Iborra
-
SevenThunders
-
Simon Marlow
-
Simon Peyton-Jones
-
Spencer Janssen
-
Thiago Arrais