DLL problem with GHC 6.0.1

2003-08-01 Thread Mark Tehver
Hi,

I have run into something in GHC that looks
like a bug (GHC 6.0.1 under Win2k). A DLL with several exported
FFI functions reports (and then terminates):

ghcDll: internal error: schedule: invalid what_next field
Please report this as a bug to [EMAIL PROTECTED],
or http://www.sourceforge.net/projects/ghc/

What is really strange: I get this error ONLY when I run my
application (C++ code which loads the DLL dynamically) under MS
Visual Studio 6 in Debug Mode. When I run the same executable
from shell/command prompt, then everything works. Also, when I
compile the DLL with GHC version 5.x, I can run the application
from Visual Studio 6 without problems. So this seems to be GHC 6.x specific.

Not 100% sure, but looks like I get this error on a first call to
any FFI function. Unfortunately the application is rather large but
I could try to simplify it. I had this problem also with GHC 6.0.0.
Any ideas?

Regards,
Mark Tehver

___
Glasgow-haskell-bugs mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs


RE: Strange Building problem...

2003-08-01 Thread Simon Marlow
 
 On Thu, 31 Jul 2003 13:57:02 +0100, you wrote:
  What is odd is that ghc-inplace is invoked by the make 
 process several
  times before this big one (which appears to be the start 
 of stage 2?)
  and works fine...
 Do the errors really refer to GHCziBase_True_Closure, or is it
 GHCziBase_True_closure? (with lower-case 'c')?
 
 It's a lower-case 'c'.  Sorry - I typed it out by hand as the build is
 on a different machine.

Could you check the following things:

  - ghc/driver/package.conf: is it empty?  Does it contain
reasonable-looking package entries?

  - Is there a discrepancy between leading underscores on the
symbols in libHSbase.a and the missing symbols?

Cheers,
SImon
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Strange Building problem...

2003-08-01 Thread Mark Green
On Fri, 1 Aug 2003 12:38:09 +0100, you wrote:

 It's a lower-case 'c'.  Sorry - I typed it out by hand as the build is
 on a different machine.

Could you check the following things:
  - ghc/driver/package.conf: is it empty?  Does it contain
reasonable-looking package entries?

  It is not empty and the entries look reasonable.

  - Is there a discrepancy between leading underscores on the
symbols in libHSbase.a and the missing symbols?

  No; neither have any leading underscores.

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


RE: Strange Building problem...

2003-08-01 Thread Simon Marlow
 
  It's a lower-case 'c'.  Sorry - I typed it out by hand as 
 the build is
  on a different machine.
 
 Could you check the following things:
   - ghc/driver/package.conf: is it empty?  Does it contain
 reasonable-looking package entries?
 
   It is not empty and the entries look reasonable.
 
   - Is there a discrepancy between leading underscores on the
 symbols in libHSbase.a and the missing symbols?
 
   No; neither have any leading underscores.

Can you compile a small hello world-type program using
ghc/compiler/stage1/ghc-inplace?

Cheers,
Simon
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Strange Building problem...

2003-08-01 Thread Mark Green
On Fri, 1 Aug 2003 12:51:21 +0100, you wrote:
 
   It is not empty and the entries look reasonable.
   - Is there a discrepancy between leading underscores on the
 symbols in libHSbase.a and the missing symbols?
   No; neither have any leading underscores.
Can you compile a small hello world-type program using
ghc/compiler/stage1/ghc-inplace?

$ more hello.hs
main = print Hello world!
$ ./ghc-inplace hello.hs
hello.o(.text+0x28): In function 'rE8_srt': undefined reference to
'GHCziShow_zdfShowChar_closure

[ another of the same error ]

[ another of the same but this time referring to 
GHCziBase_unpackCStringzh_closure ]

/home/mark/ghc-6.0/libraries/base/libHSbase.a(Show__178.o)(.text+0x0):
In function 'GHCziShow_zdfShowZMZN_srt': undefined reference to
'GHCziShow_lvl16_closure'

[A LARGE number of similar errors all within libHSbase.a]

[Similar errors in libHSrts.a]

[Invoking the already installed ghc from the .deb to check the program
isn't the problem..]
$ ghc hello.hs
Compilation was NOT necessary
$ ./a.out
Hello world!

Thanks for your help,
Mark.
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


RE: Strange Building problem...

2003-08-01 Thread Simon Marlow
 
 On Fri, 1 Aug 2003 12:51:21 +0100, you wrote:
  
It is not empty and the entries look reasonable.
- Is there a discrepancy between leading underscores on the
  symbols in libHSbase.a and the missing symbols?
No; neither have any leading underscores.
 Can you compile a small hello world-type program using
 ghc/compiler/stage1/ghc-inplace?
 
 $ more hello.hs
 main = print Hello world!
 $ ./ghc-inplace hello.hs
 hello.o(.text+0x28): In function 'rE8_srt': undefined reference to
 'GHCziShow_zdfShowChar_closure

Perhaps this is a gcc-3.3 problem.  I notice that you're compiling ghc
6.0 rather than 6.0.1, and 6.0 had some problems with gcc 3.3.

Could you try compiling 6.0.1 instead, and see if that helps?

Cheers,
Simon
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Use of H98 FFI

2003-08-01 Thread Peter Thiemann
I recently had my first exposure to Haskell's FFI when I was trying to
compute MD5 and SHA1 hashes using the existing C implementations. In
each case, the idea is to make the hash function available as function

 md5 :: String - String

However, the naive implementation

 md5_init md5_state
 n - newCString str
 md5_append md5_state n (fromIntegral (length str))
 md5_finish md5_state md5_digest

does not scale to computing hashes of really long strings (50 MB, say,
as arising from reading a moderately big file), since it tries to
create a CString of that size, first! 

Trying to avoid the allocation of this giant CString requires to split
up the original string into smaller parts and convert each part to a
CString separately. Clearly, this task involves a lot of allocation,
essentially the input string needs to be copied part by part.

Hence, I was wondering why the FFI only provides functionality to
convert an *entire* list of Char into a CString. For applications like
this hash computation, it would be advantageous to be able to specify
*how much* of the input string to marshall to the CString and have the
conversion function return the rest of the input string and the
CString. That is, in addition to 

 newCString :: String - IO CString

there should be

 newCStringPart :: String - Int - IO (CStringLen, String)

or even

 toCStringPart :: String - CStringLen - IO (Int, String)

where CStringLen describes a target buffer into which the String
argument is to be marshalled.  (and similarly for other list types)

Clearly, I can program this functionality by hand. But I have to
revert to byte-wise processing using pokeByteOff, castCharToCChar, and
so on. In addition, the optimizer does not seem to be very effective on
such code, so it seems advantageous to provide it in the library
already.

But perhaps I'm overlooking something, so I'm appending the code I was
using below.

-Peter



MD5.hs
Description: three interfaces to MD5


Re: Use of H98 FFI

2003-08-01 Thread Sven Panne
Peter Thiemann wrote:
md5 :: String - String
Hmmm, this should probably be:

 md5 :: [Word8] - [Word8]

unless you really want the MD5 of the Unicode characters...

Cheers,
   S.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: Use of H98 FFI

2003-08-01 Thread Derek Elkins
On 01 Aug 2003 09:44:14 +0200
Peter Thiemann [EMAIL PROTECTED] wrote:

 I recently had my first exposure to Haskell's FFI when I was trying to
 compute MD5 and SHA1 hashes using the existing C implementations. In
 each case, the idea is to make the hash function available as function
 
  md5 :: String - String
 
 However, the naive implementation
 
  md5_init md5_state
  n - newCString str
  md5_append md5_state n (fromIntegral (length str))
  md5_finish md5_state md5_digest
 
 does not scale to computing hashes of really long strings (50 MB, say,
 as arising from reading a moderately big file), since it tries to
 create a CString of that size, first! 
 
 Trying to avoid the allocation of this giant CString requires to split
 up the original string into smaller parts and convert each part to a
 CString separately. Clearly, this task involves a lot of allocation,
 essentially the input string needs to be copied part by part.
 
 Hence, I was wondering why the FFI only provides functionality to
 convert an *entire* list of Char into a CString. For applications like
 this hash computation, it would be advantageous to be able to specify
 *how much* of the input string to marshall to the CString and have the
 conversion function return the rest of the input string and the
 CString. That is, in addition to 
 
  newCString :: String - IO CString
 
 there should be
 
  newCStringPart :: String - Int - IO (CStringLen, String)
 
 or even
 
  toCStringPart :: String - CStringLen - IO (Int, String)
 
 where CStringLen describes a target buffer into which the String
 argument is to be marshalled.  (and similarly for other list types)
 
 Clearly, I can program this functionality by hand. But I have to
 revert to byte-wise processing using pokeByteOff, castCharToCChar, and
 so on. In addition, the optimizer does not seem to be very effective
 on such code, so it seems advantageous to provide it in the library
 already.
 
 But perhaps I'm overlooking something, so I'm appending the code I was
 using below.
 
 -Peter

Except that I would probably mapM_ over a list of chunks, I don't
see what the problem is with your second version of the code is.

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: *safe* coerce, for regular and existential types

2003-08-01 Thread Ralf Laemmel
[EMAIL PROTECTED] wrote:
 
 ... loads of cunning stuff omitted 


Software-engineering-wise your approach suffers
from an important weakness: a closed world assumption.
The programmer has to maintain your TI and pass it
on in all kinds of contexts for the array of types to
be handled. I also had a type-safe and efficient cast
in [1] with a CWA. (I guess it works fine for
extensials.) My CWA was even more serious however.
I use a class for casting whose declaration even
depends on the array of types to be handled. On the
positive side, I didn't need undecidable not even
overlapping instances. Also, the programmer is not
concerned with passing on any type seq like your
TI. I really admire your use of polymorphic lists
(which are in fact kind of products) to get the
problem of type sequences to the value level. Cool!

Do you see any way to effectively remove this CWA?
(Only then it could serve as a replacement of the
current cast function.) If yes, would you expect that
your approach is more efficient then the one taken in
Data.Typeable? (We recently split up Data.Dynamics
into Data.Dynamics and a more primitive module
Data.Typeable which contains cast; see CVS) Is it obvious
to see that fetching stuff from the type sequences would
be indeed efficient for long PLists? Well, I guess the
hard problem is the CWA anyway.

Ralf

[1] The Sketch of a Polymorphic Symphony
http://homepages.cwi.nl/~ralf/polymorphic-symphony/
See the Larghetto movement
It is trivial; it makes Stephanie Weirich's type-safe
cast fit for nominal type analysis.


-- 
Ralf Laemmel
VU  CWI, Amsterdam, The Netherlands
http://www.cs.vu.nl/~ralf/
http://www.cwi.nl/~ralf/
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: a breaking monad

2003-08-01 Thread Tomasz Zielonka
On Thu, Jul 31, 2003 at 05:15:33PM -0400, Derek Elkins wrote:
 On Thu, 31 Jul 2003 13:18:40 -0700
 Hal Daume [EMAIL PROTECTED] wrote:
 
  so, my questions are: does this exist in some other form I'm not aware
  of?  is there something fundamentally broken about this (sorry for the
  pun)?  any other comments, suggestions?
 
 This looks like a bizarre rendition of the Error/Exception monad.
 
 I believe the function breakable would be fairly accurately
 represented with '\b - runErrorT b = either return return' and use
 throwError for break.

I used the Cont(inuation) monad for similar purposes. This has an
advantage that you can choose a place to break (jump?) into, each place
having a possibly different type of return value.

Here's an example:

  module A where

  import Control.Monad.Cont
  import Control.Monad

  fun :: IO ()
  fun = (`runContT` return) $ do
  r - callCC $ \exit - do
  r1 - callCC $ \exit1 - do
  r2 - callCC $ \exit2 - do
  r3 - callCC $ \exit3 - do
  x - liftIO (readLn :: IO Int)
  when (x == 2) (exit2 two)   -- jump with a String
  when (x == 1) (exit1 1)   -- jump with an Int
  when (x == 3) (exit3 [three])   -- with [String]
  (exit other)
  return []
  liftIO $ putStrLn $ r3:  ++ show r3
  exit1 3   -- jump with Int
  return three
  liftIO $ putStrLn $ r2:  ++ show r2
  return 2
  liftIO $ putStrLn $ r1:  ++ show r1
  return (show r1)
  liftIO $ putStrLn $ r:  ++ show r

After running fun, type a number ([1..4]) and press Enter.

PS. Are there other uses of Cont monad?

Best regards,
Tom

-- 
.signature: Too many levels of symbolic links
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: a breaking monad

2003-08-01 Thread Derek Elkins
On Fri, 1 Aug 2003 12:02:00 +0200
Tomasz Zielonka [EMAIL PROTECTED] wrote:

 On Thu, Jul 31, 2003 at 05:15:33PM -0400, Derek Elkins wrote:
  On Thu, 31 Jul 2003 13:18:40 -0700
  Hal Daume [EMAIL PROTECTED] wrote:
  
   so, my questions are: does this exist in some other form I'm not
   aware of?  is there something fundamentally broken about this
   (sorry for the pun)?  any other comments, suggestions?
  
  This looks like a bizarre rendition of the Error/Exception monad.
  
  I believe the function breakable would be fairly accurately
  represented with '\b - runErrorT b = either return return' and
  use throwError for break.
 
 I used the Cont(inuation) monad for similar purposes. This has an
 advantage that you can choose a place to break (jump?) into, each
 place having a possibly different type of return value.

I was thinking of providing a Cont example too.

 PS. Are there other uses of Cont monad?

I've used it for resumptions, and I imagine you could use it to handle
the CP in an optimized via CPS function, though that likely isn't
worthwhile (heh).  Hinze's Backtracking monad uses CPS but not the Cont
monad, though it may be representable with ContT over Cont, I'm pretty
sure shift/reset can get the same effect.

Less immediately practical, I've experimented with shift/reset with it.
I'm kind of interested in translating Filinsky's monadic reification and
reflection into Haskell with the Cont(T) monad.  This would probably
have no real practical benefit (or would it... run-time changing?), I
believe a similar effect usage-wise can be achieved by using a class for
the monad parameter (MonadState/etc.) It would be more practical if a
compiler internally supported a Cont(T) monad.

Anyways, most of my uses of the Cont monad have been for my own personal
entertainment, and usually I break the abstraction (using
Control.Monad.Cont) to do the things I want.  I don't know if I've ever
written something that's used callCC that I kept.

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


ANN: H98 FFI Addendum 1.0, Release Candidate 12

2003-08-01 Thread Manuel M T Chakravarty
Dear Haskell Folks,

Release Candidate 12 of the H98 FFI Addendum 1.0 is now
available from

  http://www.cse.unsw.edu.au/~chak/haskell/ffi/

Since the release of RC 11 (12 June), there was only one
small change (which was already under discussion before RC
11 was published).  Hence, I consider Version 1.0 of the FFI
Addendum to be completed; no changes except linguistic ones
and plain error corrections will be accepted anymore for
this version.

Cheers,
Manuel

-=-

Changes since RC11:
* 5.5: Swapped argument order of `newForeignPtr' and `addForeignPtrFinalizer'

Note to FFI people, there were at least three votes
(Alastair, Sven, and me) for this change and none against.
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Submission deadline SNPD03 approaching

2003-08-01 Thread Annette Stümpel
==
CALL FOR PAPERS

Fourth International Conference on
Software Engineering, Artificial Intelligence,
Networking, and Parallel/Distributed Computing (SNPD03)

October  16-18, 2003
Luebeck, Germany

http://www.isp.uni-luebeck.de/snpd03/index.htm
==


Scope and Topics

The conference provides an international forum for scientists
to present research results in the areas of software engineering,
artificial intelligence, networking and parallel/distributed
computing. The conference particularly welcomes contributions
at the junction of theory and practice disseminating basic
research with immediate impact on practical applications. The
conference will cover a broad range of topics including theory,
methods, applications, and tools. The conference concentrates
on software issues and is structured into the following tracks:

Software Engineering and Information Engineering
Component-Based Software Engineering
Internet Technology and Applications
Information Management Systems
Software Engineering Education
Parallel and Distributed Computing
Communication Systems and Networks
Mobile and Wireless Computing
Visual and Multimedia Computing
Artificial Intelligence, Data Mining, Knowledge Discovery
Neural Networks and Genetic Algorithms
Economic and Financial Systems
Control Systems
Image, Acoustic, Speech and Signal Processing

Venue
=
After Reims (2000), Nagoya (2001) and Madrid (2002) this years
SNPD conference will be held at the Moevenpick Hotel in Luebeck.
The Hanseatic town of Luebeck is located in Northern Germany
close to the Baltic Sea with frequent train connections to major
airports. The medieval town was appointed as world cultural
heritage by the United Nations.

Important Deadlines
===
Full Paper Submission:   August 15, 2003
Notification of Acceptance:  September 10, 2003
Camera-ready Papers: September 24, 2003

Conference Proceedings  Journal

Accepted papers limited to 8 pages will be published
in the conference proceedings with ISBN. After the
conference a selection of excellent papers will be
published in a special issue of the International
Journal of Computer and Information Science.

For further details, please visit the conference web page
http://www.isp.uni-luebeck.de/snpd03/index.htm.



___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


CSMR 2004 - CALL FOR PAPERS

2003-08-01 Thread csmr2004



8th European Conference on Software
Maintenance and Reengineering
March 24 - 26, 2004
Tampere, Finland
 
Call for Papers

The European Conference on Software Maintenance is the premier European conference on 
the theory and practice of evolution, maintenance and reengineering of software 
systems. Now approaching its eight edition, we invite you to contribute to the 
discussion on the issues of developing maintainable systems and evolving, migrating 
and reengineering existing ones. 

The theme of this year's conference will be the maintenance and evolution of the 
software architecture. Although nowadays the importance of designing a robust 
software architecture is well-understood by the industry, the activities related to 
its maintenance and evolution are rather immature and unsystematic. We solicit 
contributions on this theme. 

The topics of interest include, but are not restricted to: 

Evolution, maintenance and reengineering 
Software architecture recovery and evolution 
Automated software maintenance 
Software metrics 
Economical aspects of software evolution 
Pattern languages for evolution, maintenance and reengineering 
Experience reports (successes and failures) 
Tools and enabling technologies for evolution, maintenance and reengineering tools 
Formal methods to support evolution, maintenance and reengineering 
System assessment for evolution, maintenance and reengineering 
Migration, wrapping and interfacing legacy systems 
Dealing with legacy systems towards new technologies 
Data reengineering 
Reverse engineering of embedded systems 
Web-site evolution, maintenance and reengineering 
Migration towards Web-services 
Evaluation and assessment of reverse engineering tools 
Maintenance of open source projects 
Product family migration and maintenance 
One of the basic intentions of this conference is to offer a European forum for 
discussion and exchange of experiences among researchers and practitioners. Therefore, 
besides academics, we kindly invite all those in companies developing maintenance 
tools, offering reengineering services or going through legacy systems migration 
experiences to contribute by submitting papers or presenting innovative tools, 
solutions or experience reports. This conference is not limited to European 
participants. Authors from outside Europe are also welcomed. 

SUBMISSIONS
Two types of submissions will be accepted: full length papers (not exceeding 4000 
words in length and including a 150-200 word abstract) and short papers (not exceeding 
2000 words in length and including a 75-100 word abstract) The official langue is 
Enligh. Authors are requested to submit electronically a PostScript or PDF version of 
their papers. In addition, they should send a separate file containing the title of 
the paper, full names, affiliations, postal and e-mail addresses, fax and telephone 
numbers of all authors. 

IEEE Computer Society Press will publish the CSMR 2004 Proceedings. Full papers 
exceeding 10 pages (4 pages for short papers) will be charged for pages in excess. 
Authors of accepted papers must sign the IEEE copyright form. 

At least one author of each accepted submission must register and present the paper at 
the conference. 

The Program Committee will select the best paper of the conference and a prize will be 
awarded for the winner. The Program Committee will select the winner and a formal 
presentation of the winner will be made in Tampere at CSMR 2004. 

SPECIAL SESSIONS
Sessions of special interest, workshops, and tool demonstrations are welcomed. Please 
send suggestions to the program chair before the submissions closing date. 

SUBMISSION METHOD
For submission details please visit the conference website: 
http://www.cs.tut.fi/~csmr2004/. Papers can also be submitted via email to the program 
chair. 

FINAL FORMAT OF PAPERS
Accepted papers must be revised to conform with IEEE style guidelines at 
http://www.computer.org/cspress/instruct.htm. 
 
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: Libraries and hierarchies

2003-08-01 Thread John Meacham
confluence! Inspired by some posts the other day I implemented an
immutable GUID naming scheme for interfaces with Haskell. I thought it
would require compiler support, but it turns out a good 90% solution can
be done as a separate program quite nicely and there are not too tough
workarounds for the other 10%.

http://repetae.net/john/computer/haskell/hsguid/

This is not really the same as your proposal, but is somewhat related
and addresses many of the same issues. (and might be a bit lighter
weight) 

actually, they would probably mix well as your proposed system could
just use the same GUID pragmas hsguid uses as input.

Let me know what y'all think. library developers, add a GUID to your
code. it's easy and takes no resources, but could save users of your
library a lot of hassle. :)
John
-- 
---
John Meacham - California Institute of Technology, Alum. - [EMAIL PROTECTED]
---
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: Use of H98 FFI

2003-08-01 Thread Peter Thiemann
 Derek == Derek Elkins [EMAIL PROTECTED] writes:

Derek 

Derek Except that I would probably mapM_ over a list of chunks, I don't
Derek see what the problem is with your second version of the code is.

The second version allocates memory like crazy, so much that the
pokeByteOff and castCharToCChar version becomes twice roughly twice as
fast. Here are some figures [all compiled with -O2, otherwise version
c looses badly]: 

s - hash in one go
a - chunks of 512 characters
c - byte-wise

[on 51MB String]
Main a : 58.730u 1.440s 1:00.13 100.0%   0+0k 0+0io 182pf+0w
Main c : 29.370u 0.740s 0:30.07 100.1%   0+0k 0+0io 182pf+0w
[on 32MB String]
Main a : 37.500u 1.100s 0:38.58 100.0%   0+0k 0+0io 182pf+0w
Main c : 18.790u 0.510s 0:19.43 99.3%0+0k 0+0io 182pf+0w
[on 500k String]
Main s : 0.560u 0.120s 0:00.66 103.0%0+0k 0+0io 182pf+0w
Main a : 0.610u 0.010s 0:00.59 105.0%0+0k 0+0io 182pf+0w
Main c : 0.290u 0.000s 0:00.27 107.4%0+0k 0+0io 182pf+0w

So the generally most efficient seems to be to use c, but I suspect
that further gains would be possible if this variant were implemented
at a lower level. Hence the proposal for newCStringPart.

-Peter
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: Libraries and hierarchies

2003-08-01 Thread Keith Wansbrough
[stuff about GUIDs]

Careful!  There are two things one might tie GUIDs to.

You could compute a hash of (or associate a GUID with) the *interface*, 
or the *implementation*.  These are different things.  Until we know 
which we want, we should support both.

Why?

One might reasonably say this program needs version X of the 
interface.  That is, we don't care how it's implemented, but it had 
better export these functions at these types.

But one might also reasonably say this program needs version Y of the 
implementation.  That is, it requests a particular *implementation* - 
maybe it depends on certain bugs that are fixed in that version (or are 
not fixed!).  Or it's only been tested against that implementation, and 
it wants to provide some certification guarantees (This software is 
DoD-certified to give appropriate results with specified inputs).

A side point is that GUIDs can be generated in two ways:

1. The traditional way: make up a 128-bit random number and insert it 
into the interface or implementation (as appropriate).  Use this as the 
name for that thing.

2. The nifty way: have the compiler compute a hash (SHA-1 or MD5) of 
the interface or implementation (as appropriate).  Use this as the name 
for that thing.

Option (2) has the advantage that it's one step shorter, and it's 
safer: with (1), you can generate one GUID but accidentally use it on 
two distinct interfaces / implementations; with (2), this is 
(essentially) impossible (although it may be possible to achieve a 
collision intentionally; malice is a separate issue that should be 
addressed in other ways).

For (2), we need to agree what to hash.  The options are basically the 
source text of the module (or some sub-part of it for the interface 
case), or the abstract syntax tree of the module.  The latter is 
probably nicer, but requires some agreement between compiler writers if 
it is to be valid across compilers.


For background to this discussion, see our forthcoming ICFP paper,

James J. Leifer, Gilles Peskine, Peter Sewell, Keith Wansbrough (2003). 
Global Abstraction-Safe Marshalling with Hash Types

which is available at

http://www.cl.cam.ac.uk/~kw217/research/paper-abstracts.html#Leifer*03:G
lobal


Comments?

--KW 8-)
-- 
Keith Wansbrough [EMAIL PROTECTED]
http://www.cl.cam.ac.uk/users/kw217/
University of Cambridge Computer Laboratory.

___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: Libraries and hierarchies

2003-08-01 Thread John Meacham
On Fri, Aug 01, 2003 at 05:00:55PM +0100, Keith Wansbrough wrote:
 [stuff about GUIDs]
 
 Careful!  There are two things one might tie GUIDs to.
 
 You could compute a hash of (or associate a GUID with) the *interface*, 
 or the *implementation*.  These are different things.  Until we know 
 which we want, we should support both.
yes, which is why each library can export an arbitrary number of GUIDs.
Oddly enough, I considered doing what you mentioned below (a hash of the
interface). but chose not to so that the same interface can be exported
under several GUIDs. this reflects the fact that there could be hidden
assumptions (such as relying on bugs) in interfaces which should be
reflected in the GUID. I also wanted the tool to have simple
semantics relative the haskell base language. thinking of it as modules
just having multiple Module declarations and export lists should make it
easy to adopt. 

plus, this was much easier to implement as a first stab at the problem :)

 One might reasonably say this program needs version X of the 
 interface.  That is, we don't care how it's implemented, but it had 
 better export these functions at these types.

 But one might also reasonably say this program needs version Y of the 
 implementation.  That is, it requests a particular *implementation* - 
 maybe it depends on certain bugs that are fixed in that version (or are 
 not fixed!).  Or it's only been tested against that implementation, and 
 it wants to provide some certification guarantees (This software is 
 DoD-certified to give appropriate results with specified inputs).

The idea then is that you would hsguid -g twice to generate an
implementation ID and an interface id. old implementations could be
archived and their interface id deleted.

 A side point is that GUIDs can be generated in two ways:
 
 1. The traditional way: make up a 128-bit random number and insert it 
 into the interface or implementation (as appropriate).  Use this as the 
 name for that thing.
 
 2. The nifty way: have the compiler compute a hash (SHA-1 or MD5) of 
 the interface or implementation (as appropriate).  Use this as the name 
 for that thing.

Yeah, that might be a good way to do it if I could have compiler
support, but I would need to be able to append some 'salt' to take care
of hidden assumptions not reflected in the raw interface. I actually
implemented something like this for datatypes, based on XDR... hmm.. 

http://haskell.org/pipermail/haskell-cafe/2001-September/002215.html



 Option (2) has the advantage that it's one step shorter, and it's 
 safer: with (1), you can generate one GUID but accidentally use it on 
 two distinct interfaces / implementations; with (2), this is 
 (essentially) impossible (although it may be possible to achieve a 
 collision intentionally; malice is a separate issue that should be 
 addressed in other ways).

eh. I don't think the random collision is a real concern, at worst,
hsguid spits out an error and you angrily email the authors for doing
the equivalant of winning the lottery 10 times in a row :) problem
resolved just by copying the offending pragma with a new id and use that
one. 

 For (2), we need to agree what to hash.  The options are basically the 
 source text of the module (or some sub-part of it for the interface 
 case), or the abstract syntax tree of the module.  The latter is 
 probably nicer, but requires some agreement between compiler writers if 
 it is to be valid across compilers.

what I did was implement a Hash class, which had a single function which
returned a hash, the hash was constant if the type was a terminal, and
 its type hashed with all its childrens types if it was a node.
recursive types were detected by drift and explicitly broken. 

although probably for this, the easiest thing would be to hash the
cannonicalized export list (with types). but not for hsguid. but perhaps
for some other tool which does a better job of generating hsguid
compatable pragmas.

 
 For background to this discussion, see our forthcoming ICFP paper,
 
 James J. Leifer, Gilles Peskine, Peter Sewell, Keith Wansbrough (2003). 
 Global Abstraction-Safe Marshalling with Hash Types
 
 which is available at
 
 http://www.cl.cam.ac.uk/~kw217/research/paper-abstracts.html#Leifer*03:G
 lobal

ooh. looks interesting. will read. I have really wanted something like
this for haskell for a while.

John

-- 
---
John Meacham - California Institute of Technology, Alum. - [EMAIL PROTECTED]
---
___
Haskell mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell


Re: *safe* coerce, for regular and existential types

2003-08-01 Thread Wang Meng
I admire the elegancy of your code which makes the changes to add new data
types minimum. There is one question I want to ask: Does this technique
extend to polymophic types?

Let's say we have the following type:

 data D a = C | D a

Is it possible to index the type D a? Or there is some fundmental
limitations which make it not achievable by Haskell type classes?


 -W-M-
  @ @
   |
  \_/

On Thu, 31 Jul 2003 [EMAIL PROTECTED] wrote:


 This message describes functions safeCast and sAFECoerce implemented
 in Haskell98 with common, pure extensions. The functions can be used
 to 'escape' from or to existential quantification and to make
 existentially-quantified datatypes far easier to deal with. Unlike
 Dynamic, the present approach is pure, avoids unsafeCoerce and
 unsafePerformIO, and permits arbitrary multiple user-defined typeheaps
 (finite maps from types to integers and values).

 An earlier message [1] introduced finite type maps for
 purely-functional conversion of monomorphic types to unique
 integers. The solution specifically did not rely on Dynamic and
 therefore is free from unsafePerformIO. This message shows that the
 type maps can be used for a safe cast, in particular, for laundering
 existential types. The code in this message does NOT use
 unsafePerformIO or unsafeCoerce. To implement safe casts, we define a
 function sAFECoerce -- which works just like its impure
 counterpart. However the former is pure and safe. sAFECoerce is a
 library function expressed in Haskell with common extension. The
 safety of sAFECoerce is guaranteed by the typechecker itself.

 This whole message is self-contained, and can be loaded as it is in
 GHCi, given the flags
   -fglasgow-exts -fallow-undecidable-instances -fallow-overlapping-instances

 This message was inspired by Amr Sabry's problem on existentials.  In
 fact, it answers an unstated question in Amr Sabry's original message.


 It has been observed on this list that existentially-quantified
 datatypes are not easy to deal with [2]. For example, suppose we have
 a value of a type

  data EV = forall a. (TypeRep a TI)= EV a

 (please disregard the second argument of TypeRep for a moment).

 The constructor EV wraps a value. Suppose we can guess that the
 wrapped value is actually a boolean. Even if our guess is correct, we
 *cannot* pass that value to any function of booleans:

 * *Main case (EV False) of (EV x) - not x
 *
 * interactive:1:
 * Inferred type is less polymorphic than expected
 * Quantified type variable `a' is unified with `Bool'
 * When checking an existential match that binds
 * x :: a
 * and whose type is EV - Bool
 * In a case alternative: (EV x) - not x

 A quantified type variable cannot be unified with any regular type --
 or with another quantified type variable. Values of existentially
 quantified types cannot be passed to monomorphic functions, or to
 constrained polymorphic functions (unless all their constrains have
 been mentioned in the declaration of the existential). That limitation
 guarantees safety -- on the other hand, it significantly limits the
 convenience of existential datatypes [2].

 To overcome the limitation, it _seemed_ that we had to sacrifice
 purity. If we are positive that a particular existentially quantified
 value has a specific type (e.g., Bool), we can use unsafeCoerce to
 cast the value into the type Bool [3]. This approach is one of the
 foundations of the Dynamic library. The other foundation is an ability
 to represent a type as a unique run-time value, provided by the
 methods of the class like TypeRep. Given an existentially quantified
 value and a value of the desired type, Dynamic compares type
 representations of the two values. If they are the same, we can
 confidently use unsafeCoerce to cast the former into the type of the
 latter.

 This works, yet leaves the feeling of dissatisfaction. For one thing,
 we had to resort to an impure feature. More importantly, we placed our
 trust in something like TypeRep and its members, that they give an
 accurate and unique representation of types. But what if they lie to
 us, due to a subtle bug in their implementation? What if they give the
 same representation for two different types? unsafeCoerce will do its
 dirty work nevertheless. Using the result would lead to grave
 consequences, however.

 This message describes sAFECoerce and the corresponding safe cast.
 Both functions convert the values of one type into the target type.
 One or both of these types may be existentially quantified.  When the
 source and the target types are the same, both functions act as the
 identity function. The safe cast checks that the type representations
 of the source and the target types are the same. If they are, it
 invokes sAFECoerce. Otherwise, we monadically fail. The function
 sAFECoerce does the conversion without any type checking. It always
 returns the value of the target type. If the source type was the same
 as the 

*safe* coerce: four methods compared

2003-08-01 Thread oleg

This is a Related Work section of the previous message. We compare
three main methods of achieving safe casts. It seems that the method
proposed in the earlier message is quite different -- especially in
terms of extensibility. In this message, we compare the extensibility
of four techniques. Stephanie Weirich ICFP'00 paper points out another
solution, which relies on mutable IORefs. Since that technique can
only be used with IO monad, we do not consider it here.

Some of the methods below require type classes and algebraic datatype
declarations. Some require only an algebraic datatype, or only a
typeclass. In either case, we run into an extensibility problem: to
add support for a new datatype, we must either add an instance
declaration, or a new alternative to the datatype declaration. These
are non-trivial, non-modular extensions. For example, when we add a
new alternative to a datatype declaration, we must physically update
the corresponding file. We must then re-compile all dependent modules.

Surprisingly, the solution in the earlier message is free from these
drawbacks. We can extend the type heap in a modular fashion. We do not
need to alter type or data declarations. It seems our type heaps are
sort of reified lists of instances. There appear to be a duality
between typeclasses and our type heaps. Only our type heaps are
first-class.


The idea behind all type-safe casts is simple: to cast a value of a type
'a' into a target type 'b', we inject the value into some universe and
then project it to the target type 'b'.

To illustrate the differences in implementations of that idea, we will
be using James Cheney and Ralf Hinze's example: a generic comparison
function. To avoid unnecessary complications, we limit ourselves to
built-in and scalar types. Extensions to products, exponential,
recursive and polymorphic types are possible, but too messy. We also
will not consider existential types, so we avoid introducing type
classes if they are not needed in the static case.

This whole message is self-contained, and can be loaded as it is in
GHCi, given the flags
  -fglasgow-exts -fallow-undecidable-instances -fallow-overlapping-instances


Approach 1: Tcl approach

The universal type is a string. The values to cast must belong to the
class Show and the class Read. The injection and projection functions
are trivial:

 sh_inj x = show x
 sh_prj x = read x

Generic equality and the cast functions are trivial as well:

 sh_gequal x y = sh_inj x == sh_inj y

 sh_cast x = sh_prj $ sh_inj x

Here's the test:

 sh_test1 = [sh_gequal 1 2, sh_gequal True True, sh_gequal 'a' 'b']

To add support for a new datatype, we have to place that datatype in
the class Show and the class Read. That is, we have to add the
corresponding instance declarations _and_ we have to implement methods
'show' and 'read'. Functions sh_gequal and sh_cast do not have to be
modified. The Tcl approach is also the most generous with respect to
type equivalence: for example, Int and Integer are considered
equivalent, and sh_cast may cast between them.

Incidentally, when GHC can derive Binary, this approach becomes far
more appealing.


Approach 2: The universe is the tagged union

 data TU = TChar Char | TBool Bool | TInt Int

 class TURepr t where
   tu_inj:: t - TU
   tu_prj:: TU - t
 
 instance TURepr Char where
   tu_inj = TChar
   tu_prj (TChar x) = x
  
 instance TURepr Bool where
   tu_inj = TBool
   tu_prj (TBool x) = x
 
 instance TURepr Int where
   tu_inj = TInt
   tu_prj (TInt x) = x
 
 tu_gequal x y = cmp (tu_inj x) (tu_inj y)
   where
 cmp (TChar x) (TChar y) = x == y   
 cmp (TBool x) (TBool y) = x == y   
 cmp (TInt x)  (TInt y)  = x == y   

 tu_cast x = tu_prj $ tu_inj x

 tu_test1 = [tu_gequal (1::Int) (2::Int), tu_gequal True True, 
 tu_gequal 'a' 'b']


To add support for a new datatype, we have to add a new alternative to
the declaration of the datatype TU and we have to add a new instance
for the class TURepr (with the implementation of the tu_inj and
tu_proj methods). We also have to add another clause to the tu_gequal
function. Clearly this is the least extensible approach.


Approach 3: by Cheney and Ralf Hinze's
The universe is a set of inject/project pairs

 data IPP a =  IPPInt  (a-Int)  (Int-a) 
 | IPPChar (a-Char) (Char-a)
 | IPPBool (a-Bool) (Bool-a)
   
 ipp_gequal (IPPInt  prj inj) x y = prj x == prj y
 ipp_gequal (IPPChar prj inj) x y = prj x == prj y
 ipp_gequal (IPPBool prj inj) x y = prj x == prj y

 ipp_cast (IPPInt xprj xinj) x (IPPInt yprj yinj) = yinj $ xprj x
 -- more should follow...

 ipp_test1 = [ipp_gequal (IPPInt  id id) (1::Int) (2::Int),
  ipp_gequal (IPPBool id id) True True,
  ipp_gequal (IPPChar id id) 'a' 'b']

To add a new primitive datatype, we should modify the declaration of
the datatype IPP and add a new alternative. We also need to add
clauses to ipp_gequal and ipp_cast.

Incidentally, (IPPInt 

FTP, XMLRPC libraries?

2003-08-01 Thread Bryn Keller
Hi folks,

I'm looking for FTP (client) and XMLRPC (client) libraries for Haskell. 
Does anyone know of any, or do I need to roll my own?

Thanks,
Bryn
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: a breaking monad (to haskell cafe)

2003-08-01 Thread Iavor Diatchki
hi,

Derek Elkins wrote:
Anyways, most of my uses of the Cont monad have been for my own personal
entertainment, and usually I break the abstraction (using
Control.Monad.Cont) to do the things I want.  I don't know if I've ever
written something that's used callCC that I kept.
except for entertainment purposes i feel pretty much the same way :-)
i think that in probably 95% of the cases that arise there is a simpler 
monad that does the job (i.e. exceptions, backtracking, etc).  of course 
it could be that we are simply not used to program using the callcc.

bye
iavor


--
==
| Iavor S. Diatchki, Ph.D. student   |
| Department of Computer Science and Engineering |
| School of OGI at OHSU  |
| http://www.cse.ogi.edu/~diatchki   |
==
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe