From ger at informatik.uni-bremen.de Tue Jun 1 12:06:36 2004 From: ger at informatik.uni-bremen.de (George Russell) Date: Tue Jun 1 12:05:06 2004 Subject: [Haskell] Initialisation without unsafePerformIO Message-ID: <40BCA98C.4090205@informatik.uni-bremen.de> What ideas do people have for getting rid of unsafePerformIO? The most common use of unsafePerformIO, for me at least, is initialisation. There *surely* must be a better way of doing this, but I haven't really seen much discussion of the topic. Here is my back-of-the-envelope suggestion for a new interface, can anyone do better? > type Dict > -- a collection of initialised data. > > register :: Typeable a => Dict -> a -> IO () > -- register a value of type (a) in the dictionary. Only one value of each > -- type is allowed in the dictionary; registering the same type twice will > -- cause an exception. > > defaultDict :: IO Dict > -- Each Haskell "main" program will have one of these. > > lookup :: Typeable a => Dict -> IO a > -- Get the value of (a) registered in the Dict, or raise an exception if it > -- isn't. Thus, libraries which rely on internal initialised state will also have to provide a function which initialises that state. I don't think this is very painful. IME it's often required anyway, if you want to provide the library with additional parameters. Also the library could catch the exception from (lookup) and give a helpful error message of the form "You forgot to run Gadgets.initialise". We can also provide additional dictionaries. > thisThreadDict :: IO Dict > > newEmptyDict :: IO Dict > > runWithDifferentDefaultDict :: Dict -> IO a -> IO a This would allow the programmer much more control over initialisation. For example, programs distributed over a large number of processors are no longer obliged to use a single global dictionary, which is effectively what is required now. (How else can you make sure that two processors do not try to evaluate the same unsafePerformIO value at once?) And runWithDifferentDefaultDict allows you to change the value returned by defaultDict during an action, meaning that programs can for example initialise the same library multiple times, which would be useful during debugging. Well it's a start I think. Can anyone do better? From john at repetae.net Tue Jun 1 12:35:15 2004 From: john at repetae.net (John Meacham) Date: Tue Jun 1 12:36:11 2004 Subject: [Haskell] Initialisation without unsafePerformIO In-Reply-To: <40BCA98C.4090205@informatik.uni-bremen.de> References: <40BCA98C.4090205@informatik.uni-bremen.de> Message-ID: <20040601163515.GA8357@momenergy.repetae.net> On Tue, Jun 01, 2004 at 06:06:36PM +0200, George Russell wrote: > What ideas do people have for getting rid of unsafePerformIO? > > The most common use of unsafePerformIO, for me at least, is initialisation. > There *surely* must be a better way of doing this, but I haven't really > seen much discussion of the topic. Here is my back-of-the-envelope > suggestion for a new interface, can anyone do better? I am a fan of allowing top level declarations of the form: foo <- newIORef "foo" which would behave as an initializer, with the semantics being that it be evaluated at most once before foos first use. (so it could be implemented via unsafePerformIO or as an init section run before main). The {-# NOINLINE foo #-} foo = unsafePeformIO $ newIORef "foo" idiom is so common and useful, it should have some compiler support. It is 'clean' too, since all we are doing is extending the "world" with new state, but in a much cleaner/safer way then writing to a file or environment variable or other methods of storing state in the world. John -- John Meacham - ?repetae.net?john? From ijones at syntaxpolice.org Tue Jun 1 14:49:44 2004 From: ijones at syntaxpolice.org (Isaac Jones) Date: Tue Jun 1 14:45:58 2004 Subject: [Haskell] new Library Infrastructure spec. Message-ID: <87k6yri053.fsf@syntaxpolice.org> (followups to libraries@haskell.org) Hail Haskellers! A commonly-identified obstacle to the spread of Haskell libraries is that there is no standard way a) for authors to package a library or other tool for distribution to others b) for customers to install such a package Platforms vary. Haskell compilers vary. Packages have dependencies. Etc. Isaac Jones has coordinated an effort to address this problem. We've had a lot of discussion between him and (at least some of) the folk involved in the GHC, Hugs, and nhc implementations. This discussion has led to a new concrete proposed specification[1]. Here it is: http://www.haskell.org/libraryInfrastructure/proposal See also the project home page: http://www.haskell.org/libraryInfrastructure/ We would welcome your feedback, either as a potential library or tool author, or as a potential consumer, or both. The specification isn't complete in every detail, but it seems better to post it before investing in details that may be rendered void by subsequent discussion. We hope this will be an important spec, and will be with us for a long time. So now's the time to look at it. Send feedback to libraries@haskell.org. (You can subscribe to this list at: http://www.haskell.org/mailman/listinfo/libraries .) Sincerely, Isaac Jones, Simon Marlow, Ross Paterson, Malcolm Wallace, Simon Peyton Jones [1] This specification differs from the previous proposal both in technical details, and in that it is the combined efforts of the undersigned. Those familiar with the previous proposal will not find large high-level differences, but some details have been made more concrete and some details have changed. From disita at oboe.dsi.unifi.it Tue Jun 1 14:29:58 2004 From: disita at oboe.dsi.unifi.it (MUSICNETWORK) Date: Tue Jun 1 15:20:24 2004 Subject: [Haskell] CFP: 4th Open Workshop MUSICNETWORK, Barcelona, September 2004 Message-ID: <200406011829.i51ITww5009304@oboe.dsi.unifi.it> This is a special communication dedicated to the next Open Workshop of the MUSICNETWORK it is also an activity of the AHG of MPEG on Symbolic Music Representation Sorry for multiple reception of this message. THE DEADLINE HAS BEEN EXTENDED TO THE 15 OF JUNE Paolo Nesi MusicNetwork -L-L-L-L-L-L-L-L-L-L-L-L-L-L--L-L-L-L-L-L-L-L- Call for Proposal, Papers, Expositions 4th Open Workshop of MUSICNETWORK: Integration of Music in Multimedia Applications http://www.interactivemusicnetwork.org/events/Fourth_OpenWorkshop_2004/MUSICNETWORK-4th-Open-Workshop-plan-v1-2.html http://www.interactivemusicnetwork.org/ LOCATED AT: Universitat Pompeu Fabra, Barcelona, Spain, 15th-16th September 2004 http://dmag.upf.es/wedelmusic2004/Documents/Location.html Co-located with WEDELMUSIC 2004 Conference: http://www.upf.edu/wedelmusic2004/ You are invited to participate at the Workshop and to contribute to the sessions. With the support of the European Commission, the MUSICNETWORK project has been created to explore the applications and integration of interactive multimedia technologies for Music, enabling inter- and trans-disciplinary collaborations and networking, bridging many important sectors, including cultural, commercial, industrial, research and academic. End users are discovering the multimedia experience, and thus, traditional music models are going to be overcome and replaced by their integration with multimedia, audiovisual and cross media. Thus the aim is to put together industry actors and innovative technology providers to help the music industry to overcome the present problems with the innovation. The theme of the 4th Open Workshop is the Integration of Music in Multimedia applications. Currently many new music-related applications are strongly impacting and attracting the market. Most of them will become more and more widespread in a short time due to users’ demand. Among most addressed sectors the one presenting more notable form of integration between music and multimedia there are: -- music education (notation tools integrating multimedia, educational paradigms, tools, distance learning, mobile learning, etc.); -- music management in libraries (modeling, navigation, metadata, content description, etc., MPEG-7), -- entertainment (animation, synchronisation, etc., SMIL ); -- music and multimedia music distribution and protection (watermarking, fingerprint, MPEG-21); -- valorization of cultural heritage (modeling, restring, etc.); -- electronic consumer applications: piano keyboards with symbolic music representation and audiovisual capabilities, electronic lecterns, i-TV; -- mobile applications for education and entertainment (cellular phones, PDA, tablet PC, etc.). In the current Internet and Multimedia age other applications are strongly attracting market attention and most of them will become soon widespread in short time. The integration of symbolic music representation in MPEG could completely satisfy users’ requirements for properly handling such issue into tools, allowing to integrate into a single model the powerful one of MPEG for multimedia, representation, coding and playback. The integration of symbolic music representation with MPEG or other multimedia standards will open the way for a large number of new applications and markets related to the above applications. This initiative may increase the current market for symbolic music representation, which is mainly dedicated to sheet music production. It may also open the path to creating very interesting new applications, and to increase the power and flexibility of those applications that already use both multimedia and symbolic music representation. MPEG has relevant standards in this area such as MPEG-4 for the audio visual objects, MPEG-7 for the description of audio visual content for archives, and MPEG-21 for the Digital Rights Management and distribution of digital audiovisual. At present, there is a lack of an integrated Music Notation/Representation standard with multimedia. The aim of this workshop is to make a further step towards a proper standardizing of a Music Notation/Representation Model. The MUSICNETWORK has worked very hard to create the conditions for a Call for Proposals/Technologies within MPEG with the aim of exploiting the MPEG framework for integrating Music Notation/Representation in several innovative applications. As a results an MPEG Ad Hoc Group on Symbolic Music Representation has been created, a large set of requirements and innovative applications have been identified and a call for technology can be launched. All this material can be recovered from: - http://www.interactivemusicnetwork.org/mpeg-ahg/ - http://www.interactivemusicnetwork.org/mpeg-ahg/W6457%20%28Draft%20CfP%20Symbolic%20Music%20Representation%29.doc To this end, the next Open Workshop of the MUSICNETWORK will be mainly focused on the integration of MUSIC and MULTIMEDIA in an effective CROSS MEDIA. Several different formats and media may share the same information and grant navigation, synchronization and stable relationships establishment. The 4th Open Workshop will be organized around the following sections. For each section we are open to receive proposals and contributions: ***Applications and Technical papers*** chairs: Jerome Barthelemy (IRCAM, Jerome.Barthelemy@ircam.fr), David Crombie (FNB, dcrombie@fnb.nl), David Fuschi (ILABS, d.fuschi@giuntilabs.it), Giuseppe Nicotra (ARCA, nicotra@dodiesis.com). The topic of interests for the Application session is wide ranging. For this section, we are going to accept papers and proposals from Experts and from Industries coming from different areas of music for finals user applications and/or innovative technologies. Proposals may be Industrial presentations of music applications or experts papers. The session will be focused on current applications, case-studies, applications scenarios, latest development, as well as future directions, innovative technologies. It includes, but not limited to the following areas: o Education, cooperative work, distance learning, mobile learning, etc. o Entertainment, consumer electronics, music and games, animation, synchronization, etc. o cultural heritage, exploitation of cultural assets, archives, museums, restoration, etc. o music distribution and protection, fingerprint, monitoring, business models, mobiles, etc. o music exploitation, economical impacts of content fruition on new media, etc. o accessibility and culture, technology for supporting accessibility, etc. o music modeling and representation, etc. These interdisciplinary domains share one common point the applications of science and technologies in Music or the applications of Music in interactive multimedia domains ***MPEG SMR, Symbolic Music Representation, Call for Technology*** Chairs: Paolo Nesi (DSI, nesi@dsi.unifi.it), Giorgio Zoia (EPFL, Giorgio.Zoia@epfl.ch). The idea of this section is to provide support to industries and groups that intent to respond at the Call for Technology of MPEG regarding the SMR http://www.interactivemusicnetwork.org/mpeg-ahg/. The work activities in this section will be mainly devoted in making clear what MPEG forum expects in response to the CALL and what the MPEG could provide in terms of benefits and return of investment to these companies. The registration to this event is strongly suggested, and should be accompanied by a simple document including a list of possible questions or point that you are interested to see discussed during this section. The major points will be: o Presentation of the MPEG SMR Call for Technology, aims and goals o Presentations of the proponents o Open discussion to support proposers You are invited to participate at the Workshop and to contribute to the above sessions. Free registration, please do via the WWW site of the MUSICNETWORK. The registration is not mandatory but is strongly suggested, we need to set up suitable logistic support for the right number of participants. http://www.interactivemusicnetwork.org/ Submission of your proposal by 15th of June 2004 o To be sent at the corresponding chairs (see email addresses above), in MS-WORD or PDF formats o To be also sent at musicnetwork@dsi.unifi.it o To be submitted according to the above description with the number of pages suggested below. o To be submitted with the dates reported below Please note that all the submissions will be published on the WWW site of the MUSICNETWORK. If you don't agree on this kind of publication please inform the MUSICNETWORK in the accompanying letter to the submission. Different types of contributions are welcome: - Tutorials/Surveys (4 to 8 page of proposal) - Application and Technical Papers (2 to 10 pages) - Exposition and Demonstrations (1 page summary) - MPEG SMR Symbolic Music Representation: (a list of topics to be discussed) Important deadlines - Deadline for submission: 15 June 2004 - Paper selection results: 25 June 2004 - Full paper submission: 28 July 2004 - Workshop: 15 September 2004 As usual, the MUSICNETWORK will economically support a number of speakers according to the quality of their proposal, to the relevance of the topic proposed, etc. The selection will be operated on the basis of the proposal. In addition, the MUSICNETWORK is going to invite a given number of experts, asking them to attend the meeting to give their contribution in the above mentioned topics. The latter are a sort of keynote speakers on the Conference topics and are not in competition with the former. From Ben.Yu at combined.com Tue Jun 1 15:06:31 2004 From: Ben.Yu at combined.com (Ben.Yu@combined.com) Date: Tue Jun 1 15:20:25 2004 Subject: [Haskell] how to write a list builder? fixpoint? Message-ID: Hi, just curious. When building a list, normally I do [a,b,c,d]. Is it possible to write a function to build a list [a]? so that I can write [a,b,c,d] as "getBuilt $ build a b c d"? looks like build will have to be of type ListBuilder, where ListBuilder a = a -> ListBuilder a. Is it a fix point? Ben. This message is intended only for the addressee and may contain information that is confidential or privileged. Unauthorized use is strictly prohibited and may be unlawful. If you are not the intended recipient, or the person responsible for delivering to the intended recipient, you should not read, copy, disclose or otherwise use this message, except for the purpose of delivery to the addressee. If you have received this email in error, please delete and advise us immediately. From oleg at pobox.com Tue Jun 1 21:18:03 2004 From: oleg at pobox.com (oleg@pobox.com) Date: Tue Jun 1 21:19:29 2004 Subject: [Haskell] Re: how to write a list builder? fixpoint? Message-ID: <20040602011803.50620ABC3@Adric.metnet.navy.mil> > Is it possible to write a function to build a list [a]? > so that I can write [a,b,c,d] as "getBuilt $ build a b c d"? Yes, in the format very close to desired. > {-# OPTIONS -fglasgow-exts #-} > {-# OPTIONS -fallow-undecidable-instances #-} > > module Foo where > > class BuildList a r | r-> a where > build' :: [a] -> a -> r > > instance BuildList a [a] where > build' l x = reverse$ x:l > > instance BuildList a r => BuildList a (a->r) where > build' l x y = build'(x:l) y That's it. It works both on GHC and Hugs. *Foo> build' [] True :: [Bool] [True] *Foo> build' [] True False :: [Bool] [True,False] *Foo> build' [] True False False :: [Bool] [True,False,False] *Foo> build' [] 'a' 'b' 'c' 'd' 'e' :: [Char] "abcde" *Foo> build' [] (1::Int) :: [Int] [1] *Foo> build' [] (1::Int) (2::Int) :: [Int] [1,2] *Foo> build' [] (1::Int) (2::Int) (3::Int) :: [Int] [1,2,3] Note that the type annotation [Bool] etc. at the end is required: it is the delimiter of the list. Who would have thought that the type annotation can play the role of Nil... From ccshan at post.harvard.edu Wed Jun 2 03:35:54 2004 From: ccshan at post.harvard.edu (Chung-chieh Shan) Date: Wed Jun 2 03:34:22 2004 Subject: [Haskell] Initialisation without unsafePerformIO In-Reply-To: <40BCA98C.4090205@informatik.uni-bremen.de> References: <40BCA98C.4090205@informatik.uni-bremen.de> Message-ID: <20040602073554.GA21342@ligate> On 2004-06-01T18:06:36+0200, George Russell wrote: > The most common use of unsafePerformIO, for me at least, is initialisation. > There *surely* must be a better way of doing this, but I haven't really > seen much discussion of the topic. Here is my back-of-the-envelope > suggestion for a new interface, can anyone do better? Oleg and I summarize the existing solutions to the configuration problem in Section 2 of our draft paper at http://www.eecs.harvard.edu/~ccshan/prepose/ We then propose a new solution. Implicit configuration -- or, type classes reflect the value of types The _configuration problem_ is to propagate run-time preferences throughout a program, allowing multiple concurrent configuration sets to coexist safely under staticly guaranteed separation. This problem is common in all software systems, but particularly acute in Haskell, where currently the most popular solution relies on unsafe operations and compiler pragmas. We solve the configuration problem in Haskell using only widely implemented and stable language features like the type class system. In our approach, a term expression can refer to run-time configuration parameters just as it refers to compile-time constants in global scope. Besides supporting such intuitive term notation, our solution also helps improve the program's performance by transparently dispatching to specialized code at run-time. We can propagate any type of configuration data -- numbers, strings, IO actions, polymorphic functions, closures, and abstract data types. The enabling technique behind our solution is to propagate values via types (literally), with the help of polymorphic recursion and higher-ranked polymorphism. The technique essentially emulates local type-class instance declarations. Configuration parameters are propagated throughout the code implicitly as part of type inference rather than explicitly by the programmer. We are thinking of submitting this paper to the Haskell workshop. Any comments would be appreciated, especially before Friday. (: Ken -- Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig 2004-06-05: World Environment Day http://www.unep.org/wed/2004/ 1 000 000 Europeans demand the exit of nuclear power www.atomstopp.at/1million/ -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: Digital signature Url : http://www.haskell.org//pipermail/haskell/attachments/20040602/5b60b807/attachment.bin From john at repetae.net Wed Jun 2 12:15:00 2004 From: john at repetae.net (John Meacham) Date: Wed Jun 2 12:16:08 2004 Subject: [Haskell] Idea for the Haskell Store Message-ID: <20040602161500.GC30722@momenergy.repetae.net> There are a lot of very good books and papers out there on haskell or related topics which are no longer in print or not convieniently available in paper form to people without university access. I was thinking it would be very very cool if we could sign up with one of the POD (Print on demand) services to offer useful books and collections of papers printed on demand for haskell enthusiasts. A print on demand publisher works just like amazon or any other online bookseller, but actually prints out the books as needed so can deal just as effectivly with small orders as big ones, modern technology has made the cost comparable to traditional mass-produced books and an order of magnitude better quality and cost over getting the stuff printed and bound at kinkos or similar. some things which I would LOVE to see offered would be stuff like http://www.cs.chalmers.se/~boquist/phd/index.html peyton jones's thesis on GHC optimization http://www.cs.chalmers.se/Cs/Research/Logic/book/ http://research.microsoft.com/Users/simonpj/Papers/pj-lester-book/ various collections of papers by author phillip wadler, simon peyton jones, simon marlow, etc.. or based on topics like 'the monad papers' or 'generic haskell anthology' or 'a tale of ten pretty printers' any other ideas? There will probably be some copyright issues to work out, but anything would be great. It could be done non-profit or having the profit flow back to the authors or into the maintenence of the haskell site or other worthy haskell projects (or decided on a book-by-book basis I imagine) John -- John Meacham - ?repetae.net?john? From Ben.Yu at combined.com Wed Jun 2 14:38:05 2004 From: Ben.Yu at combined.com (Ben.Yu@combined.com) Date: Wed Jun 2 14:40:25 2004 Subject: [Haskell] Re: how to write a list builder? fixpoint? In-Reply-To: <20040602011803.50620ABC3@Adric.metnet.navy.mil> Message-ID: Thanks Oleg. This is really a nice example. Never even dream about such wonderful use of type classes! It seems to me that the "fallow-undecidable-instances" for this example is not necessary though. It compiles with just glasgow-exts Another question about overloading with type classes. It seems that these overloaded functions cannot be passed as higher-order function. Is that true?A higher order function can never be overloaded? In an example, how can I pass "build" as a function to another function that does some algorithm? (as the traditional Builder pattern in OO term) myalg builder = ...... build a b c ...... Ben. oleg@pobox.com Sent by: To: haskell@haskell.org haskell-bounces@h cc: askell.org Subject: [Haskell] Re: how to write a list builder? fixpoint? 06/01/2004 08:18 PM Please respond to oleg > Is it possible to write a function to build a list [a]? > so that I can write [a,b,c,d] as "getBuilt $ build a b c d"? Yes, in the format very close to desired. > {-# OPTIONS -fglasgow-exts #-} > {-# OPTIONS -fallow-undecidable-instances #-} > > module Foo where > > class BuildList a r | r-> a where > build' :: [a] -> a -> r > > instance BuildList a [a] where > build' l x = reverse$ x:l > > instance BuildList a r => BuildList a (a->r) where > build' l x y = build'(x:l) y That's it. It works both on GHC and Hugs. *Foo> build' [] True :: [Bool] [True] *Foo> build' [] True False :: [Bool] [True,False] *Foo> build' [] True False False :: [Bool] [True,False,False] *Foo> build' [] 'a' 'b' 'c' 'd' 'e' :: [Char] "abcde" *Foo> build' [] (1::Int) :: [Int] [1] *Foo> build' [] (1::Int) (2::Int) :: [Int] [1,2] *Foo> build' [] (1::Int) (2::Int) (3::Int) :: [Int] [1,2,3] Note that the type annotation [Bool] etc. at the end is required: it is the delimiter of the list. Who would have thought that the type annotation can play the role of Nil... _______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell This message is intended only for the addressee and may contain information that is confidential or privileged. Unauthorized use is strictly prohibited and may be unlawful. If you are not the intended recipient, or the person responsible for delivering to the intended recipient, you should not read, copy, disclose or otherwise use this message, except for the purpose of delivery to the addressee. If you have received this email in error, please delete and advise us immediately. From simonpj at microsoft.com Wed Jun 2 17:39:27 2004 From: simonpj at microsoft.com (Simon Peyton-Jones) Date: Wed Jun 2 17:36:45 2004 Subject: [Haskell] Idea for the Haskell Store Message-ID: <4B93206CA3C55D4F96A61C9B1DC80DE301393E2D@EUR-MSG-03.europe.corp.microsoft.com> Good idea! At least, good idea if anyone wants to organise it. I'm optimistic that copyright issues could be worked out, but it needs an animating spirit to decide what should be available, line up POD services, decide pricing etc. Any volunteers? Simon | -----Original Message----- | From: haskell-bounces@haskell.org [mailto:haskell-bounces@haskell.org] On Behalf Of John Meacham | Sent: 02 June 2004 17:15 | To: haskell@haskell.org | Subject: [Haskell] Idea for the Haskell Store | | There are a lot of very good books and papers out there on haskell or | related topics which are no longer in print or not convieniently available in | paper form to people without university access. | | I was thinking it would be very very cool if we could sign up with one | of the POD (Print on demand) services to offer useful books and | collections of papers printed on demand for haskell enthusiasts. A | print on demand publisher works just like amazon or any other online | bookseller, but actually prints out the books as needed so can deal | just as effectivly with small orders as big ones, modern technology has | made the cost comparable to traditional mass-produced books and an order | of magnitude better quality and cost over getting the stuff printed and | bound at kinkos or similar. | | some things which I would LOVE to see offered would be stuff like | | http://www.cs.chalmers.se/~boquist/phd/index.html | peyton jones's thesis on GHC optimization | http://www.cs.chalmers.se/Cs/Research/Logic/book/ | http://research.microsoft.com/Users/simonpj/Papers/pj-lester-book/ | various collections of papers by author phillip wadler, simon peyton | jones, simon marlow, etc.. or based on topics like 'the monad papers' | or 'generic haskell anthology' or 'a tale of ten pretty printers' | | any other ideas? | | There will probably be some copyright issues to work out, but anything | would be great. It could be done non-profit or having the profit flow | back to the authors or into the maintenence of the haskell site or other | worthy haskell projects (or decided on a book-by-book basis I imagine) | | John | | -- | John Meacham - ?repetae.net?john? | _______________________________________________ | Haskell mailing list | Haskell@haskell.org | http://www.haskell.org/mailman/listinfo/haskell From oleg at pobox.com Wed Jun 2 19:38:26 2004 From: oleg at pobox.com (oleg@pobox.com) Date: Wed Jun 2 19:39:51 2004 Subject: [Haskell] Re: how to write a list builder? fixpoint? In-Reply-To: Message-ID: <20040602233826.3EAE5ABC3@Adric.metnet.navy.mil> > Another question about overloading with type classes. It seems that these > overloaded functions cannot be passed as higher-order function. Is that > true? A higher order function can never be overloaded? > > In an example, how can I pass "build" as a function to another function > that does some algorithm? (as the traditional Builder pattern in OO term) A function that takes a polymorphic function and uses it polymorphically has a higher-ranked type. Higher-ranked types cannot be inferred (in general) and must be declared explicitly. In great detail, this question is discussed in Ken Shan's survey http://www.eecs.harvard.edu/~ccshan/cs252/usage.pdf As to your question: we can indeed pass 'build' to other functions and use that argument as a function with the variable number of arguments. Please see the function use_build in the code below. It works both in GHC and Hugs. P.S. Sorry I cannot reply directly to you: your ISP combined.com blocks my mail. {-# OPTIONS -fglasgow-exts #-} module Foo where class BuildList a r | r-> a where build' :: [a] -> a -> r instance BuildList a [a] where build' l x = reverse$ x:l instance BuildList a r => BuildList a (a->r) where build' l x y = build'(x:l) y --build :: forall r a. (BuildList a r) => a -> r build x = build' [] x -- build 'a' :: String -- build 'a' 'b' :: String -- build (1::Int) :: [Int] -- build (1::Int) (2::Int) :: [Int] -- build (1::Int) (2::Int) (3::Int) :: [Int] -- polyvariadic functions -- functions with the variable number of -- arguments -- are possible in Haskell after all... -- Higher-ranked type: the signature is required use_build::(forall r a. (BuildList a r) => a -> r) -> x -> x -> x -> x -> [[x]] use_build bb a b c d = let t1 = bb a t2 = bb a b t3 = bb a b c t4 = bb a b c d t5 = bb a b c d a in [t1,t2,t3,t4,t5] test = use_build build 'a' 'b' 'c' 'd' -- *Foo> test -- ["a","ab","abc","abcd","abcda"] From oleg at pobox.com Wed Jun 2 20:07:24 2004 From: oleg at pobox.com (oleg@pobox.com) Date: Wed Jun 2 20:09:06 2004 Subject: [Haskell] Re: how to write a list builder? fixpoint? In-Reply-To: Message-ID: <20040603000724.952D9ABC3@Adric.metnet.navy.mil> I'm sorry I couldn't resist another example -- which requires fewer signatures. It also illustrates storing build in data structures. In the example below (which works with the code posted earlier) build is used to build itself. It really has quite a few faces... data W = W (forall r a. (BuildList a r) => (a->r)) test2 = let t1 = build (W build) t2 = build (W build) (W build) t3 = t1 ++ t2 f (W b) = b (1::Int) ++ b (1::Int) (2::Int) ++ b (1::Int) (2::Int) (3::Int) in map f t3 We should probably move to Cafe for further discussions, if any... From john at repetae.net Thu Jun 3 06:33:50 2004 From: john at repetae.net (John Meacham) Date: Thu Jun 3 06:35:05 2004 Subject: [Haskell] Idea for the Haskell Store In-Reply-To: <4B93206CA3C55D4F96A61C9B1DC80DE301393E2D@EUR-MSG-03.europe.corp.microsoft.com> References: <4B93206CA3C55D4F96A61C9B1DC80DE301393E2D@EUR-MSG-03.europe.corp.microsoft.com> Message-ID: <20040603103349.GF30722@momenergy.repetae.net> On Wed, Jun 02, 2004 at 10:39:27PM +0100, Simon Peyton-Jones wrote: > Good idea! At least, good idea if anyone wants to organise it. I'm > optimistic that copyright issues could be worked out, but it needs an > animating spirit to decide what should be available, line up POD > services, decide pricing etc. Any volunteers? It apperas that cafepress.com, the company we currently use to sell haskell t-shirts and mugs ( http://haskell.org/merchandise.html) also does POD printing! the costs seem reasonable, we would probably be looking at roughly $7-12 raw cost per book depending on pages and quality desired. All that is needed is a pdf in one of several formats (letter, not sure if they do A4) and a cover format and then you can just order it :) perhaps whoever already maintains the haskell cafepress store can see about setting up some books, perhaps the pj-lester book would be a good start, since its TeX is nicely available for rerunning to create a pdf in the appropriate size. If the current maintainer isn't interested, I can go ahead and set up a shop for the books myself, or be given access to the main cafepress account. (whatever is easier). I think, once we have the basics down, i.e. we can order the pj-lester book (or some other suitable starting book) and get a copy, we can start the more involved work of putting together paper anthologies and hunting down copyright holders of obsure out of print works and begging them to let us make the works available. :) John -- John Meacham - ?repetae.net?john? From Ben.Yu at combined.com Thu Jun 3 13:12:28 2004 From: Ben.Yu at combined.com (Ben.Yu@combined.com) Date: Thu Jun 3 13:14:49 2004 Subject: [Haskell] Re: how to write a list builder? fixpoint? In-Reply-To: <20040603000724.952D9ABC3@Adric.metnet.navy.mil> Message-ID: I'm sorry. I'm new to haskell, new to this group, don't even know what this "cafe" refers to. Is there a special place for discussing further details? As for the build, I was really surprised by your examples. with brain adapted to Java and C++ so deeply, seems like I just cannot think well in Haskell. Each of your example made me feel :" Wow, that's cool! How come I never thought of it?". But I just cannot get everything organized in my mind. I'm ordering the "Haskell school of expression" book, hopefully it can refactor my Object Orientized brain more Haskellsih. But anyway, let's move on. Inspired by you, I wrote (most copy-paste from yours) my generic Builder which can build not only list. class Builder c a r | r -> a where build :: (c->c) -> (a -> c -> c) -> c -> a -> r instance Builder [a] a [a] where build pub acc l a = pub $ acc a l instance Builder c a r => Builder c a (a->r) where build pub acc l a x = build pub acc (acc a l) x With this generic builder, list builder can be written as: buildl :: (Builder [a] a r) => a -> r buildl = build reverse (:) [] Similarly, a builder can be built for binary functions like addToFM. class Builder2 c a b r | r -> a, r->b where build2 :: (c->c) (a->b->c->c) -> c -> a -> r instance Builder2 c a b r => Builder c a b (a->r) where build2 pub acc l a b x y = build2 pub acc (acc a b l) x y instance Builder2 (FiniteMap k v) k v (FiniteMap k v) where build2 pub acc m k v = pub $ acc k v m buildm :: (Ord k, Builder2 (FiniteMap k v) k v r) => k -> v -> r buildm = build2 id _put emptyFM where _put k v m = addToFM m k v test3 = addToFM(buildm "a" "b" "c" "d") "x" "y" I'm not bothered too much for explicitly writing the signature. It is good practice to write explicit signature anyway. However, I don't quite like having to say buildl (1::Int). If I can say [1,2,3], which types to Num a => [a], why can't I say buildl 1 2 3 which also types to Num a => [a]? oleg@pobox.com Sent by: To: haskell@haskell.org haskell-bounces@h cc: askell.org Subject: [Haskell] Re: how to write a list builder? fixpoint? 06/02/2004 07:07 PM Please respond to oleg I'm sorry I couldn't resist another example -- which requires fewer signatures. It also illustrates storing build in data structures. In the example below (which works with the code posted earlier) build is used to build itself. It really has quite a few faces... data W = W (forall r a. (BuildList a r) => (a->r)) test2 = let t1 = build (W build) t2 = build (W build) (W build) t3 = t1 ++ t2 f (W b) = b (1::Int) ++ b (1::Int) (2::Int) ++ b (1::Int) (2::Int) (3::Int) in map f t3 We should probably move to Cafe for further discussions, if any... _______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell This message is intended only for the addressee and may contain information that is confidential or privileged. Unauthorized use is strictly prohibited and may be unlawful. If you are not the intended recipient, or the person responsible for delivering to the intended recipient, you should not read, copy, disclose or otherwise use this message, except for the purpose of delivery to the addressee. If you have received this email in error, please delete and advise us immediately. From ger at informatik.uni-bremen.de Thu Jun 3 14:11:39 2004 From: ger at informatik.uni-bremen.de (George Russell) Date: Thu Jun 3 14:10:03 2004 Subject: [Haskell] Initialisation without unsafePerformIO Message-ID: <40BF69DB.20503@informatik.uni-bremen.de> Chung-chieh Shan wrote (snipped): > The enabling technique behind our solution is to propagate values > via types (literally), with the help of polymorphic recursion and > higher-ranked polymorphism. The technique essentially emulates > local type-class instance declarations. Configuration parameters > are propagated throughout the code implicitly as part of type > inference rather than explicitly by the programmer. Crikey! You represent configuration values which are integers by encoding them as a type with constructors data Zero data Twice s data Succ s data Pred s and you encode general values which are instances of Storable by casting their binary representation (pinned by a StablePtr) into bytes and then encoding the result as integers. My mind boggles. It would be nice if your paper included an appendix containing a main program which, say, used a graphics library including configuration parameters in your style. (Say, default font (string), font size (integer) and mouse handedness (bool).) From ashley at semantic.org Fri Jun 4 03:35:14 2004 From: ashley at semantic.org (Ashley Yakeley) Date: Fri Jun 4 03:33:38 2004 Subject: [Haskell] Re: Initialisation without unsafePerformIO References: <40BCA98C.4090205@informatik.uni-bremen.de> <20040601163515.GA8357@momenergy.repetae.net> Message-ID: In article <20040601163515.GA8357@momenergy.repetae.net>, John Meacham wrote: > I am a fan of allowing top level declarations of the form: > > foo <- newIORef "foo" > > which would behave as an initializer, with the semantics being that it > be evaluated at most once before foos first use. (so it could be > implemented via unsafePerformIO or as an init section run before main). > > The > {-# NOINLINE foo #-} > foo = unsafePeformIO $ newIORef "foo" > > idiom is so common and useful, it should have some compiler support. It > is 'clean' too, since all we are doing is extending the "world" with new > state, but in a much cleaner/safer way then writing to a file or environment > variable or other methods of storing state in the world. Clean it is not: foo :: a foo <- newIORef undefined writeChar :: Int -> IO () writeChar x = writeIORef foo x readString :: IO String readString = readIORef foo cast :: Char -> IO String cast c = (writeChar c) >> readString -- Ashley Yakeley, Seattle WA From daanleijen at xs4all.nl Fri Jun 4 05:20:51 2004 From: daanleijen at xs4all.nl (Daan Leijen) Date: Fri Jun 4 05:19:07 2004 Subject: [Haskell] Re: Initialisation without unsafePerformIO In-Reply-To: References: <40BCA98C.4090205@informatik.uni-bremen.de> <20040601163515.GA8357@momenergy.repetae.net> Message-ID: On Fri, 04 Jun 2004 00:35:14 -0700, Ashley Yakeley wrote: > In article <20040601163515.GA8357@momenergy.repetae.net>, > John Meacham wrote: > >> I am a fan of allowing top level declarations of the form: >> >> foo <- newIORef "foo" >> >> which would behave as an initializer, with the semantics being that it >> be evaluated at most once before foos first use. (so it could be >> implemented via unsafePerformIO or as an init section run before main). >> >> The >> {-# NOINLINE foo #-} >> foo = unsafePeformIO $ newIORef "foo" >> >> idiom is so common and useful, it should have some compiler support. It >> is 'clean' too, since all we are doing is extending the "world" with new >> state, but in a much cleaner/safer way then writing to a file or environment >> variable or other methods of storing state in the world. > > Clean it is not: > > foo :: a > foo <- newIORef undefined > > writeChar :: Int -> IO () > writeChar x = writeIORef foo x > > readString :: IO String > readString = readIORef foo > > cast :: Char -> IO String > cast c = (writeChar c) >> readString If we check that the type of "foo" is monomorphic, this is no longer unsafe. -- Daan. From john at repetae.net Fri Jun 4 06:35:25 2004 From: john at repetae.net (John Meacham) Date: Fri Jun 4 06:36:50 2004 Subject: [Haskell] Re: Initialisation without unsafePerformIO In-Reply-To: References: <40BCA98C.4090205@informatik.uni-bremen.de> <20040601163515.GA8357@momenergy.repetae.net> Message-ID: <20040604103525.GH30722@momenergy.repetae.net> On Fri, Jun 04, 2004 at 12:35:14AM -0700, Ashley Yakeley wrote: > In article <20040601163515.GA8357@momenergy.repetae.net>, > John Meacham wrote: > > > I am a fan of allowing top level declarations of the form: > > > > foo <- newIORef "foo" > > > > which would behave as an initializer, with the semantics being that it > > be evaluated at most once before foos first use. (so it could be > > implemented via unsafePerformIO or as an init section run before main). > > > > The > > {-# NOINLINE foo #-} > > foo = unsafePeformIO $ newIORef "foo" > > > > idiom is so common and useful, it should have some compiler support. It > > is 'clean' too, since all we are doing is extending the "world" with new > > state, but in a much cleaner/safer way then writing to a file or environment > > variable or other methods of storing state in the world. > > Clean it is not: > > foo :: a > foo <- newIORef undefined > > writeChar :: Int -> IO () > writeChar x = writeIORef foo x > > readString :: IO String > readString = readIORef foo > > cast :: Char -> IO String > cast c = (writeChar c) >> readString Yeah, such an extension would need to ensure initializers are monomorphic. another advantage of a special syntax rather than unsafePerformIO. John -- John Meacham - ?repetae.net?john? From hassei at kurims.kyoto-u.ac.jp Fri Jun 4 05:26:41 2004 From: hassei at kurims.kyoto-u.ac.jp (Hasegawa Masahito) Date: Fri Jun 4 11:36:25 2004 Subject: [Haskell] TLCA 05 Call for Papers Message-ID: <200406040926.i549Qf306287@synaphai.kurims.kyoto-u.ac.jp> TLCA'05 CALL FOR PAPERS Seventh International Conference on Typed Lambda Calculi and Applications (TLCA '05) Nara, Japan 21-23 April 2005 (Colocated with RTA as RDP '05) http://www.kurims.kyoto-u.ac.jp/rdp05/tlca/ The TLCA series of conferences serves as a forum for presenting original research results that are broadly relevant to the theory and applications of typed lambda calculi and related systems. The following list of topics is non-exhaustive: * Typed and untyped lambda-calculi as models of computation. * Proof-theory: Natural deduction, sequent calculi, cut elimination and normalization. Propositions as types, linear logic and proof nets. * Types: Subtypes, dependent types, type inference, polymorphism, types for security. * Semantics: Denotational semantics, game semantics, realizability, categorical models. * Programming languages: Foundations of functional and object-oriented programming, proof search, logic programming, type checking. * Implementation: Abstract machines, parallel execution, optimal reduction, program optimization. * Computer-aided reasoning. The programme of TLCA'05 will consist of three invited talks and about 25 papers selected from original contributions. Accepted papers will be published as a volume of Springer Lecture Notes in Computer Science series. [http://www.springer.de/comp/lncs/index.html] Submissions: ------------ The submitted papers should describe original work and should allow the Programme Committee to assess the merits of the contribution: in particular references and comparisons with related work should be included. Submission of material already published or submitted to other conferences with published proceedings is not allowed. Papers should not exceed 15 pages in Springer LNCS format. An abstract (ASCII text) of no more than 150 words should be sent separately at least a week before the paper submission deadline. All submissions should be sent by e-mail to tlca05@mimuw.edu.pl Important dates: ---------------- Authors are required to submit a paper title and a short abstract at least a weak before the paper submission deadline. All deadlines below are at 24:00 Central European time (GMT+1). Titles and abstracts due: October 25, 2004 Paper submission deadline: November 2, 2004 Notification: December 22, 2004 Final versions due: January 31, 2005 Accepted papers should be prepared according to Springer LNCS guidelines as described in http://www.springer.de/comp/lncs/authors.html. Final versions must include all source files. Further information is available from the conference web page http://www.kurims.kyoto-u.ac.jp/rdp05/tlca/ Inquiries concerning submissions and programme should be addressed to tlca05@mimuw.edu.pl. Inquiries concerning the conference organization and participation should be sent to tlca05org@kurims.kyoto-u.ac.jp TLCA Steering Committee: ------------------------ Samson. Abramsky, Oxford, chair Henk Barendregt, Nijmegen Mariangiola Dezani-Ciancaglini, Turin Roger Hindley, Swansea Martin Hofmann, Munich TLCA 05 Programme Committee: ---------------------------- Thorsten Altenkirch, University of Nottingham Stefano Berardi, University of Turin Adriana Compagnoni, Stevens Institute of Technology, Hoboken Herman Geuvers, Nijmegen University Andy Gordon, Microsoft Research, Cambridge Fritz Henglein, Copenhagen University Martin Hofmann, LMU Munich Assaf J. Kfoury, Boston University Atsushi Ohori, JAIST, Tatsunokuchi Laurent Regnier, IML Marseille Pawel Urzyczyn, Warsaw University, chair Marek Zaionc, Jagiellonian University, Cracow TLCA 05 Organizing Committee: ----------------------------- Masahito Hasegawa, Kyoto, chair Ryu Hasegawa, Tokyo Mitsu Okada, Keio Masahiko Sato, Kyoto Masako Takahashi, ICU ------------------------------------------------------------------------------ From abe.egnor at gmail.com Fri Jun 4 13:56:34 2004 From: abe.egnor at gmail.com (Abraham Egnor) Date: Fri Jun 4 13:54:53 2004 Subject: [Haskell] Re: Initialisation without unsafePerformIO In-Reply-To: <20040604103525.GH30722@momenergy.repetae.net> References: <40BCA98C.4090205@informatik.uni-bremen.de> <20040601163515.GA8357@momenergy.repetae.net> <20040604103525.GH30722@momenergy.repetae.net> Message-ID: I don't see how this technique can be at all safe: instance ReflectStorable s => Reflect (Stable s a) a where reflect = unsafePerformIO $ do a <- deRefStablePtr p freeStablePtr p return (const a) where p = reflectStorable (undefined :: s p) reify :: a -> (forall s. Reflect s a => s -> w) -> w reify (a :: a) k = unsafePerformIO $ do p <- newStablePtr a reifyStorable p (\(_ :: s p) -> k' (undefined :: Stable s a)) where k' (s :: s) = (reflect :: s -> a) `seq` return (k s) The above means that a StablePtr will be allocated once per reify and destroyed once per reflect; I don't see how the code can guarantee that there will be only one reflect per reify. In fact, it seems quite likely that there will be far more reflects than reifys. On Fri, 4 Jun 2004 03:35:25 -0700, John Meacham wrote: > > On Fri, Jun 04, 2004 at 12:35:14AM -0700, Ashley Yakeley wrote: > > In article <20040601163515.GA8357@momenergy.repetae.net>, > > John Meacham wrote: > > > > > I am a fan of allowing top level declarations of the form: > > > > > > foo <- newIORef "foo" > > > > > > which would behave as an initializer, with the semantics being that it > > > be evaluated at most once before foos first use. (so it could be > > > implemented via unsafePerformIO or as an init section run before main). > > > > > > The > > > {-# NOINLINE foo #-} > > > foo = unsafePeformIO $ newIORef "foo" > > > > > > idiom is so common and useful, it should have some compiler support. It > > > is 'clean' too, since all we are doing is extending the "world" with new > > > state, but in a much cleaner/safer way then writing to a file or environment > > > variable or other methods of storing state in the world. > > > > Clean it is not: > > > > foo :: a > > foo <- newIORef undefined > > > > writeChar :: Int -> IO () > > writeChar x = writeIORef foo x > > > > readString :: IO String > > readString = readIORef foo > > > > cast :: Char -> IO String > > cast c = (writeChar c) >> readString > > Yeah, such an extension would need to ensure initializers are monomorphic. another > advantage of a special syntax rather than unsafePerformIO. > > > John > > -- > John Meacham - ?repetae.net?john? > _______________________________________________ > Haskell mailing list > Haskell@haskell.org > http://www.haskell.org/mailman/listinfo/haskell > From ccshan at post.harvard.edu Fri Jun 4 13:04:53 2004 From: ccshan at post.harvard.edu (Chung-chieh Shan) Date: Fri Jun 4 14:28:40 2004 Subject: [Haskell] Re: Initialisation without unsafePerformIO In-Reply-To: <20040604103525.GH30722@momenergy.repetae.net> References: <40BCA98C.4090205@informatik.uni-bremen.de> <20040601163515.GA8357@momenergy.repetae.net> <20040604103525.GH30722@momenergy.repetae.net> Message-ID: <20040604170453.GA8367@ligate> On 2004-06-04T03:35:25-0700, John Meacham wrote: > Yeah, such an extension would need to ensure initializers are > monomorphic. another advantage of a special syntax rather than > unsafePerformIO. A next thing to worry about is the order of initialization, especially when mutually recursive imports are involved. -- Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig unsafePerformIO is NOT Haskell! -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: Digital signature Url : http://www.haskell.org//pipermail/haskell/attachments/20040604/5387e3d7/attachment.bin From jadrian at mat.uc.pt Fri Jun 4 16:59:21 2004 From: jadrian at mat.uc.pt (Jorge Adriano Aires) Date: Fri Jun 4 16:58:27 2004 Subject: [Haskell] Initialisation without unsafePerformIO In-Reply-To: <40BCA98C.4090205@informatik.uni-bremen.de> References: <40BCA98C.4090205@informatik.uni-bremen.de> Message-ID: <200406042159.21728.jadrian@mat.uc.pt> > What ideas do people have for getting rid of unsafePerformIO? Hope my suggestion is not too naive. I get along quite fine using implicit parameters in many cases, it's just tedious explicitly typing them in every function context. I'd be pretty happy if it was possible to define the 'scope' of some implicit parameters in a module and/or define their scope as being a whole module. The 2nd option would be something like: > module (?par :: Parameter) => A where > ... Functions in A could have ?par in their context without having it explicitly typed. Now the import of A could be done with: > module B where > > import A -- simple, ?par unbound > import A as Ak where ?par = k -- ?par bound to k > import A as Am where ?par = m -- ?par bound to m > > ... > > k :: Parameter > k = ... > > m :: Parameter > m = ... > ... Also, > module (?par :: Parameter) => C where > import A -- both A and C paremeterised by ?par Since both modules share the same parameter, instantiation on ?par in the import of C would propagate to the import of A. At first glance it seems simple syntactic sugar and therefore doable. Along with some options in the interpreter to hide/show (this kind of) implicit parameters when displaying signatures, check module context, etc. probably also quite usable. J.A. From camio at yahoo.com Sat Jun 5 20:03:53 2004 From: camio at yahoo.com (David Sankel) Date: Sat Jun 5 20:02:08 2004 Subject: [Haskell] Lists as Arrows Message-ID: <20040606000353.42406.qmail@web40604.mail.yahoo.com> Hello, Forgive me, I have but a fuzzy idea of what Arrows are. I was thinking it might be possible to make lists arrows instead of monads. This would allow (++) to be one of those special arrow computations. It would have some quite nice properties. For example (++ [a]) could be a O(1) operation instead of a O(n). Also, the trivial implementation of a queue would be O(1) for push and pop operations instead of the more complicated amortized O(1) implementation. Am I missing the point or is what I said above a possibility? David J. Sankel From venice at vreme.yubc.net Fri Jun 4 13:54:33 2004 From: venice at vreme.yubc.net (IPSI-2004) Date: Sat Jun 5 22:33:21 2004 Subject: [Haskell] Invitation to IPSI-2004 VENICE and IPSI-2004 PRAGUE, vip/ba Message-ID: <200406041754.i54HsXh04608@vreme.yubc.net> Dear Potential Speaker: This is an invitation for you to attend two IPSI BgD multidisciplinary and interdisciplinary conferences, one in Venice, and one in Prague, as follows: IPSI-2004 VENICE Venice, Italy (arrival: 10.11.2004. departure: 14.11.2004.) Deadlines: 15 June 2004 (abstract) + 1 August 2004 (full paper). IPSI-2004 PRAGUE Prague, Czeck Republic (arrival: 11.12.2004. departure: 14.12.2004.). Deadlines: 15 July 2004 (abstract) + 1 September 2004 (full papers) If you like to obtain more information on both conferences, please reply to this email. All IPSI BgD conferences are non-profit! They bring together the elite of the world science (so far, 7 times a Nobel Laureate was talking at the opening ceremony), and they take place in the leading hotels of the world. Topics of interest include, but are not limited to: Internet, Computer Science and Engineering, Management and Business Administration, Education, e-Medicine, Electrical Engineering, Bioengineering, Environment Protection, and e-Economy. Sincerely Yours, Prof. V. Milutinovic, Chairman PS - If you plan to submit an abstract/paper, let us know immediately. If you are not able to attend now, but you like to be informed about the future IPSI BgD conferences, please let us know. If you do not like to receive future invitations, let us know, as well! From ccshan at post.harvard.edu Sun Jun 6 21:03:45 2004 From: ccshan at post.harvard.edu (Chung-chieh Shan) Date: Sun Jun 6 21:02:09 2004 Subject: [Haskell] Re: Initialisation without unsafePerformIO In-Reply-To: References: <40BCA98C.4090205@informatik.uni-bremen.de> <20040601163515.GA8357@momenergy.repetae.net> <20040604103525.GH30722@momenergy.repetae.net> Message-ID: <20040607010345.GA28697@ligate> On 2004-06-04T13:56:34-0400, Abraham Egnor wrote: > I don't see how this technique can be at all safe: > > instance ReflectStorable s => Reflect (Stable s a) a where > reflect = unsafePerformIO $ > do a <- deRefStablePtr p > freeStablePtr p > return (const a) > where p = reflectStorable (undefined :: s p) > > reify :: a -> (forall s. Reflect s a => s -> w) -> w > reify (a :: a) k = unsafePerformIO $ > do p <- newStablePtr a > reifyStorable p (\(_ :: s p) -> k' (undefined :: Stable s a)) > where k' (s :: s) = (reflect :: s -> a) `seq` return (k s) > > The above means that a StablePtr will be allocated once per reify and > destroyed once per reflect; I don't see how the code can guarantee > that there will be only one reflect per reify. In fact, it seems > quite likely that there will be far more reflects than reifys. But (in a typical Haskell implementation) the action supplied as an argument to unsafePerformIO is only performed once. The result is memoized for future use. In particular, "reflect" only calls "freeStablePtr" the first time it is invoked; thereafter it simply produces the function "const a" that was computed the first time. You can easily verify for yourself that "deRefStablePtr" is called exactly once per "newStablePtr", regardless of whether the reified value is looked up once, multiple times, or not at all. (The "not at all" case is dealt with by the "seq".) In any case, if you don't trust this explanation, then you can use the preceding pieces of code in Section 4. The memory leak that this code eliminates only exists for non-serializable data types, and only significant if your program generates and discards many sets of non-serializable parameters outside the IO monad over its lifetime. Oleg + Ken -- Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig I HATE SIGNATURES. AND I HATE MYSELF FOR USING THEM. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: Digital signature Url : http://www.haskell.org//pipermail/haskell/attachments/20040606/486c1f23/attachment.bin From jmj at info.fundp.ac.be Sun Jun 6 12:35:11 2004 From: jmj at info.fundp.ac.be (Jean-Marie JACQUET) Date: Mon Jun 7 09:24:17 2004 Subject: [Haskell] Foclasa: Call for Papers Message-ID: <200406061635.i56GZBE02139@backus.info.fundp.ac.be> [ Our apologies for multiple copies. ] ====================================================================== 3nd International Workshop on Foundations of Coordination Languages and Software Architectures (Foclasa 2004) August 30, 2004, London, United Kingdom Workshop affiliated to CONCUR'2004, August 30 - September 3 2004. WITH DEADLINE EXTENSIONS ====================================================================== SCOPE AND TOPICS Modern information systems rely more and more on combining concurrent, distributed, mobile and heterogenous components. This move from old systems, typically conceived in isolation, induces the need for new languages and software architectures. In particular, coordination languages have been proposed to cleanly separate computational aspects and communication. On the other hand, software architects face the problem of specifying and reasoning on non-functional requirements. All these issues are widely perceived as fundamental to improve software productivity, enhance maintainability, advocate modularity, promote reusability, and lead to systems more tractable and more amenable to verification and global analysis. The aim of the workshop is to bring together researchers working on the foundations of component-based computing, coordination, and software architectures. Topics of interest include (but are not limited to): o Theoretical models for coordination (component composition, concurrency, dynamic aspects of coordination, semantics, expressiveness); o Specification, refinement, and analysis of software archi- tectures (patterns and styles, verification of functional and non-functional properties); o Coordination, architectural, and interface description languages (implementation, interoperability, heterogeneity); o Agent-oriented languages (formal models for interacting agents); o Dynamic software architectures (mobile agents, configuration, reconfiguration); o Modeling of information systems (groupware, internet and the web, workflow management, CSCW and multimedia applications) o Coordination patterns (mobile computing, internet computing); o Tools and environments for the development of coordinated applications o Methodologies for validating and certifying software compositions SUBMISSION GUIDELINES Papers describing original work are solicited as contributions to Foclasa. Submitted papers should be limited to 6 000 words, preferrably formatted according to the Electronical Notes in Theoretical Computer Science. They should be emailed as PostScript (PS) or Portable Document Format (PDF) files to jmj@info.fundp.ac.be. PUBLICATION Following the previous edition, the proceedings will be published as a volume of the Electronical Notes in Theoretical Computer Science. IMPORTANT DATES: o June 7, 2004: Abstract Submission deadline. o June 13, 2004: Full Paper Submission deadline. o July 15, 2004: Notification of acceptance. o August 15, 2004: Final version. o August 30, 2004: Meeting Date. LOCATION The workshop will be held in London in August 30 2004. It is a satellite workshop of CONCUR 2004. For venue and registration, see the CONCUR web page at http://www.doc.ic.ac.uk/concur2004/. WORKSHOP ORGANIZERS o Antonio Brogi (University of Pisa, Italy) o Jean-Marie Jacquet (University of Namur, Belgium) o Ernesto Pimentel (University of Malaga, Spain) PROGRAMME COMITTEE (provisional): o Farhad Arbab (CWI, The Netherlands) o Antonio Brogi (University of Pisa, Italy) - Co-chair o Manfred Broy (University of Munich, Germany) o Jean-Marie Jacquet (University of Namur, Belgium) - Co-chair o Joost Kok (University of Leiden, The Netherlands) o Antonia Lopes (University of Lisbon, Portugal) o Ronaldo Menezes (Florida Institute of Technology, USA) o Amy Murphy (University of Rochester, USA) o Ernesto Pimentel (University of Malaga, Spain) - Co-chair o Sebastian Uchitel (Imperial College, United Kingdom) o Mirko Viroli (University of Bologna, Italy) o Jan Vitek (Purdue University, USA) From lmagnani at cc.gatech.edu Sun Jun 6 16:11:22 2004 From: lmagnani at cc.gatech.edu (Lorenzo Magnani) Date: Mon Jun 7 09:24:18 2004 Subject: [Haskell] MBR04 Extended deadline Message-ID: <40C37A6A.1080900@cc.gatech.edu> EXTENDED DEADLINE - Deadline June 20, 2004 ****************************************************************** MODEL-BASED REASONING IN SCIENCE AND ENGINEERING ABDUCTION, VISUALIZATION, AND SIMULATION MBR'04 Pavia, Italy, December 16-18, 2004 Chair: Lorenzo Magnani ****************************************************************** Up-to date information on the conference will be found at http://www.unipv.it/webphilos_lab/courses/progra1.html ****************************************************************** GENERAL INFORMATION From Thursday 16 to Saturday 18 December 2004 (three days) the International Conference "MODEL-BASED REASONING IN SCIENCE AND ENGINEERING: ABDUCTION, VISUALIZATION, AND SIMULATION" will be held at the University of Pavia (near Milan, Italy). The conference continues the theme of the Conferences "Model-Based Reasoning in Scientific Discovery" MBR'98 and "Model-Based Reasoning: Scientific Discovery, Technological Innovation, and Values" MBR'01 The previous volumes derived from those conferences are: L. Magnani and N. J. Nersessian (eds.) (2002), Model-Based Reasoning. Science, Technology, Values, Kluwer Academic/Plenum Publishers, New York. http://www.wkap.nl/prod/b/0-306-47244-9 L. Magnani, N. J. Nersessian, and C. Pizzi (eds.) (2002), Logical and Computational Aspects of Model-Based Reasoning, Kluwer Academic, Dordrecht. http://www.wkap.nl/prod/b/1-4020-0791-4 L. Magnani, N. J. Nersessian, and P. Thagard (eds.) (1999), Model-Based Reasoning in Scientific Discovery, Kluwer Academic/Plenum Publishers, New York. http://www.wkap.nl/prod/b/0-306-46292-3 (Chinese edition, translated and edited by Q. Yu and T. Wang, China Science and Technology Press, Beijing, 2000). PROGRAM The conference will deal with the logical, epistemological, and cognitive aspects of modeling practices employed in science and engineering, including computational models of such practices. We solicit papers that examine the role of abduction, visualization, and simulation in model-based reasoning from philosophical, historical, sociological, psychological, or computational perspectives. RELEVANT RESEARCH AREAS We call for papers that cover topics pertaining to model-based reasoning in science and engineering from the following list: - abduction - visual, spatial, imagistic modeling and reasoning - simulative modeling - the role of diagrammatic representations - computational models of visual and simulative reasoning - causal and counterfactual reasoning in model construction - visual analogy - thought experimenting - logical analyses related to model-based reasoning - manipulative reasoning - distributed model-based reasoning - embodiment in model-based reasoning - model-based reasoning and technological innovation INVITES SPEAKERS WHO ALREADY ACCEPTED TO GIVE A PRESENTATION AT MBR'04 - Atocha Aliseda, Instituto de Investigaciones Filosoficas Universidad Nacional Autonoma de Mexico (UNAM), Mexico City, MEXICO - Lawrence W. Barsalou,Department of Psychology,Emory University Atlanta, GA, USA - Diderik Batens, Centre for Logic and Philosophy of Science, Universiteit Gent, Ghent, BELGIUM - Walter Carnielli, CLEHC State University of Campinas - UNICAMP, Campinas, SP, Brazil - Balakrishnan Chandrasekaran, Laboratory for Artificial Intelligence Research, Department of Computer and Information Sience, Columbus, OH, USA. - Kenneth D. Forbus, Walter P. Murphy Professor of Computer Science and Education, Northwestern University, Evanston, IL, USA - Dov Gabbay, Department of Computer Science, King's College, London, UK - David Gooding, Science Studies Centre, Department of Psychology University of Bath, Bath, UK - Mary Hegarty, Department of Psychology, University of California, Santa Barbara, CA, USA - Theo A.F. Kuipers, Dept. of Philosophy, University of Groningen, Groningen, NETHERLANDS - Michael Leyton, DIMACS, Busch Campus, Rutgers University, New Brunswick, NJ, USA - Li Ping, Department of Philosophy, Sun Yat-sen (Zhongshan) University, Guangzhou, P.R.CHINA - Lorenzo Magnani, Department of Philosophy, University of Pavia, Pavia, ITALY and Baruch College, The City University of New York, New York, USA - Nancy J. Nersessian, College of Computing, Georgia Institute of Technology, Atlanta, GA, USA - Claudio Pizzi, Department of Philosophy and Social Sciences, University of Siena, Siena, ITALY - Qiming Yu, Department of Philosophy, Central University for Nationalities, Bejing, P.R. CHINA - Friedrich Steinle, Max-Planck-Institut, Berlin, GERMANY - John Woods, Department of Philosophy, University of British Columbia, Vancouver and Department of Computer Science, King's College, London, UK - Andrea Woody, Department of Philosophy, University of Washington Seattle, WA, USA SUBMISSIONS OF PAPERS All submitted papers will be carefully refereed. The precise format of the conference will be fixed after we have an idea of the number of accepted papers. We expect approximately 40 contributed presentations some of 40 and others of 20 minutes. There will be several invited papers of 1 hour. A selected subset will be invited for inclusion (subject to additional refereeing) in a book which will constitute an advanced handbook for researchers in this area. The book will be published by an international publishing house. Moreover another selected subset will be invited for inclusion (subject to additional refereeing) in special issues of suitable international journals. Authors must submit an electronic version - formatted in Microsoft Word or RTF, PS or PDF ( in this last case two cases please include source - DOC, TEX, etc., file) - of an extended abstract (total word count aproximately 1000-1200). The file must also contain a 300 WORD abstract that will be used for the conference web site/booklet. Not later than June 20, 2004 Please send electronically the extended abstract to the Prof. Magnani at the address lmagnani@unipv.it A RIGID LAW ON PRIVACY IN ITALY DOES NOT FAVOR MORE COMFORTABLE COMPUTATIONAL METHODS OF PAYMENTS (CONFERENCE AND ACCOMMODATION FEES), SORRY. PLEASE FOLLOW THE INSTRUCTIONS INDICATED BELOW. REGISTRATION AND FURTHER INFORMATION PLEASE REGISTER by email lorenzo.magnani@unipv.it, fax or air mail by sending the PROGRAM CHAIR Lorenzo Magnani first and last name, function, institution, full address, phone, fax and email. For information about paper submission and the program that is not available on the web site, please contact the program chair. Registration Fees: Before October 15, 2004: Standard: Euro 180,00 (to participate in all the activities of the Conference Social Dinner included) Phd Students: Euro 120,00 Students (Undergraduates): Free After October 15, 2004: Standard: Euro 240,00 (to participate in all the activities of the Conference Social Dinner Included) Phd Students: Euro 160,00 Students (Undergraduates): Free One day only: Euro 100,00 No refunds will be granted after November 1st Terms & Conditions: an administration fee of Euro 75,00 will be charged for cancellations confirmed in writing by December 1st. We regret that no refund can be made after that date, for whatever reason,although substitutions will be acceptable if notified in writing before the event. METHOD OF PAYMENT: SWIFT TRANSFER Bank (Swift) Transfer to BANCA REGIONALE EUROPEA S.p.A BRANCH PAVIA - Sede SWIFT BREUITM2 301 Bank Code 06906.11301 CIN V Acc. n. 43008 COMITATO CONVEGNI E. W. I. C. IBAN: IT32V0690611301000000043008. Please indicate CONVEGNO INTERNAZIONALE MBR04 Please ask your BANK to clearly indicate in the order of payment your first and last NAME. In case of problems please contact Elena Gandini Local Organizer elena@acrossevents.com). If you prefer, you can mail an international check to CONVEGNO INTERNAZIONALE E-CAP2004_ITALY, Dipartimento di Filosofia, Piazza Botta 6, 27100 Pavia, Italy . ACCOMMODATION To book a reservation please fill and fax to +39-0382-23215 the ACCOMMODATION FORM you will find in the Conference Web Site http://www.unipv.it/webphilos_lab/courses/progra1.html (to dr. Elena Gandini Local Organizer). POSSIBLY BEFORE NOVEMBER 10, 2003. For information please email Elena Gandini, Local Organizer elena@acrossevents.com. Please do not send email messages containing your credit card data. All accommodation is hotel-based with en-suite facilities (the prices are per room per day). Hotel Moderno ****Euro 103,00 (single b&b) Euro138,00 (double b&b) Hotel Ariston *** Euro 80,00(single) Euro 110,00 (double), Breakfast Euro 10,00 Hotel Excelsior *** Euro 50,00(single) Euro 73,00(double) Euro 62,00(D/S) breakfast Euro 6,00 Hotel Ritz*** Euro 65,00 (single b&b) Euro 87,00 (double b&b) Hotel Excelsior (from the station walk east) Hotel Moderno (from the station walk north) Hotel Ritz (San Genesio-PV); an Hotel bus service is available. To reach Hotel Ariston take the bus n. 3 or taxi. If the Hotels above will be completely booked other Hotels are available, in this last case please email dr. Elena Gandini Local Organizer e-mail: elena@acrossevents.com PENALTY In case of no show the Hotels will charged you their own penalty. For further information, please contact our local organiser Elena Gandini elena@acrossevents.com. IMPORTANT DATES Submission deadline..................... June 20, 2004 Notification of acceptance..............Sept 15, 2004 Conference............................. Dec 16-18, 2004 Final papers......................due.. February 15, 2005 PROGRAM CHAIR Lorenzo MAGNANI Department of Philosophy and Computational Philosophy Laboratory University of Pavia, Piazza Botta 6, 27100 Pavia, Italy Office: +39-0382-506283, Home: +39-0383-371067 Fax: +39-0382-23215 & Weissman Distinguished Visiting Professor Department of Philosophy, Baruch College, 1 Bernard Baruch Way, New York , NY 10010 Office: +646-312-4367, Fax: +646- 312-4361, Home: 646-432-9309 Email: lmagnani@unipv.it PROGRAM COMMITTEE - Atocha Aliseda, Instituto de Investigaciones Filosoficas Universidad Nacional Autonoma de Mexico (UNAM), Mexico City, MEXICO - Diderik Batens, Centre for Logic and Philosophy of Science, Universiteit Gent, Ghent, Belgium - Walter Carnielli,Centre for Logic, Epistemology and the History of Science - CLEHC State University of Campinas - UNICAMP, Campinas, SP, Brazil - Simon Colton, Department of Computing, Imperial College London 180 Queens Gate, London SW7 2BZ, United Kingdom - Roberto Cordeschi, Department of Communication Sciences, University of Salerno, Salerno , ITALY - Kenneth D. Forbus, Walter P. Murphy Professor of Computer Science and Education, Northwestern University, 1890 Maple Avenue, Evanston, IL, 60201, USA - Dov Gabbay, Department of Computer Science, King's College, London, UK - Ronald N. Giere, Department of Philosophy, 831 Heller Hall University of Minnesota, Minneapolis, MN USA 55455 - David Gooding, Science Studies Centre, Department of Psychology University of Bath, Bath BA2 7AY, UK - Elke Kurz-Milcke, College of Computing, Georgia Institute of Technology 801 Atlantic Dr. NW, Atlanta, GA 30332-0280, USA - Michael Leyton, Center for Discrete Mathematics & Theoretical Computer Science (DIMACS), Busch Campus, Rutgers University, New Brunswick, NJ 08854. USA - Lorenzo Magnani, Department of Philosophy, University of Pavia, Pavia, ITALY and Baruch College, The City University of New York, New York, USA - Nancy J. Nersessian, College of Computing, Georgia Institute of Technology, Atlanta, GA, USA - Wendy C. Newstetter, Director of Learning Sciences Research Wallace H. Coulter Dept. of Biomedical Engineering, Georgia Institute of Technology/Emory University school of Medicine, Atlanta, GA, USA - Claudio Pizzi, Department of Philosophy and Social Sciences, University of Siena, Siena, ITALY -.Stefanelli Mario, Dipartimento di Informatica e Sistemistica, Universit? di Pavia, Pavia, ITALY - Ryan D. Tweney, Professor of Psychology, Bowling Green State University Bowling Green, OH 43403, USA - Riccardo Viale, Fondazione Rosselli,Via San Quintino, 18/c, 10121 Torino, Italy - John Woods, Department of Philosophy, University of British Columbia, Vancouver and Department of Computer Science, King's College, London, UK - Andrea Woody, Department of Philosophy, University of Washington Box 353350, 345 Savery Hall, University of Washington, Seattle, WA 98195 - Xiang Chen, Department of Philosophy, California Lutheran University Thousand Oaks, CA 91360 LOCAL ORGANIZER dr. Elena Gandini Across Events s.r.l. Via A. Moro, 12 27021 Bereguardo (PV) Italy mobile +39 349 55 41 915 e-mail: elena@acrossevents.com www.acrossevents.com LOCAL ORGANIZING COMMITTEE Elena Gandini (elena@acrossevents.com), Riccardo Dossena (riki.dox@libero.it), Lorenzo Magnani (lmagnani@unipv.it), (Department of Philosophy, University of Pavia, Pavia, Italy) Stefanelli Mario (mstefa@aim.unipv.it), Matteo Piazza (pimat@yahoo.com), (Dipartimento di Informatica e Sistemistica, Universit? di Pavia, Pavia, Italy) CONFERENCE SITE: Collegio Ghislieri, Piazza Ghislieri, 27100 PAVIA, Italy, phone +39 0382 37861. http://www.ghislieri.it/ The Conference is sponsored by UNIVERSITY OF PAVIA, ITALY UNIVERSITY OF SIENA, ITALY MIUR (Ministero dell'Universit? e della Ricerca Scientifica e Tecnologica), ITALY CARIPLO (Cassa di Risparmio delle Provincie Lombarde) HOW TO REACH PAVIA LINATE Airport: www.sea-aeroportimilano.it/linate People arriving by plane at LINATE should take the bus to the CENTRAL STATION of Milan (cf. below from this Station to Pavia). In LINATE it could be convenient to take a Taxi because the airport is close to the center of Milan. Moreover,the bus company SGEA ( www.sgea.it ) offers six runs from LINATE to Pavia at 9.00, 10.00, 12.00 AM and 2.00, 5.00, 8.30 PM. The last stop is Pavia, near the station (see again our updated web page for possible alterations of this time-table) (from Pavia to LINATE six runs at 5.00, 7.30, 10.00 AM, 1.00, 4.00, 6.00 PM) (one hour trip; _13,00 return ticket, _8,00 one way ticket). In Pavia there is only one station. The easiest way to reach the center of the town is to get off at the station and than take the bus n. 3. MALPENSA 2000 (Terminal 1) and OLD MALPENSA (Terminal 2) Airport: www.sea-aeroportimilano.it/malpensa (usually people arrive to Malpensa 2000 and not to OLD MALPENSA): People arriving by plane at MALPENSA 2000 (also called MALPENSA 2000 Terminal 1) or at "old" MALPENSA (now called MALPENSA NORTH but also called Malpensa 2000 Terminal 2) should take the bus to the CENTRAL STATION of Milan. There is also a bus AND A shuttle TRAIN (Malpensa Express) from Malpensa 2000 to the NORTH STATION (Piazzale Cadorna) of Milan, in this case from NORTH Station you will have to take the underground MM2 (green line) to the Central Raylway Station: trains to Pavia leave from Central station. Moreover, the bus company SGEA offers various runs from MALPENSA 2000 to Pavia at 9.00, 11:00 AM, 1:30 3:00, 5:00, 7:00, 9:30, PM (from Pavia to MALPENSA 2000 and to OLD MALPENSA various runs at 7.00, 9:00, 11:00 AM, 1:00, 3:15, 5:00, 7:00 PM) (one hour and half trip; _18,00 retourn ticket, _12,00 one way ticket). The last stop is Pavia, near the rail station. In Pavia there is only one rail station. The easiest way to reach the center of the town is to get off at the station and than take the bus n. 3. There are trains from MILAN (Central Raylway Station) to PAVIA and vice versa about every an hour www.trenitalia.it (routes: MILAN-GENOVA; MILAN-VENTIMIGLIA; MILAN-LA SPEZIA; MILAN-SAVONA; MILAN-SESTRI LEVANTE; MILAN-IMPERIA; MILAN-ALBENGA; Pavia is the first stop only if the train is not slow, that is, if it is not, in ITALIAN, "L", locale). (see again our updated web page for possible alterations of this time-table) From oleg at pobox.com Tue Jun 8 17:12:17 2004 From: oleg at pobox.com (oleg@pobox.com) Date: Tue Jun 8 17:13:30 2004 Subject: [Haskell] Re: how to write a list builder? fixpoint? In-Reply-To: Message-ID: <20040608211217.27AEDABC3@Adric.metnet.navy.mil> Ben Yu wrote: > I'm new to haskell, new to this group, don't even know what this > "cafe" refers to. Is there a special place for discussing further > details? Yes, http://haskell.org/mailman/listinfo/haskell-cafe >Similarly, a builder can be built for binary functions like addToFM. Here's a bit more general variant of it: > class Builder2 c a b r | r -> a where > build2 :: (a->b->c a b->c a b) -> c a b -> a -> b -> r > instance Builder2 c k v (c k v) where > build2 acc seed k v = acc k v seed > instance Builder2 c a b r => Builder2 c a b (a->b->r) where > build2 acc seed a b x y = build2 acc (acc a b seed) x y > > newtype AL a b = AL [(a,b)] deriving Show > > test1::AL String Bool > test1 = build2 (\x y (AL l) -> AL $ (x,y):l) (AL []) "a" True "b" False > > test2:: FiniteMap String Bool > test2 = build2 (\x y m -> addToFM m x y) emptyFM "a" True "b" False "c" True The function build2 not only has the variable number of arguments. These arguments don't even have to be of the same type. > However, I don't quite like having to say buildl (1::Int). If I can say > [1,2,3], which types to Num a => [a], why can't I say buildl 1 2 3 which > also types to Num a => [a]? [1,2,3] is a syntactic sugar for 1:(2:(3:[])). The operator (:) has the type (:) :: forall a. a -> [a] -> [a] Since (:) is actually a function, the type of the result (which is [a]->[a]) is unambiguously determined by the type of the argument, 'a'. Informally, the type of a function has a functional dependency. The function build' is a member of a class such that the type of the result of build' unambiguously determines the type of the argument. Note the reverse implication. Therefore, once we specify the type of the result, everything works out. And it does: Foo> build 1 2 3 4 :: [Int] [1,2,3,4] In Hugs. But not in GHC (6.0.1). My impression is that GHC assumes overlapping instances when choosing instances -- even if no -fallow-overlapping-instances flag is present. In order to get the example work in GHC, we have to assure that all arguments to build have the same type in some other way, e.g., using local type variables: *Foo> let (a::t)=1 in let b=(2::t); c=(3::t) in build a b c a b c ::[t] [1,2,3,1,2,3] The result is actually polymorphic, Num t => [t]. From per at L4i.se Wed Jun 9 14:37:32 2004 From: per at L4i.se (Per Larsson) Date: Wed Jun 9 14:35:34 2004 Subject: [Haskell] Implicit parameters Message-ID: <200406092037.32595.per@L4i.se> When using implicit parameters I have noticed (at least for me) a rather puzzling behaviour with GHC and Hugs. Given the declarations data Env = Env {numlines :: Int, numcols :: Int} initEnv = Env {numlines = 0, numcols = 1} withEnv :: ((?env :: Env) => IO a) -> IO a withEnv io = let ?env = initEnv in io I can write code like: main = withEnv (do let lines = numlines ?env putStrLn ("Initial number of lines is " ++ (show lines))) which works as expected, but the version below main = withEnv $ do let lines = numlines ?env putStrLn ("Initial number of lines is " ++ (show lines)) is not accepted by either GHC or Hugs! Is this a bug or have stumbled into a context where it actually matters if you use '$' or explicit grouping with parentheses? Per Larsson From diatchki at cse.ogi.edu Wed Jun 9 17:32:25 2004 From: diatchki at cse.ogi.edu (Iavor S. Diatchki) Date: Wed Jun 9 17:30:39 2004 Subject: [Haskell] Implicit parameters In-Reply-To: <200406092037.32595.per@L4i.se> References: <200406092037.32595.per@L4i.se> Message-ID: <40C781E9.4060709@cse.ogi.edu> hi, i don't think this is a bug, and this is a situation where it matters if you use ($) or parens. the same probelm occurs when you work with polymorohism, rank-2 and above, e.g. when you use runST. the problem occurs because ($) has a monomorphic (non-overloaded) type: ($) :: (a -> b) -> (a -> b) now consider the type of runST (same example applies to your problem bellow, but with constraints) runST :: (forall s. ST s b) -> b now if we were to apply ($) to runST, we must make sure that the type of runST is at least as polymorphic as what is required by ($),i.e. (forall s. ST s b) -> b <= a -> b (type on the left should be _more_ polymorphic, i.e. has _less_ elements hence the notation) the above would be true, if 1. b <= b (which is ok) 2. a <= forall s. ST s b (which is not ok, as "a" is an arbitry _monomorphic_ type, and is not more polymorphic then a schema) hope this helps, for details on the polymorphism & subtyping you may take a look at a number of papers over the past few years. there are some on simon pj's page i forget the exact title, but it is easy to find. -iavor Per Larsson wrote: >When using implicit parameters I have noticed (at least for me) a rather >puzzling behaviour with GHC and Hugs. > >Given the declarations > >data Env = Env {numlines :: Int, numcols :: Int} > >initEnv = Env {numlines = 0, numcols = 1} > >withEnv :: ((?env :: Env) => IO a) -> IO a >withEnv io = let ?env = initEnv in io > >I can write code like: > >main = withEnv (do > let lines = numlines ?env > putStrLn ("Initial number of lines is " ++ (show lines))) > >which works as expected, but the version below > >main = withEnv $ do > let lines = numlines ?env > putStrLn ("Initial number of lines is " ++ (show lines)) > >is not accepted by either GHC or Hugs! Is this a bug or have stumbled into a >context where it actually matters if you use '$' or explicit grouping with >parentheses? > >Per Larsson > > >_______________________________________________ >Haskell mailing list >Haskell@haskell.org >http://www.haskell.org/mailman/listinfo/haskell > > From m.escardo at cs.bham.ac.uk Thu Jun 10 05:39:07 2004 From: m.escardo at cs.bham.ac.uk (Martin Escardo) Date: Thu Jun 10 05:37:13 2004 Subject: [Haskell] topology in Haskell Message-ID: <16584.11323.961905.483469@gargle.gargle.HOWL> Dear Haskell-list members, This is to advertise the monograph Synthetic topology of data types and classical spaces, to appear in ENTCS 87, 150pp, three parts, 6+5+2 chapters. http://www.cs.bham.ac.uk/~mhe/papers/entcs87.pdf (or .dvi or .ps) Chapter 3 develops topology in Haskell, without assuming any previous knowledge of topology. Notions of topology such as space, continuous map, open set, closed set, discrete space, Hausdorff space, compact space are defined directly in the programming language. Theorems in topology are proved by writing programs. The development here is purely operational. This gives some surprising results, e.g. that the type ((Int->Bool)->Int) has decidable equality (for total elements). Chapter 12 has more sophisticated computational applications, which invoke classical topology with the aid of denotational semantics. We apply the Tychonoff theorem of classical topology to show that a certain (we hope surprising) Haskell program has the correct termination properties. Martin Escardo From Jon.Fairbairn at cl.cam.ac.uk Thu Jun 10 16:21:17 2004 From: Jon.Fairbairn at cl.cam.ac.uk (Jon Fairbairn) Date: Thu Jun 10 16:19:18 2004 Subject: [Haskell] topology in Haskell In-Reply-To: Your message of "Thu, 10 Jun 2004 10:39:07 BST." <16584.11323.961905.483469@gargle.gargle.HOWL> Message-ID: <6192.1086898877@cl.cam.ac.uk> On 2004-06-10 at 10:39BST Martin Escardo wrote: > Dear Haskell-list members, > > This is to advertise the monograph > > Synthetic topology of data types and classical spaces, to appear in > ENTCS 87, 150pp, three parts, 6+5+2 chapters. Interesting. But why do you use Int rather than the Integer? In particular > This gives some surprising results, e.g. that the type > ((Int->Bool)->Int) has decidable equality (for total elements). is not at all surprising, since Int (and Bool) is finite, so there are only finitely many total elements of that type :-) For Integer it is surprising, but I haven't read that far yet... J?n -- J?n Fairbairn Jon.Fairbairn@cl.cam.ac.uk From m.escardo at cs.bham.ac.uk Fri Jun 11 05:12:07 2004 From: m.escardo at cs.bham.ac.uk (Martin Escardo) Date: Fri Jun 11 05:10:09 2004 Subject: [Haskell] topology in Haskell In-Reply-To: <6192.1086898877@cl.cam.ac.uk> References: <16584.11323.961905.483469@gargle.gargle.HOWL> <6192.1086898877@cl.cam.ac.uk> Message-ID: <16585.30567.427874.522652@gargle.gargle.HOWL> Dear Jon, Thanks for your remarks. Jon Fairbairn writes: > Interesting. But why do you use Int rather than the Integer? Ok, I admit that I should have used Integer. Moreover, in practice you would like to use [a] when I use (Int -> a), as you'll notice. > In particular > > > This gives some surprising results, e.g. that the type > > ((Int->Bool)->Int) has decidable equality (for total elements). > > is not at all surprising, since Int (and Bool) is finite, so > there are only finitely many total elements of that type :-) > For Integer it is surprising, Let me add that I don't count "seq" as part of the language, so that two functions are equal iff they are equal at all arguments (i.e., functions are functions). But, with more trouble, it is possible to consider the full language, although I don't find this particularly illuminating. Martin From hofte at natlab.research.philips.com Fri Jun 11 07:23:11 2004 From: hofte at natlab.research.philips.com (Tom Hofte) Date: Fri Jun 11 07:32:22 2004 Subject: [Haskell] IO question Message-ID: <000801c44fa6$7b3fca00$37ae9182@ddns.htc.nl.philips.com> Hi, I have an question about the IO monad I want to have a function that unpack an IO. I should have the type: IO a -> a. Is this possible? Kind regards Tom Hofte -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org//pipermail/haskell/attachments/20040611/1401fcfa/attachment.htm From t.zielonka at students.mimuw.edu.pl Fri Jun 11 07:39:39 2004 From: t.zielonka at students.mimuw.edu.pl (Tomasz Zielonka) Date: Fri Jun 11 07:37:58 2004 Subject: [Haskell] IO question In-Reply-To: <000801c44fa6$7b3fca00$37ae9182@ddns.htc.nl.philips.com> References: <000801c44fa6$7b3fca00$37ae9182@ddns.htc.nl.philips.com> Message-ID: <20040611113939.GB5475@students.mimuw.edu.pl> On Fri, Jun 11, 2004 at 01:23:11PM +0200, Tom Hofte wrote: > I want to have a function that unpack an IO. > I should have the type: IO a -> a. > Is this possible? There is unsafePerformIO, but before you use it, think - do you really, really want to use it and you really, really know what the consequences can be? Perhaps you could tell us what it is that you think you need unsafePerformIO for? Maybe it can be done without it? Best regards, Tom -- .signature: Too many levels of symbolic links From ronny at cs.kun.nl Fri Jun 11 07:46:08 2004 From: ronny at cs.kun.nl (Ronny Wichers Schreur) Date: Fri Jun 11 07:44:05 2004 Subject: [Haskell] IO question In-Reply-To: <20040611113939.GB5475@students.mimuw.edu.pl> References: <000801c44fa6$7b3fca00$37ae9182@ddns.htc.nl.philips.com> <20040611113939.GB5475@students.mimuw.edu.pl> Message-ID: <40C99B80.2050001@cs.kun.nl> Tom Hofte writes (to the Haskell mailing list): > I want to have a function that unpack an IO. > I should have the type: IO a -> a. > Is this possible? Tomasz Zielonka replies: > There is unsafePerformIO, but before you use it, think [..] See also . Cheers, Ronny Wichers Schreur From Keith.Wansbrough at cl.cam.ac.uk Fri Jun 11 08:50:06 2004 From: Keith.Wansbrough at cl.cam.ac.uk (Keith Wansbrough) Date: Fri Jun 11 08:48:07 2004 Subject: [Haskell] IO question In-Reply-To: Your message of "Fri, 11 Jun 2004 13:39:39 +0200." <20040611113939.GB5475@students.mimuw.edu.pl> Message-ID: > On Fri, Jun 11, 2004 at 01:23:11PM +0200, Tom Hofte wrote: > > I want to have a function that unpack an IO. > > I should have the type: IO a -> a. > > Is this possible? > > There is unsafePerformIO, but before you use it, think - do you > really, really want to use it and you really, really know what the > consequences can be? Perhaps you could tell us what it is that you think > you need unsafePerformIO for? Maybe it can be done without it? It really should be a list Rule that we don't mention unsafePerformIO to newbies. It should be obvious from the post that unsafePerformIO is *not* what the poster wants, so telling them about it will just confuse them. The wiki pointer is much more useful. (and the ghost of Launchbury whispers in my ear that this is the Haskell list, and "unsafePerformIO is not Haskell"!). --KW 8-) From knarf at bka-inc.com Fri Jun 11 09:50:26 2004 From: knarf at bka-inc.com (Frank Seaton Taylor) Date: Fri Jun 11 09:49:10 2004 Subject: [Haskell] IO question In-Reply-To: References: Message-ID: <4B4568FA-BBAE-11D8-ABAA-000393B0273A@bka-inc.com> On 11 Jun 2004, at 08:50, Keith Wansbrough wrote: >> On Fri, Jun 11, 2004 at 01:23:11PM +0200, Tom Hofte wrote: >>> I want to have a function that unpack an IO. >>> I should have the type: IO a -> a. >>> Is this possible? >> >> There is unsafePerformIO, but before you use it, think - do you >> really, really want to use it and you really, really know what the >> consequences can be? Perhaps you could tell us what it is that you >> think >> you need unsafePerformIO for? Maybe it can be done without it? > > > It really should be a list Rule that we don't mention unsafePerformIO > to newbies. It should be obvious from the post that unsafePerformIO > is *not* what the poster wants, so telling them about it will just > confuse them. The wiki pointer is much more useful. > > (and the ghost of Launchbury whispers in my ear that this is the > Haskell list, and "unsafePerformIO is not Haskell"!). John is dead?!?!?! I guess it's obvious now that someone has implied it. It's seems that every time he's seen me of late, he wore an expression of great pain, bordering on a rictus. Further, consider that not one of the Galois ( http://www.galois.com ) pages has a photo of him and his OGI page ( http://www.cse.ogi.edu/~jl ) advertises "Warning: This page is out of date". Indeed, on the latter page, his visage lacks any sign of animation. Furthermore, it is a closely guarded secret that Oregonian Oxford Alumni are always interred in their symbolic color, eggplant. Now couple this with the most recent issue of the Onion ( http://www.theonion.com/ ). Notice the second photo in the middle column is obviously a young John Launchbury. (This is clearer in the small picture, the larger one within the article has been discernibly retouched.) The accompanying story is about a young man committing suicide. Coincidence? Or maybe this is all a ploy to boost sales. Those Galois fellows have a reputation for being clever. (Hmm... perhaps Wansbrough is a stock holder?) ---knarF P.S. Perhaps on the Haskell wiki we could start a page along the lines of: http://www.angelfire.com/ct/scrmgdasys/ From Keith.Wansbrough at cl.cam.ac.uk Fri Jun 11 10:09:46 2004 From: Keith.Wansbrough at cl.cam.ac.uk (Keith Wansbrough) Date: Fri Jun 11 10:08:26 2004 Subject: [Haskell] IO question In-Reply-To: Your message of "Fri, 11 Jun 2004 09:50:26 EDT." <4B4568FA-BBAE-11D8-ABAA-000393B0273A@bka-inc.com> Message-ID: > > (and the ghost of Launchbury whispers in my ear that this is the > > Haskell list, and "unsafePerformIO is not Haskell"!). > > John is dead?!?!?! Not to my knowledge, just not on the mailing list... --KW 8-) -- Keith Wansbrough http://www.cl.cam.ac.uk/users/kw217/ University of Cambridge Computer Laboratory. From GK at ninebynine.org Fri Jun 11 10:22:38 2004 From: GK at ninebynine.org (Graham Klyne) Date: Fri Jun 11 10:26:53 2004 Subject: [Haskell] IO question In-Reply-To: <000801c44fa6$7b3fca00$37ae9182@ddns.htc.nl.philips.com> Message-ID: <5.1.0.14.2.20040611152056.02d0dc30@127.0.0.1> At 13:23 11/06/04 +0200, Tom Hofte wrote: >Hi, > >I have an question about the IO monad > >I want to have a function that unpack an IO. >I should have the type: IO a -> a. >Is this possible? Possible, but... in addition to other responses, I'd also recommend looking at this: http://www.nomaware.com/monads/html/laws.html#nowayout If you can get computed values out the IO monad, you have the potential to seriously break many things. #g -- ------------ Graham Klyne For email: http://www.ninebynine.org/#Contact From simonpj at microsoft.com Fri Jun 11 11:32:10 2004 From: simonpj at microsoft.com (Simon Peyton-Jones) Date: Fri Jun 11 11:30:08 2004 Subject: [Haskell] Errata to the Revised Haskell 98 Report Message-ID: <4B93206CA3C55D4F96A61C9B1DC80DE3014185C7@EUR-MSG-03.europe.corp.microsoft.com> Gentle Haskellers It's pleasing that there have been so few bug reports about the Revised Haskell 98 report, which was published in January 2003. But there have been some: see http://research.microsoft.com/~simonpj/haskell98-revised/haskell98-revis ed-bugs.html and every now and again another one comes up. Malcolm Wallace has kindly agreed to take over custody of this errata list. There's no current plan to do more than keep a list of errors, but if any genuine ambiguities are found, he'll start a discussion to try to nail them down. Thanks Malcolm! Simon From Ben.Yu at combined.com Fri Jun 11 19:52:22 2004 From: Ben.Yu at combined.com (Ben.Yu@combined.com) Date: Fri Jun 11 19:54:21 2004 Subject: [Haskell] Annoying naming clashes Message-ID: Hi, when writing haskell code. It is so annoying that name clashes keep happening. I have to be careful about the data constructor names, about the class names, about the class member names. I understand that we can use class to achieve some overloading effect. However, it does not help with data constructors. And, what's more important, it looks like Haskell does not allow two classes sharing methods of the same name. And that is something I deemed the most annoying. No matter how powerful type class is compared to Java interfaces, the naming problem just makes it so inconvinient. I'm a programmer who can be so easily affected by ethetics of the program. And when I have to keep worrying about "should I use this name? it may have been used in a similar class", the precious peace in mind is gone. As a novice haskell programmer, I might be missing something here though. If somebody can kindly give me some instruction of how to work with names, appreicate it a lot! Ben. This message is intended only for the addressee and may contain information that is confidential or privileged. Unauthorized use is strictly prohibited and may be unlawful. If you are not the intended recipient, or the person responsible for delivering to the intended recipient, you should not read, copy, disclose or otherwise use this message, except for the purpose of delivery to the addressee. If you have received this email in error, please delete and advise us immediately. From b.i.mills at massey.ac.nz Fri Jun 11 21:35:25 2004 From: b.i.mills at massey.ac.nz (b.i.mills@massey.ac.nz) Date: Fri Jun 11 21:34:03 2004 Subject: [Haskell] IO question Message-ID: <200406120135.i5C1ZP113565@it012687.massey.ac.nz> While what I want to say has implicitly been said I'd just like to suggest that there is a simple way to put the whole matter less cryptically. The "obvious" question that just about anyone starting with the IO monad asks is how can I write (IO a -> a)? The "simple" answer is, you don't have to because you can use (>>=) with something (a -> b) to write (IO a -> IO b). That is, if you are dealing with an IO operation, you must always think in terms of the complete read-modify-write sequence. This requires you to think explicitly about the temporal nature of your code, but I see the strength of the IO monad as being exactly that, it forces you to be explicit. For me writing (IO a -> a) is logically non-sensical, you have just broken the semantics of IO, that's all. I know what (IO a -> a) is, because I know that the Haskell language is not the whole universe. But, it is like *(int *)(&x) in C, the meaning depends on the implimentation of the language, outside the semantics of the language per se. Regards, Bruce. From tpledger at ihug.co.nz Fri Jun 11 22:27:25 2004 From: tpledger at ihug.co.nz (Tom Pledger) Date: Fri Jun 11 22:20:33 2004 Subject: [Haskell] Annoying naming clashes References: Message-ID: <40CA6A0D.70609@ihug.co.nz> Ben.Yu@combined.com wrote: >Hi, when writing haskell code. It is so annoying that name clashes keep >happening. > >I have to be careful about the data constructor names, about the class >names, about the class member names. > >[...] > >As a novice haskell programmer, I might be missing something here though. >If somebody can kindly give me some instruction of how to work with names, >appreicate it a lot! > Hi. Try using small modules and qualified names. module Illumination where data Illumination = Dark | Light module Weight where data Weight = Heavy | Light module UseBoth where import Illumination import Weight easyToCarry = (Illumination.Light, Weight.Light) Regards, Tom From gk at ninebynine.org Mon Jun 14 09:34:51 2004 From: gk at ninebynine.org (Graham Klyne) Date: Mon Jun 14 09:32:38 2004 Subject: [Haskell] IO, exceptions and error handling Message-ID: <5.1.0.14.2.20040614131259.00bd7e70@127.0.0.1> I'm finding that a recurring theme in my work with Haskell libraries (and in particular the XML libraries) is the awkwardness of handling errors outside the IO monad. While it's often very easy to write some code that performs some function, assuming that the inputs are valid, as soon as code is required to deal with incorrect input, life gets more complicated. The choice seems to be that the functions have to be re-modelled to return a value that incorporates a possible error condition, or any such error condition results in a failure of the calling program, removing the the calling program's option to effect a recovery strategy. The exception handling system made available in the IO monad is one way out of this awkwardness, but it's only available when the recovery code is coded to run in the I/O monad (or by using unsafePerformIO). I find this is problematic when I'm trying to write a general purpose library that uses some other general-purpose library that can raise errors. I can't see any fundamental reason why exception handling has to occur in the IO monad. E.g. I'm not aware that something like this would break the Haskell type assurances: class (Eq e, Show e, Show v) => Exception e v where makeExcept :: v -> e catchExcept :: a -> (e->a) -> a throw :: e -> a instance Exception IOError String where makeExcept = userError catchExcept = catch throw e = error (show e) -- for Haskell implementations that allow errors -- to be caught in the IO monad I think a limited implementation may be possible using unsafePerformIO: data MyException = MyException String showEx (MyException s) = s instance Exception MyException String where makeExcept = MyException catchExcept a h = unsafePerformIO $ catch (return a) throw e = fail (showEx e) ... Another approach that occurs to me is to introduce an error Monad along the lines of that described by Philip Wadler as "E" in his "Essence of functional programming" paper [1]. (Or just use Either as an error monad?, which is part of what I've been doing with my XML work.) The disadvantages I see here are: (a) it requires existing code to be modified to return the error monad value. (b) it imposes a strict sequencing on the order of computation, which as far as I can see is not necessary to achieve the required error handling. For example, a computation that returns a result that is not actually used in a subsequent computation would still cause an exception; e.g. do { b <- f1 -- False ; c <- f2 -- raises exception ; d <- f3 -- value required ; return (if b then c else d) } (I know this could be coded differently to avoid the claimed problem, but to my mind it still illustrates unnecessary complexity compared with: if f1 then f2 else f3 In effect, it requires the programmer to figure out the lazy evaluation sequences instead of letting the Haskell system do it.) ... I'll note that I have reservations about using exception handling in imperative languages (because it disrupts the normal guarantees of execution flow), but I can't see any corresponding disadvatages to using exceptions in a purely functional language environment. Are there any plans or thoughts for introducing more widely usable exception handling in "Haskell 2"? #g -- [1] http://homepages.inf.ed.ac.uk/wadler/papers/essence/essence.ps and others, linked from: http://homepages.inf.ed.ac.uk/wadler/topics/monads.html (cf. section 2.3) ------------ Graham Klyne For email: http://www.ninebynine.org/#Contact From Keith.Wansbrough at cl.cam.ac.uk Mon Jun 14 09:46:37 2004 From: Keith.Wansbrough at cl.cam.ac.uk (Keith Wansbrough) Date: Mon Jun 14 09:44:28 2004 Subject: [Haskell] IO, exceptions and error handling In-Reply-To: Your message of "Mon, 14 Jun 2004 14:34:51 BST." <5.1.0.14.2.20040614131259.00bd7e70@127.0.0.1> Message-ID: > I can't see any fundamental reason why exception handling has to occur in > the IO monad. Read the paper _A Semantics for Imprecise Exceptions_. The problem is that the evaluation order of Haskell would have to be fixed for this not to lose referential transparency. What is the value of catchExcept (show (makeExcept "E1" + makeExcept "E2")) (\x -> x) ? Haskell wouldn't be "purely functional" any more. http://research.microsoft.com/~simonpj/Papers/imprecise-exn.htm --KW 8-) -- Keith Wansbrough http://www.cl.cam.ac.uk/users/kw217/ University of Cambridge Computer Laboratory. From duncan.coutts at worcester.oxford.ac.uk Mon Jun 14 10:57:02 2004 From: duncan.coutts at worcester.oxford.ac.uk (Duncan Coutts) Date: Mon Jun 14 10:55:07 2004 Subject: [Haskell] IO, exceptions and error handling In-Reply-To: <5.1.0.14.2.20040614131259.00bd7e70@127.0.0.1> References: <5.1.0.14.2.20040614131259.00bd7e70@127.0.0.1> Message-ID: <1087225021.6812.11.camel@localhost> On Mon, 2004-06-14 at 14:34, Graham Klyne wrote: > I'm finding that a recurring theme in my work with Haskell libraries (and > in particular the XML libraries) is the awkwardness of handling errors > outside the IO monad. With GHC You can throw exceptions in pure code but may only catch them in the IO monad. As Keith pointed out this is because the language would not be referentially transparent if you could catch exception in 'pure' code. This is often enough in most situations. If you need to catch the exceptions too then you'll want an error monad of some sort. Duncan From Ben.Yu at combined.com Mon Jun 14 11:06:30 2004 From: Ben.Yu at combined.com (Ben.Yu@combined.com) Date: Mon Jun 14 11:08:32 2004 Subject: [Haskell] Annoying naming clashes In-Reply-To: <40CA6A0D.70609@ihug.co.nz> Message-ID: Tom, Then what will you do when naming operations in a class? Is it right that care has to be taken in order not to conflict with other classes? Say, I have a Person class where I want to define an operation "getName". Is it wise to name it "getPersonName" instead? I notice that FiniteMap always names operations and functions xxxFM, although that looks ugly to me. Is that a general good thing to do when naming operations? Ben. Tom Pledger cc: haskell@haskell.org Sent by: Subject: Re: [Haskell] Annoying naming clashes haskell-bounces@h askell.org 06/11/2004 09:27 PM Ben.Yu@combined.com wrote: >Hi, when writing haskell code. It is so annoying that name clashes keep >happening. > >I have to be careful about the data constructor names, about the class >names, about the class member names. > >[...] > >As a novice haskell programmer, I might be missing something here though. >If somebody can kindly give me some instruction of how to work with names, >appreicate it a lot! > Hi. Try using small modules and qualified names. module Illumination where data Illumination = Dark | Light module Weight where data Weight = Heavy | Light module UseBoth where import Illumination import Weight easyToCarry = (Illumination.Light, Weight.Light) Regards, Tom _______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell This message is intended only for the addressee and may contain information that is confidential or privileged. Unauthorized use is strictly prohibited and may be unlawful. If you are not the intended recipient, or the person responsible for delivering to the intended recipient, you should not read, copy, disclose or otherwise use this message, except for the purpose of delivery to the addressee. If you have received this email in error, please delete and advise us immediately. From timothy.docker at macquarie.com Mon Jun 14 10:39:32 2004 From: timothy.docker at macquarie.com (Tim Docker) Date: Mon Jun 14 11:57:41 2004 Subject: [Haskell] IO, exceptions and error handling Message-ID: <7F3CFECC66117548BE71E9D7CD2EFB50434AB9@nt_lon_exm01.pc.internal.macquarie.com> Keith Wansbrough wrote: > Read the paper _A Semantics for Imprecise Exceptions_. The > problem is that the evaluation order of Haskell would have to > be fixed for this not to lose referential transparency. What > is the value of > > catchExcept (show (makeExcept "E1" + makeExcept "E2")) > (\x -> x) > > ? Haskell wouldn't be "purely functional" any more. As Graham Klyne indicated in a previous mail, in practice there are two ways of dealing with errors in purely functional code: - capture possible errors in the result type. This will probably force the use of a monad, with the subsequent sequencing of operation and coding style. - throw an exception, and hence be unable to recover from errors outside the IO monad. Both of these approaches seem fairly "invasive" in their effect on the code. Are people using haskell for real world tasks happy with having to choose from these? The former is more general, but any function that needs to be able to fail or propagate failure will end up being a do {} block. Tim From stefano.bistarelli at iit.cnr.it Mon Jun 14 11:56:45 2004 From: stefano.bistarelli at iit.cnr.it (Stefano Bistarelli) Date: Mon Jun 14 11:57:42 2004 Subject: [Haskell] Soft2004 workshop CFP Message-ID: <025f01c45228$321f5460$5f633092@bistarelli> ============================================================================ ======= 6th International Workshop on Soft Constraints and Preferences September 27th, 2004 Toronto, Canada Held in conjunction with 10th International Conference on Principles and Practice of Constraint Programming, CP2004 http://www.sci.unich.it/~bista/organizing/soft-2004/ ============================================================================ ======== Call for Paper ============================================================================ ======== Preferences are ubiquitous in real life: most problems are over-constrained and would not be solvable if we insist that all their requirements are strictly met. Moreover, many problems are more naturally described via preference rather than hard statements. Soft constraints are the way the constraint community has extended his classical framework to deal with the conceept of preferences. However, other frameworks for expressing preferences have been proposed in the last few years in AI or related disciplines, with different features and leading to different results. For example, both qualitative and quantitative preference frameworks are being studied and used to model and solve real-life probleems. This workshop would like to bring together researchers interested in all aspects of preferences and soft constraints, such as: - theoretical frameworks - problem modeling - solving algorithms - languages - preference aggregation - preference elicitation - multi-objective or qualitative optimization - combining/integrating different frameworks and algorithms - comparative studies - real-life applications Submissions This workshop is intended to build on the experience and success of the workshops on soft constraints that have been held at CP99, CP2000, CP2001, CP2002 and CP2003, and on the AAAI 2002 workshop on preferences in AI and CP. Its aim is to provide a forum where researchers currently working in the area of preferences or soft constraints can discuss their most recent ideas and developments and think together about the most promising new directions. Therefore we encourage the presentation of work in progress or on specialized aspects of soft constraints. Papers that bridge the gap between theory and practice are especially welcome. Prospective attendees can submit a paper, which can be up to 15 pages in length. We encourage authors to submit papers electronically in postscript or pdf format. Papers should be formatted using the Lecture Notes in Computer Science (LNCS) style. Please send your submissions by email to stefano.bistarelli@iit.cnr.it using the subject line Soft-2004 Workshop Submission. Although no agreement is yet in place, we will consider the publication of a selection of papers presented at this workshop in a special issue of a journal or in a volume of a serie. Important Dates The proposed schedule of important dates for the workshop is as follows: Paper Submission deadline June 26th Notification of acceptance July 24th Camera-ready version deadline August 14th Workshop Date September 27th Workshop Organizers: Stefano Bistarelli (Primary Contact) Dipartimento di Scienze Universit? degli studi "G. D'Annunzio" di Chieti-Pescara, Italy Email: bista@sci.unich.it Web: http://www.sci.unich.it/~bista/ and Istituto di Informatica e Telematica C.N.R. Pisa, Italy Email: stefano.bistarelli@iit.cnr.it and Francesca Rossi Dipartimento di Matematica Pura ed Applicata Universita' degli Studi di Padova, Italy Email: frossi@math.unipd.it Web: http://www.math.unipd.it/~frossi/ Program Committee: Stefano Bistarelli (University of Pescara, Italy --- C.N.R., Pisa, Italy) Simon De Givry (Institut National de La Recherche Agronomique, Castanet Tolosan Cedex, France) Boi Faltings (EPFL, Switzerland) Carmen Gervet (IC-Parc, Imperial College, UK) Ulrich Junker (ILOG, France) Javier Larrosa (Universitat Polit?cnica de Catalunya, UPC, Barcelona, Spain) Jimmy H. M. Lee (The Chinese University of Hong Kong, Hong Kong) Pedro Meseguer (IIIA-CSIC, Bellaterra, Spain) Barry O'Sullivan (University College Cork, Ireland) Francesca Rossi (University of Padova, Italy) Thomas Schiex (Institut National de La Recherche Agronomique, Castanet Tolosan Cedex, France) Toby Walsh (Cork Constraints Computation Centre, Ireland) From mark at chaos.x-philes.com Mon Jun 14 12:03:04 2004 From: mark at chaos.x-philes.com (Mark Carroll) Date: Mon Jun 14 12:01:22 2004 Subject: [Haskell] IO, exceptions and error handling In-Reply-To: References: Message-ID: On Mon, 14 Jun 2004, Keith Wansbrough wrote: (snip) > to lose referential transparency. What is the value of > > catchExcept (show (makeExcept "E1" + makeExcept "E2")) (\x -> x) > > ? Haskell wouldn't be "purely functional" any more. (snip) We've already had these issues raised on haskell-cafe when I've been wanting non-monadic synchronous exceptions. (-: The answer is that you evaluate all branches sufficiently to discover all the exceptions raised, and maybe have an ordering on exceptions such that you can return "answers" deterministically (as a list of ones that occurred or something). I'll be happy to follow discussion of this on haskell-cafe but will be reluctant to say much that I've already said (e.g. in December 2002's "Error Handling") for fear of boring everyone silly. -- Mark From flippa at flippac.org Mon Jun 14 12:17:17 2004 From: flippa at flippac.org (Philippa Cowderoy) Date: Mon Jun 14 12:03:41 2004 Subject: [Haskell] IO, exceptions and error handling In-Reply-To: <7F3CFECC66117548BE71E9D7CD2EFB50434AB9@nt_lon_exm01.pc.internal.macquarie.com> References: <7F3CFECC66117548BE71E9D7CD2EFB50434AB9@nt_lon_exm01.pc.internal.macquarie.com> Message-ID: On Mon, 14 Jun 2004, Tim Docker wrote: > Both of these approaches seem fairly "invasive" in their > effect on the code. Are people using haskell for real world > tasks happy with having to choose from these? The former is > more general, but any function that needs to be able to > fail or propagate failure will end up being a do {} block. > The ability to fail doesn't need the do notation, just use of return for success - similar for propagating failure. -- flippa@flippac.org From gk at ninebynine.org Mon Jun 14 10:57:54 2004 From: gk at ninebynine.org (Graham Klyne) Date: Mon Jun 14 12:07:12 2004 Subject: [Haskell] IO, exceptions and error handling In-Reply-To: References: Message-ID: <5.1.0.14.2.20040614155735.00b7da88@127.0.0.1> Now I see it. Thanks. Thanks also for the reference. Nice paper! So now where do I stand? I still think that being forced to handle exceptions in the IO monad is (sometimes) inconvenient, but I can now see why it is required for a rigorous language semantics. My problem relates to wanting to be able to effect some level of recovery in one library component for errors that arise in another. I thought about returning the entire set of exceptions, but I see that the implementation penalty is probably too high. I assume the suggested mapException function [sect 5.4] remains unproblematic ... is it (or some equivalent) actually implemented? I could imagine it being useful for mapping errors into a common framework; e.g. to catch exceptions from an XML parser and return a common "XML error" exception, incorporating information from the original as additional diagnostic. I think that the suggested unsafeIsException is appealing, since it allows some level of recovery action without (I think) opening up the insecurities of unsafePerformIO. The idea that the semantics of programs that do no raise exceptions is not affected is particularly appealing. #g -- At 14:46 14/06/04 +0100, Keith Wansbrough wrote: > > I can't see any fundamental reason why exception handling has to occur in > > the IO monad. > >Read the paper _A Semantics for Imprecise Exceptions_. The problem is >that the evaluation order of Haskell would have to be fixed for this not >to lose referential transparency. What is the value of > >catchExcept (show (makeExcept "E1" + makeExcept "E2")) (\x -> x) > >? Haskell wouldn't be "purely functional" any more. > >http://research.microsoft.com/~simonpj/Papers/imprecise-exn.htm > >--KW 8-) >-- >Keith Wansbrough >http://www.cl.cam.ac.uk/users/kw217/ >University of Cambridge Computer Laboratory. ------------ Graham Klyne For email: http://www.ninebynine.org/#Contact From timothy.docker at macquarie.com Mon Jun 14 12:30:54 2004 From: timothy.docker at macquarie.com (Tim Docker) Date: Mon Jun 14 12:28:52 2004 Subject: [Haskell] IO, exceptions and error handling Message-ID: <7F3CFECC66117548BE71E9D7CD2EFB50434ABA@nt_lon_exm01.pc.internal.macquarie.com> Philippa Cowderoy wrote: > The ability to fail doesn't need the do notation, just use of > return for success - similar for propagating failure. I'm not sure I understand. Do you mean writing functions like: sqr x | x < 0 = fail "less than zero" | otherwise = return (sqrt x) If so, I don't see how I can use this without either do or >>=: test x = do v1 <- sqr x v2 <- sqr (x+1) return (v1+v2) I can't (easily) write text c = sqr x + sqr (x+1) which was what I was getting at. Tim From Keith.Wansbrough at cl.cam.ac.uk Mon Jun 14 12:41:03 2004 From: Keith.Wansbrough at cl.cam.ac.uk (Keith Wansbrough) Date: Mon Jun 14 12:38:55 2004 Subject: [Haskell] IO, exceptions and error handling In-Reply-To: Your message of "Mon, 14 Jun 2004 17:30:54 BST." <7F3CFECC66117548BE71E9D7CD2EFB50434ABA@nt_lon_exm01.pc.internal.macquarie.com> Message-ID: > Philippa Cowderoy wrote: > > > The ability to fail doesn't need the do notation, just use of > > return for success - similar for propagating failure. > > I'm not sure I understand. Do you mean writing functions > like: > > sqr x | x < 0 = fail "less than zero" > | otherwise = return (sqrt x) s/fail/error/ s/return// Then you can easily write > I can't (easily) write > > text c = sqr x + sqr (x+1) You just can't *catch* this outside the IO monad. --KW 8-) -- Keith Wansbrough http://www.cl.cam.ac.uk/users/kw217/ University of Cambridge Computer Laboratory. From timothy.docker at macquarie.com Mon Jun 14 12:50:39 2004 From: timothy.docker at macquarie.com (Tim Docker) Date: Mon Jun 14 12:48:37 2004 Subject: [Haskell] IO, exceptions and error handling Message-ID: <7F3CFECC66117548BE71E9D7CD2EFB50434ABB@nt_lon_exm01.pc.internal.macquarie.com> Keith Wansbrough wrote: > s/fail/error/ > s/return// > > Then you can easily write > > > I can't (easily) write > > > > text c = sqr x + sqr (x+1) > > You just can't *catch* this outside the IO monad. Of course... that was my second alternative error strategy. I'm interest in how/when people decide when to throw exceptions versus when to thread errors using monads, given that changing code from one to the other could be quite a big deal. Tim From alastair at reid-consulting-uk.ltd.uk Mon Jun 14 12:57:46 2004 From: alastair at reid-consulting-uk.ltd.uk (Alastair Reid) Date: Mon Jun 14 12:55:48 2004 Subject: [Haskell] IO, exceptions and error handling In-Reply-To: <5.1.0.14.2.20040614155735.00b7da88@127.0.0.1> References: <5.1.0.14.2.20040614131259.00bd7e70@127.0.0.1> <5.1.0.14.2.20040614155735.00b7da88@127.0.0.1> Message-ID: <200406141757.46450.alastair@reid-consulting-uk.ltd.uk> > I assume the suggested mapException function [sect 5.4] remains > unproblematic ... is it (or some equivalent) actually implemented? http://etudiants.insia.org/~jbobbio/pafp/docs/base/Control.Exception.html#v% 3AmapException The same page has a host of other useful operations. Two useful capabilities that are missing in the actual implementation are: 1) Provision for routinely adding filename and line number. (Of course, we'd need some kind of compiler support for filling that info in.) data Exception = ... | Location SrcLoc Exception | ... 2) The ability to build up lists of exceptions perhaps by adding something like: data Exception = ... | Nested Exception Exception | ... This would allow handlers to build 'stacks' of exceptions rather like the stackdumps Java exceptions produce. For example: foo x = mapException (Nested (ErrorCall "while in foo")) $ bar x bar x = mapException (Nested (ErrorCall "while in bar")) $ baz x baz x = 1/x foo 0 ==> Nested (ErrorCall "while in foo") (Nested (ErrorCall "while in bar") (ArithException DivideByZero)) [Alternate names for 'Nested' welcome. `WhileDoing` is my next best attempt :-)] -- Alastair Reid From cwitty at newtonlabs.com Mon Jun 14 15:28:26 2004 From: cwitty at newtonlabs.com (Carl Witty) Date: Mon Jun 14 15:26:21 2004 Subject: [Haskell] Programming language shootout (completing the Haskell entry) In-Reply-To: <200403261739.33169.haskell@ser.fdns.net> References: <200403261626.31692.haskell@ser.fdns.net> <1080338644.1505.11.camel@flare> <200403261739.33169.haskell@ser.fdns.net> Message-ID: <1087241305.24262.1.camel@flare> On Fri, 2004-03-26 at 14:39, Sean E. Russell wrote: > On Friday 26 March 2004 17:04, Carl Witty wrote: > > Are you aware of this: > > > > 2001-12-12 > > * Due to wanting to get on with other things, I'm freezing the > > shootout as is, with no further updates planned. It isn't > > complete, just abandoned (for now). > > Nope. Didn't see it. But, heck... all of the sources are available, > including build files... maybe if I ask him he'll send me the CGIs that > generate the page, too. > > > (from http://www.bagley.org/~doug/shootout/news.shtml)? So it's > > unlikely that your updates would get on to the official shootout page... > > Someday, they might :-) Well, it looks like the Shootout has been revived. The revival was announced by Brent Fulgham on June 7; the new site is at http://shootout.alioth.debian.org/ . Carl Witty From john at repetae.net Mon Jun 14 18:43:20 2004 From: john at repetae.net (John Meacham) Date: Mon Jun 14 18:41:08 2004 Subject: [Haskell] IO, exceptions and error handling In-Reply-To: References: <7F3CFECC66117548BE71E9D7CD2EFB50434ABA@nt_lon_exm01.pc.internal.macquarie.com> Message-ID: <20040614224319.GA2378@momenergy.repetae.net> On Mon, Jun 14, 2004 at 05:41:03PM +0100, Keith Wansbrough wrote: > > Philippa Cowderoy wrote: > > > > > The ability to fail doesn't need the do notation, just use of > > > return for success - similar for propagating failure. > > > > I'm not sure I understand. Do you mean writing functions > > like: > > > > sqr x | x < 0 = fail "less than zero" > > | otherwise = return (sqrt x) > > s/fail/error/ > s/return// better yet, import Control.Monad.Identity sqr' x = runIdentity (sqr x) now sqr' behaves exactly as if you used 'error' and direct code, but the monadic version is still available for those that care about it. John -- John Meacham - ?repetae.net?john? From ozone at algorithm.com.au Mon Jun 14 21:21:47 2004 From: ozone at algorithm.com.au (=?ISO-8859-1?Q?Andr=E9_Pang?=) Date: Mon Jun 14 21:20:01 2004 Subject: [Haskell] Annoying naming clashes In-Reply-To: References: Message-ID: <5EC2FECA-BE6A-11D8-8C0A-000A95BAC4AE@algorithm.com.au> On 12/06/2004, at 9:52 AM, Ben.Yu@combined.com wrote: > Hi, when writing haskell code. It is so annoying that name clashes keep > happening. > > I have to be careful about the data constructor names, about the class > names, about the class member names. > > I understand that we can use class to achieve some overloading effect. > However, it does not help with data constructors. And, what's more > important, it looks like Haskell does not allow two classes sharing > methods > of the same name. The standard response to this is "use the module system to help you". Don't export your data constructors because you then expose the internals of your module, which is bad for abstraction; export function names which serve as the data constructors instead. Use qualified module names. e.g. in the case of the Data.FiniteMap module, it has function names such as "emptyFM", "unitFM", "addToFM", etc. Don't do this, instead call those functions "empty", "unit", "add", and then a user of a module can use the module by using qualified module names: module MyModule where import Data.FiniteMap as FM foo = FM.add key elt FM.empty You can 'wrap' the current Data.FiniteMap module with your own MyFiniteMap module to achieve this affect. I think this is a far from ideal solution, but it's adequate. Google for "per-type function namespaces", which was an idea I sent to the list a few months ago, for something which I think better solves the naming issue. Quite a lot of people disagreed with it, but I still think it's a good idea. (FWIW, I nearly managed to implement this with Template Haskell, but I couldn't work around the restriction that you couldn't splice in a TH function declared in the same module.) -- % Andre Pang : trust.in.love.to.save From john at repetae.net Mon Jun 14 22:05:37 2004 From: john at repetae.net (John Meacham) Date: Mon Jun 14 22:03:25 2004 Subject: [Haskell] Annoying naming clashes In-Reply-To: <5EC2FECA-BE6A-11D8-8C0A-000A95BAC4AE@algorithm.com.au> References: <5EC2FECA-BE6A-11D8-8C0A-000A95BAC4AE@algorithm.com.au> Message-ID: <20040615020537.GB2378@momenergy.repetae.net> Another problem is that people learning haskell, especially those coming from a OO background or language like java, tend to write code that needlessly exasperates the naming conflict problem. I think this is because of the initial steps one usually takes in other languages, the first thing one types when writing java or other OO languages tends to be something like 1. define the data structures you think you will need or 2. define the class/interface your data structures will have (which tend to be confabulated together in OO languages) however, neither of these is a very good way to start a haskell program, for example, a novice programmer when presented with writing a simple interpreter might write out (somewhat contrived) > data Exp = Val Int | Plus Exp Exp | ... > readExp = readInt <|> readPlus > readInt = x <- do readInt ; return (Val x) > readPlus = x <- do readExp; readPlus; y <- readExp ; return (Plus x y) > interpretExp (Val x) = x > interpretExp (Plus x y) = (interpretExp x) + (interpretExp y) however an experienced haskell programmer might realize the data structure is not needed and just write > readInterpretExp = readInterpretInt <|> readInterpretPlus > readInt = do x <- readInt ; return x > readPlus = do x <- readExp; readPlus; y <- readExp ; return ( x + y) by getting rid of these needless intermediate data structures (something you learn to do intuitivly as you use haskell), one reduces the chances for naming conflicts. now classes are a bit trickier, the main thing is that classes in haskell are not like classes in other languages. A class in haskell is nothing more than a construct allowing you to reuse the same syntax on different types. (to hopefully do similar things) Very few actual applications require you to write a class. It is not that writing a class is particularly difficult or they are complicated, it is just that they are usually not needed unless you are specifically writing a reusable library. The key thing to remember when starting a haskell program is to NOT write your classes first. just write your program and if you notice that you are performing similar operations to different types, only then consider adding a class after the fact. classes should be used to clean up and refactor existing code, not as a basic building block like in OO languages.. Haskell is very malliable, it is a lot easier to observe how your algorithms are being used than to predict how beforehand. Hope this helps, of course, this is not generally applicable to all haskell programmers, it is just an observation of how I see new users of the language try to use it and perhaps get frustrated. John now, if anyone has some insight as to what the first thing you type should be when writing haskell code.. :) Perhaps haskells concisity obviates the need for these 'easy choices'. if it were trivial to know how to start a program then one might say the language is deficient for forcing you to make the easy decision anyway... but now I am rambling... -- John Meacham - ?repetae.net?john? From zednenem at psualum.com Tue Jun 15 01:00:49 2004 From: zednenem at psualum.com (David Menendez) Date: Tue Jun 15 00:58:36 2004 Subject: [Haskell] IO, exceptions and error handling In-Reply-To: <5.1.0.14.2.20040614131259.00bd7e70@127.0.0.1> Message-ID: Graham Klyne writes: > Another approach that occurs to me is to introduce an error Monad > along the lines of that described by Philip Wadler as "E" in his > "Essence of functional programming" paper [1]. (Or just use Either > as an error monad?, which is part of what I've been doing with my XML > work.) Control.Monad.Error defines a class MonadError and some instances that provide the functionality of Wadler's E monad. > The disadvantages I see here are: (a) it requires existing code to be > modified to return the error monad value. (b) it imposes a strict > sequencing on the order of computation, which as far as I can see is > not necessary to achieve the required error handling. For example, a > computation that returns a result that is not actually used in a > subsequent computation would still cause an exception; e.g. > do { b <- f1 -- False > ; c <- f2 -- raises exception > ; d <- f3 -- value required > ; return (if b then c else d) > } > (I know this could be coded differently to avoid the claimed problem, > but to my mind it still illustrates unnecessary complexity compared > with: > if f1 then f2 else f3 > In effect, it requires the programmer to figure out the lazy > evaluation sequences instead of letting the Haskell system do it.) I usually do that as: > do b <- f1 > if b then f2 else f3 It's only slightly more complex, it's lazy, and it works with any monad. But your general point is still valid. -- As for bridging errors from one library to another, if you use MonadError e m rather than a specific error monad, you can do something along these lines: > import Control.Monad.Error > > data XmlError = X1 | X2 | X3 | XOther String > deriving (Eq, Show) > > instance Error XmlError where > strMsg = XOther > > > data AppError = AppXmlError XmlError | AppOther String > deriving (Eq, Show) > > instance Error AppError where > strMsg = AppOther > > -- > > xmlFunc :: (MonadError XmlError m) > => String -> m String > xmlFunc str = throwError X1 > > > appFunc :: (MonadError AppError m) > => String -> m String > appFunc s > = do s' <- mapError AppXmlError (xmlFunc s) > return ("result: " ++ s') > > > mapError :: (MonadError e m) > => (e' -> e) -> ErrorT e' m a -> m a > mapError f m = runErrorT m >>= either (throwError . f) return > > -- n.b. runErrorT :: ErrorT e m a -> m (Either e a) > > test :: String -> Either AppError String > test = appFunc -- David Menendez From alastair at reid-consulting-uk.ltd.uk Tue Jun 15 02:35:44 2004 From: alastair at reid-consulting-uk.ltd.uk (Alastair Reid) Date: Tue Jun 15 02:33:39 2004 Subject: [Haskell] Annoying naming clashes In-Reply-To: <20040615020537.GB2378@momenergy.repetae.net> References: <5EC2FECA-BE6A-11D8-8C0A-000A95BAC4AE@algorithm.com.au> <20040615020537.GB2378@momenergy.repetae.net> Message-ID: <200406150735.45005.alastair@reid-consulting-uk.ltd.uk> > [snip: parser and interpreter for a little expression language] > > however an experienced haskell programmer might realize the data > structure is not needed and just write > > [snip: combined parser/interpreter for same language] > > by getting rid of these needless intermediate data structures (something > you learn to do intuitivly as you use haskell), one reduces the chances > for naming conflicts. I don't think I agree with that at all. John Hughes' "Why Functional Programming Matters" makes it very clear how much power you gain from adding intermediate data structures. I personally find them extremely valuable in compilers and interpreters because they help me separate the concrete syntax from the abstract syntax. Further, if the language were to evolve a little, having a separate data structure would make it possible to add typechecking or other static semantics. [I avoid name clashes using a combination of smallish modules, qualified naming and ad hoc use of prefixes and deliberate mis-spellings. The situation in Haskell isn't especially happy.] -- Alastair Reid From ketil+haskell at ii.uib.no Tue Jun 15 03:13:18 2004 From: ketil+haskell at ii.uib.no (Ketil Malde) Date: Tue Jun 15 03:11:08 2004 Subject: [Haskell] IO, exceptions and error handling In-Reply-To: <7F3CFECC66117548BE71E9D7CD2EFB50434ABB@nt_lon_exm01.pc.internal.macquarie.com> References: <7F3CFECC66117548BE71E9D7CD2EFB50434ABB@nt_lon_exm01.pc.internal.macquarie.com> Message-ID: "Tim Docker" writes: > Of course... that was my second alternative error strategy. I'm > interest in how/when people decide when to throw exceptions versus > when to thread errors using monads, given that changing code from > one to the other could be quite a big deal. I generally use 'error' for any kind of situation that shouldn't happen during normal execution. For run-time situations that can be dealt with gracefully, I use Maybe or Either, and try to deal with it as low as possible. I realize this is very simplistic, but IME, exception handling code trying to deal with all kinds of possibilities for failure often becomes very spaghettiized, just like excessive use of (the other kind of) GOTO. There are simply too many bad things that can happen, so I prefer the (Erlang?) strategy of 'letting it crash'. If I were building a large long-lived application, I would probably build subsystems using the LIC philosophy, and catch errors and restart subsystems from a monadic framework. -kzm -- If I haven't seen further, it is by standing in the footprints of giants From john at repetae.net Tue Jun 15 04:25:54 2004 From: john at repetae.net (John Meacham) Date: Tue Jun 15 04:23:44 2004 Subject: [Haskell] Annoying naming clashes In-Reply-To: <200406150735.45005.alastair@reid-consulting-uk.ltd.uk> References: <5EC2FECA-BE6A-11D8-8C0A-000A95BAC4AE@algorithm.com.au> <20040615020537.GB2378@momenergy.repetae.net> <200406150735.45005.alastair@reid-consulting-uk.ltd.uk> Message-ID: <20040615082554.GI9008@momenergy.repetae.net> On Tue, Jun 15, 2004 at 07:35:44AM +0100, Alastair Reid wrote: > I don't think I agree with that at all. > > John Hughes' "Why Functional Programming Matters" makes it very clear how much > power you gain from adding intermediate data structures. > > I personally find them extremely valuable in compilers and interpreters > because they help me separate the concrete syntax from the abstract syntax. > Further, if the language were to evolve a little, having a separate data > structure would make it possible to add typechecking or other static > semantics. > > [I avoid name clashes using a combination of smallish modules, qualified > naming and ad hoc use of prefixes and deliberate mis-spellings. The > situation in Haskell isn't especially happy.] Oh, I didn't mean to say intermediate data structures are bad, or that they should be avoided, they are quite useful and a fundamental technique of haskell programming. I just meant that people coming from different backgrounds tend not to know how or even realize that they can elide them when they are not important, which leads to a perception that the naming problem is far worse than it actually is. When you are creating the intermediate data structure for a reason, you tend to come up with good unique names anyway that deal with the algorithm or technique you are trying to express so it is less of an issue. In fact, I find this to be a useful measure when programming, if I really can't think of an appropriate name for a function or data constructor, then perhaps I should rethink why I think I need it in the first place. It is the purely intermediate data structures that have no real operations on them because they need not exist that are hard to name and lead to naming conflicts. It is these structures that haskell programers learn are not needed as their skills improve. but yeah, I love intermediate structures as much as the next haskell programmer :) John -- John Meacham - ?repetae.net?john? From waldmann at imn.htwk-leipzig.de Tue Jun 15 04:26:11 2004 From: waldmann at imn.htwk-leipzig.de (Johannes Waldmann) Date: Tue Jun 15 04:23:58 2004 Subject: [Haskell] Annoying naming clashes In-Reply-To: <20040615020537.GB2378@momenergy.repetae.net> References: <5EC2FECA-BE6A-11D8-8C0A-000A95BAC4AE@algorithm.com.au> <20040615020537.GB2378@momenergy.repetae.net> Message-ID: <40CEB2A3.8080805@imn.htwk-leipzig.de> John Meacham wrote: > 1. define the data structures you think you will need or > 2. define the class/interface your data structures will have if you want to take the "prototyping" route, then indeed do 1. first and then 2., but of course first 2. then 1. gives better code right from the start. I mean, you don't write a sort function for strings, another for doubles etc. only to discover later that you should use the Ord interface (erm, class). OTOH, if you do the complete sequence 1+2+1 then you can call it "refactoring" in order to be buzzword compliant. > however an experienced haskell programmer might realize the data > structure is not needed and just write as has been said already, the programmer should indeed *use* such structures, and it's the job of the *compiler* to figure out where and how they could be removed. as Eric Raymond puts it, "Smart data structures and dumb code works a lot better than the other way around." http://www.catb.org/~esr/writings/cathedral-bazaar/cathedral-bazaar/ar01s06.html best regards, -- -- Johannes Waldmann, Tel/Fax: (0341) 3076 6479 / 6480 -- ------ http://www.imn.htwk-leipzig.de/~waldmann/ --------- From wolfgang at jeltsch.net Tue Jun 15 05:30:24 2004 From: wolfgang at jeltsch.net (Wolfgang Jeltsch) Date: Tue Jun 15 05:28:13 2004 Subject: [Haskell] Annoying naming clashes In-Reply-To: <20040615020537.GB2378@momenergy.repetae.net> References: <5EC2FECA-BE6A-11D8-8C0A-000A95BAC4AE@algorithm.com.au> <20040615020537.GB2378@momenergy.repetae.net> Message-ID: <200406151130.25014.wolfgang@jeltsch.net> Am Dienstag, 15. Juni 2004 04:05 schrieb John Meacham: > [...] > now classes are a bit trickier, the main thing is that classes in > haskell are not like classes in other languages. A class in haskell is > nothing more than a construct allowing you to reuse the same syntax on > different types. (to hopefully do similar things) Classes are not only for reusing the same syntax but also for polymorphism. For example, the Num class doesn't exist solely for the purpose that I can use the + operator with different types. It's also for the purpose that one can, for example, define a function which sums up the elements of a list where the element type isn't restricted to one specific numeric type. I'd say, classes in Haskell are similar to interfaces in Java. > [...] Wolfgang From john at repetae.net Tue Jun 15 06:02:18 2004 From: john at repetae.net (John Meacham) Date: Tue Jun 15 06:00:04 2004 Subject: [Haskell] Annoying naming clashes In-Reply-To: <200406151130.25014.wolfgang@jeltsch.net> References: <5EC2FECA-BE6A-11D8-8C0A-000A95BAC4AE@algorithm.com.au> <20040615020537.GB2378@momenergy.repetae.net> <200406151130.25014.wolfgang@jeltsch.net> Message-ID: <20040615100218.GJ9008@momenergy.repetae.net> On Tue, Jun 15, 2004 at 11:30:24AM +0200, Wolfgang Jeltsch wrote: > Am Dienstag, 15. Juni 2004 04:05 schrieb John Meacham: > > [...] > > > now classes are a bit trickier, the main thing is that classes in > > haskell are not like classes in other languages. A class in haskell is > > nothing more than a construct allowing you to reuse the same syntax on > > different types. (to hopefully do similar things) > > Classes are not only for reusing the same syntax but also for polymorphism. > For example, the Num class doesn't exist solely for the purpose that I can > use the + operator with different types. It's also for the purpose that one > can, for example, define a function which sums up the elements of a list > where the element type isn't restricted to one specific numeric type. yes, and that summing function is a piece of reusable syntax. Whether something is a class member or built on class members is nicely abstracted away in haskell. (at least for those not creating new instances). Yeah, polymorphism is the right term, but not always the best one when trying to explain basic haskell to my impertive minded friends. I find trying to draw analogies between haskell classes and constructs in other languages to be problematic as people then try to apply knowledge from other fields incorrectly to haskell unless you give a full explanation of haskell classes anyway.. but YMMV. John -- John Meacham - ?repetae.net?john? From GK at ninebynine.org Tue Jun 15 07:05:46 2004 From: GK at ninebynine.org (Graham Klyne) Date: Tue Jun 15 07:06:16 2004 Subject: [Haskell] Annoying naming clashes In-Reply-To: <200406151130.25014.wolfgang@jeltsch.net> References: <20040615020537.GB2378@momenergy.repetae.net> <5EC2FECA-BE6A-11D8-8C0A-000A95BAC4AE@algorithm.com.au> <20040615020537.GB2378@momenergy.repetae.net> Message-ID: <5.1.0.14.2.20040615120155.02b2a008@127.0.0.1> At 11:30 15/06/04 +0200, Wolfgang Jeltsch wrote: >I'd say, classes in Haskell are similar to interfaces in Java. I started my Haskell programming with that viewpoint, but got tripped up by it. A Java interface can be used as a type in its own right, but a Haskell class cannot. For example, you can't have a list of Eq's, only a list of some type that happens to be an Eq. The different list members can't be differently-typed instances of Eq. To emulate a Java interface, I have ended up creating algebraic data types whose components are functions. (I don't claim that's a good approach to Haskell programming, just what I ended up doing.) #g ------------ Graham Klyne For email: http://www.ninebynine.org/#Contact From mai99dgf at studserv.uni-leipzig.de Tue Jun 15 09:06:54 2004 From: mai99dgf at studserv.uni-leipzig.de (Georg Martius) Date: Tue Jun 15 09:04:53 2004 Subject: [Haskell] Annoying naming clashes In-Reply-To: <5.1.0.14.2.20040615120155.02b2a008@127.0.0.1> References: <20040615020537.GB2378@momenergy.repetae.net> <5EC2FECA-BE6A-11D8-8C0A-000A95BAC4AE@algorithm.com.au> <20040615020537.GB2378@momenergy.repetae.net> <5.1.0.14.2.20040615120155.02b2a008@127.0.0.1> Message-ID: On Tue, 15 Jun 2004 12:05:46 +0100, Graham Klyne wrote: > At 11:30 15/06/04 +0200, Wolfgang Jeltsch wrote: >> I'd say, classes in Haskell are similar to interfaces in Java. > > I started my Haskell programming with that viewpoint, but got tripped up by it. > > A Java interface can be used as a type in its own right, but a Haskell > class cannot. For example, you can't have a list of Eq's, only a list of > some type that happens to be an Eq. The different list members can't be > differently-typed instances of Eq. Well, just with existential types. > To emulate a Java interface, I have ended up creating algebraic data types > whose components are functions. (I don't claim that's a good approach to > Haskell programming, just what I ended up doing.) My approach was to create an existential types for each class and instanciate it from the class like: class FooClass f where bar :: f -> Integer setBar :: Integer -> f -> f data Foo = forall f . FooClass f => Foo f instance FooClass Foo where bar (Foo f) = bar f setBar b (Foo f) = Foo $ setBar b f I am not sure if this is the way to go, but at least it works (except for read issues). The advantage I see in this approach is that I can stick all types that are instanciated from FooClass in a list and can deal with them as there would be no exitential type constructor "in the way". Cheers, Georg From Ben.Yu at combined.com Tue Jun 15 11:30:57 2004 From: Ben.Yu at combined.com (Ben.Yu@combined.com) Date: Tue Jun 15 11:32:59 2004 Subject: [Haskell] Annoying naming clashes In-Reply-To: <5EC2FECA-BE6A-11D8-8C0A-000A95BAC4AE@algorithm.com.au> Message-ID: > Don't export your data constructors because you then expose the > internals of your module, which is bad for abstraction; export function > names which serve as the data constructors instead. Actually this is another thing that I'm wondering about. it is nice to use 'maybe', 'either' functions. However, with data types with more than 2 constructors, using such function tends to be tedious than pattern match, where, you can pick specific constructors of interest. And in order to use pattern match, I have to expose my constructors. This message is intended only for the addressee and may contain information that is confidential or privileged. Unauthorized use is strictly prohibited and may be unlawful. If you are not the intended recipient, or the person responsible for delivering to the intended recipient, you should not read, copy, disclose or otherwise use this message, except for the purpose of delivery to the addressee. If you have received this email in error, please delete and advise us immediately. From esa.pulkkinen at kotiposti.net Tue Jun 15 13:38:45 2004 From: esa.pulkkinen at kotiposti.net (Esa Pulkkinen) Date: Tue Jun 15 13:36:30 2004 Subject: [Haskell] Annoying naming clashes In-Reply-To: Your message of "Tue, 15 Jun 2004 10:30:57 CDT." Message-ID: <20040615173845.KYZU4346.fep01-app.kolumbus.fi@kotiposti.net> In message , Ben.Yu@combined.com writes: >it is nice to use 'maybe', 'either' functions. However, with data types >with more than 2 constructors, using such function tends to be tedious than >pattern match, where, you can pick specific constructors of interest. > >And in order to use pattern match, I have to expose my constructors. You don't necessarily need to expose the constructors even in that case. Often you can expose functions that return 'Maybe a' for some suitably chosen 'a' instead of the constructor itself. Then you can pattern match with e.g. the following syntax: f x | Just(y) <- matchZ x = y + 1 And the Maybe monad works beautifully for combining such functions into larger pattern matchers. The point with having abstraction is to actually expose only higher level operations. Of course, this doesn't negate any other reasons you might have for exposing the constructors [e.g. if the data type is used to represent an interface], but if you want to build abstract data types, those should be at higher level of abstraction than the concrete types. -- Esa Pulkkinen From oleg at pobox.com Wed Jun 16 01:01:07 2004 From: oleg at pobox.com (oleg@pobox.com) Date: Wed Jun 16 01:02:07 2004 Subject: [Haskell] The two-class trick Message-ID: <20040616050107.BD2DAABC3@Adric.metnet.navy.mil> The two-class trick helps us indirectly write desirable multi-parameter classes with functional dependencies or overlapping. The example below happens to have both. The example illustrates that an attempt to write desired instances directly runs into problems of bad overlapping or violations of functional dependencies. The trick lets us get around those unfortunately quite common problems. Many if not all problems with overlapping instances can be solved with the general approach described in the HList paper [HList]. The paper conjectures that the overlapping instances extension itself may be unnecessary after all. The HList paper: http://www.cwi.nl/~ralf/HList/ The two-class trick still seems worth explaining because it gives an example of turning an apparent drawback of the instance selection algorithm to our advantage. In Haskell, class instances are chosen based only on the syntactic shape of the type terms in question. Specifically, instance constraints, if any, do _not_ affect the instance selection. This fact is often considered one of the major stumbling blocks to using Haskell overloading for ``logical programming''. The instance selection algorithm is somewhat akin to the selection of the appropriate function declaration clause. We can influence the selection by adding a guard -- an arbitrary boolean expression -- to a function clause. Alas, we cannot similarly influence the selection of an instance by adding a constraint. If an instance has a constraint, the latter is checked _after_ the typechecker has selected and become committed to that instance. If that constraint turns out unsatisfiable, the whole typechecking fails. There is no backtracking: the typechecker does not attempt to choose another instance. This message is the complete code. Therefore, we need preliminaries > {-# OPTIONS -fglasgow-exts #-} > {-# OPTIONS -fallow-undecidable-instances #-} > {-# OPTIONS -fallow-overlapping-instances #-} > > module DelH where > > data HNil = HNil deriving Show > data HCons a b = HCons a b deriving Show A sample heterogenous list is as follows: > l1 = HCons True $ HCons 'a' $ HCons "ab" $ HCons 'z' $ HNil The HList paper defines infix operators that make building heterogenous lists far more pleasant. Please see the HList paper [HList] for much more explanations and many more operations on heterogenous lists. Our goal here is to write a function |hdel| that deletes the first occurrence of an element of a given type from a given heterogeneous list. For example, > test1 = hdel 'x' l1 will delete the first element of the type |Char| from the list |l1|: *DelH> l1 HCons True (HCons 'a' (HCons "ab" (HCons 'z' HNil))) *DelH> test1 HCons True (HCons "ab" (HCons 'z' HNil)) The given list must contain at least one element of the desired type. Otherwise, it is a type error. We can start by writing > class HDeleteFst e l l' | e l -> l' where > hdel:: e -> l -> l' > instance HDeleteFst e (HCons e l) l where > hdel _ (HCons _ l) = l At first, the code is quite straightforward: if we see the occurrence of the desired element type in the head of |HList|, we return the tail of the list. We are tempted to write the second case (when the desired element type is not in the head of the list) as follows *> instance HDeleteFst e l l' => *> HDeleteFst e (HCons e' l) (HCons e' l') where *> hdel e (HCons e' l) = HCons e' (hdel e l) Alas, that does not work. The most general unifier of the instances HDeleteFst e (HCons e l) l and HDeleteFst e (HCons e' l) (HCons e' l') is e' -> e, l -> (HCons e l') The unifier exists, therefore, the instances do overlap. However, there is no such substitution that, when applied to the second instance makes it identical to the first, nor vice versa. So, the instances are unifiable but not comparable -- and the compiler will complain. The trick is to introduce a helper class > class HDeleteFst' e l l' | e l -> l' where > hdel':: e -> l -> l' which is in all respect similar to the first class. Now, we add a relaying instance of |HDeleteFst|: > instance HDeleteFst' e l l' => HDeleteFst e l l' where > hdel = hdel' As we can see, the two instances of our class, |HDeleteFst e (HCons e l1) l1| and |HDeleteFst e l l'| still overlap. Now, the former is strictly more specialized than the latter, because there exists a substitution |l -> (HCons e l1), l -> l1|, which, when applied to the general instance makes it identical to the former instance. GHC no longer complains because now the overlapping instances are ordered and so the compiler can choose the right one. We still need to add an instance for the new class |HDeleteFst'| > instance HDeleteFst e l l' => > HDeleteFst' e (HCons e' l) (HCons e' l') where > hdel' e (HCons e' l) = HCons e' (hdel e l) Modulo the substitution |HDeleteFst'| for |HDeleteFst| and |hdel'| for |hdel|, this is precisely the instance we wanted -- but could not write before. In writing the relaying instance of |HDeleteFst| we specifically relied on the fact that instances are chosen only on the syntactic shape of the type terms in question. The constraints (in our case, |HDeleteFst' e l l'|) are checked only after the selection is complete. From tpledger at ihug.co.nz Wed Jun 16 05:43:59 2004 From: tpledger at ihug.co.nz (Tom Pledger) Date: Wed Jun 16 05:36:42 2004 Subject: [Haskell] Annoying naming clashes References: Message-ID: <40D0165F.7070104@ihug.co.nz> Ben.Yu@combined.com wrote: >Tom, >Then what will you do when naming operations in a class? Is it right that >care has to be taken in order not to conflict with other classes? > >Say, I have a Person class where I want to define an operation "getName". >Is it wise to name it "getPersonName" instead? > Class method names support the small-modules-and-qualified-names approach too. module C1 where class C1 a where c :: Int -> a module C2 where class C2 a where c :: Int -> a module UseBoth where import C1 import C2 f i = (C1.c i, C2.c i) This can cause trouble if you use C1 extensively without C2, and *then* import C2: you'd have to change a lot of unqualified c to C1.c. But when you're using C1 in the first place, you can guess whether you should write C1.c in anticipation of clashes. >I notice that FiniteMap always names operations and functions xxxFM, >although that looks ugly to me. Is that a general good thing to do when >naming operations? > It's not my preferred approach, but opinions vary. Regards, Tom From tpledger at ihug.co.nz Wed Jun 16 06:04:37 2004 From: tpledger at ihug.co.nz (Tom Pledger) Date: Wed Jun 16 05:57:20 2004 Subject: [Haskell] Annoying naming clashes References: <5EC2FECA-BE6A-11D8-8C0A-000A95BAC4AE@algorithm.com.au> <20040615020537.GB2378@momenergy.repetae.net> <200406151130.25014.wolfgang@jeltsch.net> <20040615100218.GJ9008@momenergy.repetae.net> Message-ID: <40D01B35.6070802@ihug.co.nz> John Meacham wrote: >[...] > >I find trying to draw analogies between haskell classes and constructs >in other languages to be problematic as people then try to apply >knowledge from other fields incorrectly to haskell unless you give a >full explanation of haskell classes anyway.. but YMMV. > John > In the particular case of Haskell classes and Java interfaces, I like the analogy *provided that* the Haskell class in question doesn't have a method with two occurrences of the class variable in parameter positions. For example, class Set s where empty :: (a -> a -> Ordering) -> s a insert :: s a -> a -> s a member :: s a -> a -> Bool fits nicely (until you add a union method), but Eq does not. The classes which fit the Java interface analogy are also the classes which can be rendered as explicit dictionaries instead: module Set where data Set a = Set {insert :: a -> Set a, member :: a -> Bool} module RedBlack(empty) where import Set empty :: (a -> a -> Ordering) -> Set a empty cmp = ... Importantly (IMHO), if you use an explicit dictionary instead of a class, the 'heterogeneous list of class instances' problem goes away. Regards, Tom From fluet at cs.cornell.edu Wed Jun 16 18:48:54 2004 From: fluet at cs.cornell.edu (Matthew Fluet) Date: Wed Jun 16 18:46:37 2004 Subject: [Haskell] closure of coercions with classes Message-ID: [Apologies for the slightly long setup. The guts of the question is: can one use the class system to code up the reflexive, transitive closure of a set of dynamic (but contextually implied) coercions? I'm coming to the conclusion that the answer is no, but I'm interested in a good explaination of why things don't work out.] Imagine an extension of the ST monad that gives nested scope [1]; that is, I add the following: blockST :: (forall s2. ST (s1, s2) a) -> ST s1 a liftST :: ST s1 a -> ST (s1, s2) a The first encapsulates the nested scope much as runST encapsulates the entire computation; the second imports computations from the outer scope to the inner scope. Now suppose I want to write a function that pairs the contents of two references into a new reference; furthermore, the function should be polymorphic in the scope of each of the input references, the output reference, and the final computation. That is, I'd like the type to be: pair :: STRef s1 a -> STRef s2 b -> ST s4 (STRef s3 (a, b)) The simplest definition clearly doesn't have enough polymorphism. If I write: pair v w = do a <- readSTRef v b <- readSTRef w newSTRef (v, w) then the function has the type: pair :: STRef s a -> STRef s b -> ST s (STRef s (a, b)) Now, there is no way to write pair with liftST terms that will result in sufficient polymorphism over scopes. For example, if I write: pair v w = do a <- readSTRef v b <- liftST (readSTRef w) liftST (liftST (newSTRef (v, w))) then the function has the type: pair :: STRef ((s1, s2), s3) a -> STRef (s1, s2) b -> ST (((s1, s2), s3), s4) (STRefr1 (a, b)) which isn't as general as I would like, as it imposes a particular order on the nested scopes. The only requirement is that scopes of the input refs and the output refs are nested inside the scope of the resulting computation. I can abstract the liftST applications and pass evidence that witnesses the correct scope nesting: pair :: (ST s1 a -> ST s4 a) -> (ST s2 a -> ST s4 b) -> (ST s3 (STRef s3 (a, b)) -> ST s4 (STRef s3 (a, b))) -> STRef s1 a -> STRef s2 b -> ST s4 (STRef s3 (a, b) pair lift1 lift2 lift3 v w = do a <- lift1 (readSTRef v) b <- lift2 (readSTRef w) lift3 (newSTRef (v, w)) Since evidence is really assembled from liftST terms, it is parametric in the return type. So, it make sense to give pair the more general type: pair :: (forall c. ST s1 c -> ST s4 c) -> (forall c. ST s2 c -> ST s4 c) -> (forall c. ST s3 c -> ST s3 c) -> STRef s1 a -> STRef s2 b -> ST s4 (STRef s3 (a, b)) Now, for the most part, it is obvious how to construct this evidence. My driving question is whether or not there is a way of moving it to the class system. That is, can some variation of the following be made to work: class AutoLiftST s1 s2 where autoLiftST :: ST s1 a -> ST s2 b instance AutoLiftST s1 (s1, s2) where autoLiftST = liftST pair :: (AutoLiftST s1 s4) -> (AutoLiftST s2 s4) -> (AutoLiftST s3 s4) -> STRef s1 a -> STRef s2 b -> ST s4 (STRef s3 (a, b)) pair v w = do a <- autoLiftST (readSTRef v) b <- autoLiftST (readSTRef w) autoLiftST (newSTRef (v, w)) where I could then write: test :: ST s0 (STRef s0 (Integer, Integer)) test = blockST (do v <- newSTRef 1 blockST (do w <- newSTRef 2 blockST (gpair v w))) and have the appropriate instances be derived/inferred. Note that this is basically boils down to choosing the appropriate elements from the reflexive, transitive closure of the liftST's implied by each blockST. Clearly, blindly throwing in reflexive and transitive instances of AutoLiftST leads to overlapping and undecidable instances. (OTOH, if one anticipates that blockST and liftST are operationally identity functions, then all of the instances of autoLiftST correspond to identity functions, and it doesn't matter which instance is chosen.) I've experimented with a few different attempts, but in the best case succeeded only in exhausting stack space while searching for satisfying instances. My gut feeling is that the search space is just too unconstrained; I'd be just as happy to hear a good explaination of exactly _what_ aspect of the problem makes it difficult, if not impossible. Finally, note that the type of liftST and the tuple type are just one way of connecting the inner and outer scopes. I'd actually prefer to dispense with liftST and make the evidence part of blockST. In explicit evidence style: blockST :: (forall s2. (forall b. ST s1 b -> ST s2 b) -> ST s2 a) -> ST s1 a while in the implicit evidence style: blockST :: (forall s2. AutoLiftST s1 s2 => ST s2 a) -> ST s1 a Now the atomic coercions are all implicitly introduced in the body of a blockST by the AutoLiftST s1 s2 class constraint. This leads to the interesting situation where _all_ AutoLiftST instances are of variables. On the other hand, it seem clear that within a nesting of blockST, we accumulate the constraints (AutoLiftST s1 s2, AutoLiftST s2 s3, ..., AutoLiftST sn-1 sn) and it is "obvious" how to compose AutoLiftST si sj for i <= j. [1] John Launchbury and Amr Sabry. Monadic State: Axiomatization and Type Safety. ICFP'97. From Ben.Yu at combined.com Wed Jun 16 19:00:18 2004 From: Ben.Yu at combined.com (Ben.Yu@combined.com) Date: Wed Jun 16 19:02:19 2004 Subject: [Haskell] Annoying naming clashes In-Reply-To: <5EC2FECA-BE6A-11D8-8C0A-000A95BAC4AE@algorithm.com.au> Message-ID: > Google > for "per-type function namespaces", which was an idea I sent to the > list a few months ago, for something which I think better solves the > naming issue. Quite a lot of people disagreed with it, but I still > think it's a good idea. (FWIW, I nearly managed to implement this with > Template Haskell, but I couldn't work around the restriction that you > couldn't splice in a TH function declared in the same module.) Andrei, I just skimmed through the "per-type namespace" thread. I'd say besides the ability to do overloading with type classes, I do like what they called ad-hoc polymorphism. And that is by no means the type classes can support. By "ad-hoc", we mean we don't know who the heck will create a function with the same name with whatever parameters and in whatever modules, classes. If you create a type class to mean "well, this name may be used by different module for god-knows different things", that feels awkward. And theoretically, any name can be duplicated. Do we create a class for every function names we create? And there's naming problems for type class operations too. When you create classes, how do you name operations? If you name your operation happily as "get", how are you sure that somebody else will not want to use this name for his own functions or class operations? Actually, to me, it is the naming clash for class operations that bothers me the most. For the alternatives people present so far, I don't see any of them satisfactory. 1. Use small modules. Yes. I can use small modules. But I will somewhere need to use more than one modules. And it is very possible that two names from two modules that I import clash. Also, even not able to use the same name within one module is sometimes annoying too. Split this module into 2 sub modules? I suppose modules are designed for seperating natural modules, not for seperating duplicate names. Creating a module just to get some synonym out sounds quite ad-hoc design. OO languages, on the other hand, even within the same class/interface, we have overloadings, we can create nested classes that brings its own namespace. Very rarely do I need to worry about name clashes. I can name functions as nicely as I can come up with. 2. Use qualified name. Well. that is a systematic solution. But, if I know I'll have to almost always write MySomeModule.add, I probably would want to name it "addMSM" to make it short, as what FiniteMap is doing. I like the code example that Oleg presented in your thread, and I love the Haskell type system that can even support overloading by returns, very powerful indeed. However, they are parametric polymorphism, even though they can to some extent simulate ad-hoc polymorphism, I just don't see they are the right tool to support ad-hoc polymorphism. In summary, names may seem a cosmetic issue. What is the fundamental semantics and functionality differnce between "add" and "MyModule.add" anyway? Just a few keystrokes, right? However, IMHO, naming is the very fundamental cosmetic issue, as in most programming languages. Not being able to name things freely is a big problem in my eyes. This message is intended only for the addressee and may contain information that is confidential or privileged. Unauthorized use is strictly prohibited and may be unlawful. If you are not the intended recipient, or the person responsible for delivering to the intended recipient, you should not read, copy, disclose or otherwise use this message, except for the purpose of delivery to the addressee. If you have received this email in error, please delete and advise us immediately. From djg at cs.washington.edu Wed Jun 16 20:09:35 2004 From: djg at cs.washington.edu (Dan Grossman) Date: Wed Jun 16 20:11:56 2004 Subject: [Haskell] Reminder: ICFP Poster Session In-Reply-To: <200403151020.i2FAKEKU007937@dogfish.cs.indiana.edu> References: <200403151020.i2FAKEKU007937@dogfish.cs.indiana.edu> Message-ID: <40D0E13F.5060008@cs.washington.edu> Participants for the ICFP poster session should sign up by June 30th. No additional information is required until later... -------------------------------------------------------------------- The 2004 ICFP Poster Session http://abstract.cs.washington.edu/~djg/icfp-poster.html Part of the 2004 International Conference on Functional Programming http://www.cs.indiana.edu/icfp04/ The 2004 International Conference on Functional Programming (ICFP) will include a poster session during the first day of the conference. The poster session aims to give students and professionals an opportunity to gain experience presenting technical material to the research community, and to get technical advice from leading researchers in the field. PARTICIPANT OBLIGATIONS: * Sign-up via the on-line form below by June 30, 2004. * Submit a one-page abstract summarizing the poster topic by July 15, 2004. * Register for ICFP 2004. (There is no separate poster registration beyond the on-line sign-up form.) * Prepare a poster and attend the session on September 19, 2004. In addition, participants are strongly encouraged to prepare a short article (roughly 2 or 3 pages) for peer feedback and to provide feedback for some other participants' articles. This process should improve the quality of the posters. Articles should be submitted by August 1, 2004. NUMBER OF PARTICIPANTS: * We hope to accomodate everyone wishing to participate, but may restrict participation (based on relevance and interest to the community) in the case of unmanageably high interest. * We may need to cancel the session if there is too little interest, roughly fewer than ten participants. * To ensure we know there is interest, please sign-up promptly. Somebody has to be first and there is no danger you will be the sole participant. POSTER PRESENTATIONS: In the poster session, each participant will be provided with a space for posting their diagrams and short descriptions of their research (approximately 3x6 feet, or 1x2 meters). Contact with your audience happens through casual conversation. Count on only a reasonable attention span when describing your work. Over five minutes is usually overdoing it. Prepare a list of questions that you would like help getting answered. Please feel free to direct any questions that you might have to: Dan Grossman, ICFP2004 Poster Session Chair http://www.cs.washington.edu/homes/djg From vivian.mcphail at paradise.net.nz Thu Jun 17 05:19:17 2004 From: vivian.mcphail at paradise.net.nz (Vivian McPhail) Date: Thu Jun 17 05:20:50 2004 Subject: [Haskell] Monadic Loops Message-ID: <003401c4544c$2a4c2ee0$0301a8c0@intranet> Hi, I've implemented a Neural Net simulator which needs to repeat a training loop many times. For this I used a while function: while test body = do (cond,res) <- body if (test cond) then do rs <- while test body return (res:rs) else return [res] However, when I run the program, the interpreter falls over after a few thousand iterations, running out of space. I think that this is because the Monadic implementation of the while loop actually nests functions of type (a -> M b) and there is a maximum ?stack size. Is there a better way to implement (possibly infinite) loops in Haskell? -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org//pipermail/haskell/attachments/20040617/ed4fdf9c/attachment.htm From mai99dgf at studserv.uni-leipzig.de Thu Jun 17 05:55:20 2004 From: mai99dgf at studserv.uni-leipzig.de (Georg Martius) Date: Thu Jun 17 05:55:18 2004 Subject: [Haskell] Monadic Loops In-Reply-To: <003401c4544c$2a4c2ee0$0301a8c0@intranet> References: <003401c4544c$2a4c2ee0$0301a8c0@intranet> Message-ID: Hi, On Thu, 17 Jun 2004 21:19:17 +1200, Vivian McPhail wrote: > Hi, > > I've implemented a Neural Net simulator which needs to repeat a training loop many times. It seams we are doing the same thing. I will share my one quite soon. For this I used a while function: > > while test body = do > (cond,res) <- body > if (test cond) then do rs <- while test body > return (res:rs) > else return [res] > However, when I run the program, the interpreter falls over after a few thousand iterations, running out of space. I think that this is because the Monadic implementation of the while loop actually nests functions of type (a -> M b) and there is a maximum ?stack size. Well, there is a maximum stack size. I use ghc and I can give the runtime system the stacksize it shoudld use. However I guess you real problem is not the stack itself, it is the laziness. I guess you perform every trail or epoch some weight updates. That means you are doing some kind of network transformation. Because Haskell is lazy the result of your transformations won't get evaluated until you actually force it to. In case your condition (cond) doesn't force the evaluation of all transformations you get large unevaluated stuff in you memory. > > Is there a better way to implement (possibly infinite) loops in Haskell? > I' am curious as well! Cheers, Georg -- ---- Georg Martius, Tel: (034297) 89434 ---- ------- http://www.flexman.homeip.net --------- From sholderm at students.cs.uu.nl Thu Jun 17 06:30:03 2004 From: sholderm at students.cs.uu.nl (Stefan Holdermans) Date: Thu Jun 17 06:27:44 2004 Subject: [Haskell] Annoying naming clashes In-Reply-To: Message-ID: <20040617103005.JNIF20358.amsfep12-int.chello.nl@POSEIDON> Ben, BY> it is nice to use 'maybe', 'either' functions. However, with BY> data types with more than 2 constructors, using such function BY> tends to be tedious than pattern match, where, you can pick BY> specific constructors of interest. BY> And in order to use pattern match, I have to expose my BY> constructors. Well, you've just identified the well-known trade-off between abstraction and induction. A language extension involving 'views' [4, 1, 3] has been proposed [2] to deal with this issue. Regards, Stefan [1] Warren Burton and Robert Cameron. Pattern matching with abstract data types. Journal of Functional Programming, 3(2):171-190, 1993. http://citeseer.ist.psu.edu/context/176591/0/ [2] Warren Burton, Erik Meijer, Patrick Sansom, Simon Thompson, and Philip Wadler. Views: An extension to Haskell pattern matching, 1996. http://www.haskell.org/development/views.html [3] Chris Okasaki. Views for Standard ML, 1998. 1998 ACM SIGPLAN Workshop on ML. http://citeseer.ist.psu.edu/okasaki98views.html [4] Philip Wadler. Views: A way for pattern matching to cohabit with data abstraction. In Steve Munchnik, editor, Proceedings of the 14th Symposium on Principles of Programming Languages, pages 307-312. Association for Computing Machinery, 1987. http://citeseer.ist.psu.edu/wadler87views.html From waldmann at imn.htwk-leipzig.de Thu Jun 17 06:39:28 2004 From: waldmann at imn.htwk-leipzig.de (Johannes Waldmann) Date: Thu Jun 17 06:37:09 2004 Subject: [Haskell] Monadic Loops In-Reply-To: <003401c4544c$2a4c2ee0$0301a8c0@intranet> References: <003401c4544c$2a4c2ee0$0301a8c0@intranet> Message-ID: <40D174E0.8090404@imn.htwk-leipzig.de> > while test body = do > (cond,res) <- body > if (test cond) then do rs <- while test body > return (res:rs) > else return [res] do you need the monad here? what monad is it? the problem could to be that the "return $ res: rs" can happen only after it is certain that "while test body" succeeds. so you won't even see the very first cons cell before the last one is evaluated. could you produce a (lazy) list of results instead? the garbage collector might be able to collect the list cells that are no longer needed possibly, a lazy state monad would help (if the computation of "while test body" cannot fail) > Is there a better way to implement (possibly infinite) loops in Haskell? generally, don't program your own recursions - use pre-defined combinators instead. (I like to think of this as a "higher analogon" of "don't use goto - use block structures" from imperative programming) if you need monads, have a look at sequence, sequence_, mapM, mapM_ http://www.haskell.org/onlinereport/monad.html if you can do with lists, then use iterate, fold etc. http://www.haskell.org/onlinereport/list.html best regards, -- -- Johannes Waldmann, Tel/Fax: (0341) 3076 6479 / 6480 -- ------ http://www.imn.htwk-leipzig.de/~waldmann/ --------- From listener at thaldyron.com Thu Jun 17 06:58:55 2004 From: listener at thaldyron.com (Peter Robinson) Date: Thu Jun 17 06:56:51 2004 Subject: [Haskell] Monadic Loops In-Reply-To: <40D174E0.8090404@imn.htwk-leipzig.de> References: <003401c4544c$2a4c2ee0$0301a8c0@intranet> <40D174E0.8090404@imn.htwk-leipzig.de> Message-ID: <200406171258.56032.listener@thaldyron.com> On Thursday 17 June 2004 12:39, Johannes Waldmann wrote: > > while test body = do > > (cond,res) <- body > > if (test cond) then do rs <- while test body > > return (res:rs) > > else return [res] > > do you need the monad here? what monad is it? > > the problem could to be that the "return $ res: rs" > can happen only after it is certain > that "while test body" succeeds. > so you won't even see the very first cons cell > before the last one is evaluated. See also http://haskell.org/hawiki/TailRecursive > > could you produce a (lazy) list of results instead? > the garbage collector might be able to collect > the list cells that are no longer needed > > possibly, a lazy state monad would help > (if the computation of "while test body" cannot fail) > > > Is there a better way to implement (possibly infinite) loops in Haskell? You could have a look at "Tackling the awkward squad: monadic input/output, concurrency, exceptions, and foreign-language calls in Haskell" (Simon Peyton Jones) http://research.microsoft.com/users/simonpj/papers/marktoberdorf/ where quite a few "control structures" are described. Cheers, Peter > > generally, don't program your own recursions - > use pre-defined combinators instead. > (I like to think of this as a "higher analogon" > of "don't use goto - use block structures" from imperative programming) > > if you need monads, have a look at sequence, sequence_, mapM, mapM_ > http://www.haskell.org/onlinereport/monad.html > if you can do with lists, then use iterate, fold etc. > http://www.haskell.org/onlinereport/list.html > > best regards, From bka at iist.unu.edu Thu Jun 17 07:07:19 2004 From: bka at iist.unu.edu (Bernhard K. Aichernig) Date: Thu Jun 17 07:05:38 2004 Subject: [Haskell] ICTAC 2004: Extended Deadline (5 July) Message-ID: <40D17B67.5070107@iist.unu.edu> ***** Extended Deadline (5 July) ***** ICTAC 2004 FIRST INTERNATIONAL COLLOQUIUM ON THEORETICAL ASPECTS OF COMPUTING Guiyang, China 20 - 24 September 2004 http://www.iist.unu.edu/ICTAC2004 IMPORTANT DATES Submission deadline of papers: 5 July (extended!) Notification of acceptance: 9 August Final version due: 30 August Submission deadline of tutorial proposal 21 June Notification of tutorial acceptance 12 July Tutorials 20 - 21 September Workshop 22 - 24 September AIMS AND OBJECTIVES The International Institute for Software Technology of the United Nations University (UNU-IIST) decides to found an International Colloquium on Theoretical Aspects of Computing (ICTAC). The aim of the colloquium is to bring together practitioners and researchers from academia, industry and government to present research results, and exchange experience, ideas, and solutions for their problems in theoretical aspects of computing. We believe that this will help the developing countries to strengthen their research, teaching and development in computer science and engineering, to improve the links between developing countries and developed countries, and to establish collaboration in research and education. The technical program lasts five days including two days for tutorials and three days for a workshop. We plan to organize such a colloquium every 18 months jointly with a UNU-IIST training school in a developing country, and each time there will be a theme and a focus. The school participants will also attend the technical program of the colloquium. A small registration fee will be charged to cover meals tutorial handouts and proceedings only. There will be also a limited amount of grant that participants, tutorial and workshop speakers from developing countries can apply. Application should be submitted together with their tutorial proposals or papers to the workshop. The first ICTAC will be jointly organized by the Guizhou Academy of Sciences and UNU-IIST during 20-24 September 2004. SCOPE AND TOPICS ICTAC 2004 calls for tutorials in the areas of theoretical aspects of computing including automata, languages, software engineering and formal methods and solicits research papers for the workshop related to, but not limited to, the following principal topics: * automata theory and formal languages * principle and semantics of programming languages * logics and their applications * software architectures and their description languages * software specification, refinement and verification * models of object and component system * coordination and feature interaction * integration of formal and engineering methods * service-oriented development * document-driven development * models of concurrency, security and mobility * theory of parallel, distributed and internet-based (Grid) computing * real-time and embedded systems * type and category theory in computer science SUBMISSIONS OF TUTORIAL PROPOSALS Proposals should be approximately five pages and must include the following information: * contents including abstract and syllabus/contents * duration of the tutorial (2 hours - 6 hours) * intended audience including prerequisites * biography of presenter * any special requirements (e.g., software/hardware for tool demo, software/hardware requirements for participants) Please send proposals (in postscript or PDF format) via email directly to the Program Chair Zhiming Liu at lzm@iist.unu.edu. SUBMISSIONS TO THE WORKSHOP Submissions to the workshop must not have been published or be concurrently considered for publication elsewhere. All submissions will be judged on the basis of originality, contribution to the field, technical and presentation quality, and relevance to the workshop. The ICTAC 2004 Program Committee selects original technical papers for publication in the proceedings of the workshop and envisages published the proceedings after the workshop by Springer in its Lecturer Notes in Computer Science series. Papers should be written in English and not exceed 15 pages in LNCS format: see. http://www.springer.de/comp/lncs/authors.html for details. Further information and instructions about submissions can be found on the colloquium website http://www.iist.unu.edu/ICTAC2004. Authors are strongly encouraged to use this website to submit their papers in electronic form. INVITED SPEAKERS Jose Luiz Fiadeiro (University of Leicester, UK) Jifeng He (UNU-IIST, Macao) K. Rustan M. Leino (Microsoft Research, WA, USA) Huimin Lin (Institute of Software, CAS, Beijing, China) Program Committee Chairs Keijiro Araki (Kyushu University, Japan) Zhiming Liu (UNU/IIST, Macao SAR China) Publicity Chairs Bernhard Aichernig (UNU/IIST, Macao) Dan Li (Academy of Sciences, Guizhou, China) Finance Chair Danning Li (Academy of Sciences, Guizhou, China) Organization Chair Danning Li (Academy of Sciences, Guizhou, China) Advisory Committee Dines Bjoerner (Denmark), Manfred Broy (Germany), Jose Luiz Fiadeiro (University of Leicester, UK), Jifeng He (UNU-IIST), Mathai Joseph (India), Shaoying Liu (Japan), Zhiming Liu (UNU-IIST), Jim Woodcock (UK) Program Committee Luis S. Barbosa (University of Minho, Portugal) Gabriel Baum (National University of La Plata, Argentina) Hubert Baumeister (LMU, Munich, Germany) Jonathan Bowen (London South Bank University, UK) Cristian S. Calude (University of Auckland, New Zealand) Ana Cavalcanti (University of Kent, UK) Wei Ngan Chin (NUS, Singapore) Jim Davies (Oxford University, UK) Henning Dierks (University of Oldenburg, Germany) Jin Song Dong (National University, Singapore) Wan Fokkink (CWI, the Netherlands) Michael R. Hansen (DTU, Lyngby, Denmark) James Harland (RMIT University, Melbourne, Australia) Jozef Hooman (Embedded Systems Institute, Eindhoven, the Netherlands) Guoxing Huang (ECNU, Shanghai, China) Purush Iyer (North Carolina State University, USA) Ryszard Janicki (McMaster University, Ontario, Canada,) Michael Johnson( Macquarie University, Sydney, Australia) Fabrice Kordon (University of Paris VI, France) Maciej Koutny (University of Newcastle upon Tyne, UK) Kung-Kiu Lau (Manchester University, UK) Antonia Lopes (University of Lisbon, Portugal) Jian Lu (Nanjing University, China) Andrea Maggiolo-Schettini (University of Pisa, Italy) Huaikou Miao (Shanghai University, China) Paniti Netinant (Bangkok University, Thailand) Paritosh Pandya (TIFR, Mumbai, India) Zongyan Qiu (Peking University, Beijing, China) Anders P. Ravn (Aalborg University, Denmark) Gianna Reggio (University of Genova, Italy) Riadh Robbana (LIP2/EPT, Tunisia) Augusto Sampaio (Federal Univ of Pernambuco, Recife, Brazil) Bernhard Schatz (TU Munchen, Germany) Irek Ulidowski (University of Leicester, UK) Ji Wang (National Lab for Parallel and Distributed Processing, China) Wang Yi (Uppsala University, Swiden) Jian Zhang (Institute of Software, CAS, China) Mingyi Zhang (Academic of Sciences, Guizhou, China) Hongjun Zheng (Semantics Designs Inc, USA) -- Bernhard Aichernig, Research Fellow of UNU-IIST www.iist.unu.edu/~bka ---------------------------------------------------------------------- Go to China for SEFM 2004 www.iist.unu.edu/SEFM2004 and ICTAC 2004. www.iist.unu.edu/ICTAC2004 Plan to attend ASE 2004! www.ase-conference.org See you at FM 2005 www.csr.ncl.ac.uk/fm05 From afie at cs.uu.nl Thu Jun 17 07:59:01 2004 From: afie at cs.uu.nl (Arjan van IJzendoorn) Date: Thu Jun 17 07:56:41 2004 Subject: [Haskell] Monadic Loops References: <003401c4544c$2a4c2ee0$0301a8c0@intranet> Message-ID: <11c101c45462$7af39b10$f551d383@Warcraft> Hello, Vivian uses this while function: while test body = do (cond,res) <- body if (test cond) then do rs <- while test body return (res:rs) else return [res] > However, when I run the program, the interpreter falls over after a few thousand iterations, running out of space. Maybe making it tail-recursive helps. Let me think...... untested code ahead: while test body = do res <- funnyWhile test body [] return (reverse res) funnyWhile test body revResult = do (cond, res) <- body if test cond then while test body (res:revResult) else return revResult Greetings, Arjan From gustavov at ucse.edu.ar Thu Jun 17 09:15:08 2004 From: gustavov at ucse.edu.ar (Gustavo Villavicencio) Date: Thu Jun 17 08:09:29 2004 Subject: [Haskell] Monadic Loops In-Reply-To: <200406171258.56032.listener@thaldyron.com> References: <003401c4544c$2a4c2ee0$0301a8c0@intranet> <40D174E0.8090404@imn.htwk-leipzig.de> <200406171258.56032.listener@thaldyron.com> Message-ID: <2185.200.82.81.51.1087478108.squirrel@www.ucse.edu.ar> An interesting paper on Monads and Recursion is "Merging Monads and Folds for Functional Programming" Erik Meijer and Johan Jeuring best regards, gustavo Peter Robinson said: > On Thursday 17 June 2004 12:39, Johannes Waldmann wrote: >> > while test body = do >> > (cond,res) <- body >> > if (test cond) then do rs <- while test body >> > return (res:rs) >> > else return [res] >> >> do you need the monad here? what monad is it? >> >> the problem could to be that the "return $ res: rs" >> can happen only after it is certain >> that "while test body" succeeds. >> so you won't even see the very first cons cell >> before the last one is evaluated. > See also > http://haskell.org/hawiki/TailRecursive > >> >> could you produce a (lazy) list of results instead? >> the garbage collector might be able to collect >> the list cells that are no longer needed >> >> possibly, a lazy state monad would help >> (if the computation of "while test body" cannot fail) >> >> > Is there a better way to implement (possibly infinite) loops in >> Haskell? > You could have a look at "Tackling the awkward squad: monadic > input/output, concurrency, exceptions, and foreign-language calls in > Haskell" (Simon Peyton Jones) > http://research.microsoft.com/users/simonpj/papers/marktoberdorf/ > where quite a few "control structures" are described. > Cheers, > Peter >> >> generally, don't program your own recursions - >> use pre-defined combinators instead. >> (I like to think of this as a "higher analogon" >> of "don't use goto - use block structures" from imperative >> programming) >> >> if you need monads, have a look at sequence, sequence_, mapM, mapM_ >> http://www.haskell.org/onlinereport/monad.html >> if you can do with lists, then use iterate, fold etc. >> http://www.haskell.org/onlinereport/list.html >> >> best regards, > _______________________________________________ > Haskell mailing list > Haskell@haskell.org > http://www.haskell.org/mailman/listinfo/haskell From simons at cryp.to Thu Jun 17 08:20:49 2004 From: simons at cryp.to (Peter Simons) Date: Thu Jun 17 08:18:37 2004 Subject: [Haskell] HsDNS -- asynchronous DNS resolver Message-ID: <87llimml3y.fsf@peti.cryp.to> On top of the GNU adns library, I have implemented a pretty simple-to-use DNS resolver, which hides the concurrency from the user through the use of MVars. I thought, maybe someone found this useful. You can get the source code at: http://cryp.to/hsdns/ Peter From t.zielonka at students.mimuw.edu.pl Thu Jun 17 08:41:48 2004 From: t.zielonka at students.mimuw.edu.pl (Tomasz Zielonka) Date: Thu Jun 17 08:39:31 2004 Subject: [Haskell] HsDNS -- asynchronous DNS resolver In-Reply-To: <87llimml3y.fsf@peti.cryp.to> References: <87llimml3y.fsf@peti.cryp.to> Message-ID: <20040617124148.GA3868@students.mimuw.edu.pl> On Thu, Jun 17, 2004 at 02:20:49PM +0200, Peter Simons wrote: > On top of the GNU adns library, I have implemented a pretty > simple-to-use DNS resolver, which hides the concurrency from > the user through the use of MVars. I thought, maybe someone > found this useful. You can get the source code at: > > http://cryp.to/hsdns/ You stole my project's name! Oh, well, I guess I should have released it, now I can't complain :( BTW, my library is pure Haskell. In a month or two I'll try to replace Parsec (yes, I used Parsec to decode DNS packages :) with my UArrayParser, implement full domain name resolution algorithm, think of another name, and release it. Best regards, Tom -- .signature: Too many levels of symbolic links From afie at cs.uu.nl Thu Jun 17 08:45:30 2004 From: afie at cs.uu.nl (Arjan van IJzendoorn) Date: Thu Jun 17 08:43:10 2004 Subject: [Haskell] Space behaviour & hyperseq Message-ID: <11f501c45468$f9193fd0$f551d383@Warcraft> Hello Haskellers, I supervise a student who uses Haskell for simulating neural nets. A lot of computation goes on there and the program cannot handle as many iterations as we would like. We have improved performance by a factor of more than ten by putting strictness annotations in all data types. But the problem is that there are lists within these data structures and they are not strict. By using a trick I have now found that making the whole program state strict the program gets a much better looking heap profile. The trick I use is by writing a function hyperseq and then applying it before the next iterations begins: hyperseq x y = if x==x then y else error "this is very unlikely" This is very expensive and I chose to apply the function only once every 100 iterations. This gives reasonable performance. Two questions remain: 1) Is there a more efficient definition of hyperseq that does not traverse the data structure twice? The "show" function traverses the structure once but I found it to be much slower. 2) In this application the uses of lazy evaluation are rare and easily eliminated (zip xs [1..] and so on); is there some hidden GHC option that evaluates everything strictly? I realise that this would invalidate optimisations relying on certain laws but I just wonder how difficult this would be. Somebody must have given this a thought at one point. Cheers, Arjan From afc at aber.ac.uk Thu Jun 17 09:00:44 2004 From: afc at aber.ac.uk (Amanda Clare) Date: Thu Jun 17 08:57:42 2004 Subject: [Haskell] Space behaviour & hyperseq In-Reply-To: <11f501c45468$f9193fd0$f551d383@Warcraft> References: <11f501c45468$f9193fd0$f551d383@Warcraft> Message-ID: <40D195FC.9030803@aber.ac.uk> > 1) Is there a more efficient definition of hyperseq that does not traverse > the data structure twice? The "show" function traverses the structure once > but I found it to be much slower. I think DeepSeq is what you're looking for. I've had all these problems and more and written down the advice people gave me at http://users.aber.ac.uk/afc/stricthaskell.html (DeepSeq is included as an appendix). > 2) In this application the uses of lazy evaluation are rare and easily > eliminated (zip xs [1..] and so on); is there some hidden GHC option that > evaluates everything strictly? I'd like this too. Amanda From waldmann at imn.htwk-leipzig.de Thu Jun 17 09:14:54 2004 From: waldmann at imn.htwk-leipzig.de (Johannes Waldmann) Date: Thu Jun 17 09:12:34 2004 Subject: [Haskell] Space behaviour & hyperseq In-Reply-To: <11f501c45468$f9193fd0$f551d383@Warcraft> References: <11f501c45468$f9193fd0$f551d383@Warcraft> Message-ID: <40D1994E.8000205@imn.htwk-leipzig.de> > 1) Is there a more efficient definition of hyperseq that does not traverse > the data structure twice? The "show" function traverses the structure once > but I found it to be much slower. persumably because it produces its output with (++), or with (.) and building up lots of closures (?) something like class Size s where size :: s -> Int would help. (or a class Hash ... - both are nice to have anyway in a program) (and automatic instance derivations for them would be nice as well...) > 2) In this application the uses of lazy evaluation are rare and easily > eliminated (zip xs [1..] and so on); is there some hidden GHC option that > evaluates everything strictly? I realise that this would invalidate > optimisations relying on certain laws but I just wonder how difficult this > would be. Somebody must have given this a thought at one point. It would also be interesting to find out what exactly the compiler is missing when translating your program. Ideally, it should be able to "see" that everything is strict. -- -- Johannes Waldmann, Tel/Fax: (0341) 3076 6479 / 6480 -- ------ http://www.imn.htwk-leipzig.de/~waldmann/ --------- From p.turner at computer.org Thu Jun 17 10:09:43 2004 From: p.turner at computer.org (Scott Turner) Date: Thu Jun 17 10:07:22 2004 Subject: [Haskell] Space behaviour & hyperseq In-Reply-To: <11f501c45468$f9193fd0$f551d383@Warcraft> References: <11f501c45468$f9193fd0$f551d383@Warcraft> Message-ID: <200406171009.43680.p.turner@computer.org> On 2004 June 17 Thursday 08:45, Arjan van IJzendoorn wrote: > function hyperseq and then applying it before the next iterations > begins: > hyperseq x y = if x==x then y else error "this is very unlikely" > This is very expensive The concept of DeepSeq bothers me, because usually more limited use of strictness will do the job, and sometimes total strictness can't be used. Alternatives are strictList_ and strictList as defined in the "Prelude Extensions" at http://haskell.org/hawiki/PreludeExts You could substitute seq (strictList x) y for hyperseq x y. From vivian.mcphail at paradise.net.nz Thu Jun 17 05:16:21 2004 From: vivian.mcphail at paradise.net.nz (Vivian McPhail) Date: Thu Jun 17 10:43:33 2004 Subject: [Haskell] Monadic Loops Message-ID: <001901c4544b$c18955e0$0301a8c0@intranet> Hi, I've implemented a Neural Net simulator which needs to repeat a training loop many times. For this I used a while function: while test body = do (cond,res) <- body if (test cond) then do rs <- while test body return (res:rs) else return [res] However, when I run the program, the interpreter falls over after a few thousand iterations, running out of space. I think that this is because the Monadic implementation of the while loop actually nests functions of type (a -> M b) and there is a maximum ?stack size. Is there a better way to implement (possibly infinite) loops in Haskell? -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org//pipermail/haskell/attachments/20040617/dd02458b/attachment.htm From Ben.Yu at combined.com Thu Jun 17 11:44:21 2004 From: Ben.Yu at combined.com (Ben.Yu@combined.com) Date: Thu Jun 17 11:46:24 2004 Subject: [Haskell] Monadic Loops In-Reply-To: <001901c4544b$c18955e0$0301a8c0@intranet> Message-ID: You may want to try tail-recursion version while test body = liftM reverse $ loop [] where loop acc = do (cond,res) <- body (if test cond then loop else return) (res:acc) Regards, Vivian McPhail cc: Sent by: Subject: [Haskell] Monadic Loops haskell-bounces@haske ll.org 06/17/2004 04:16 AM Hi, I've implemented a Neural Net simulator which needs to repeat a training loop many times. For this I used a while function: while test body = do (cond,res) <- body if (test cond) then do rs <- while test body return (res:rs) else return [res] However, when I run the program, the interpreter falls over after a few thousand iterations, running out of space. I think that this is because the Monadic implementation of the while loop actually nests functions of type (a -> M b) and there is a maximum ?stack size. Is there a better way to implement (possibly infinite) loops in Haskell? _______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell This message is intended only for the addressee and may contain information that is confidential or privileged. Unauthorized use is strictly prohibited and may be unlawful. If you are not the intended recipient, or the person responsible for delivering to the intended recipient, you should not read, copy, disclose or otherwise use this message, except for the purpose of delivery to the addressee. If you have received this email in error, please delete and advise us immediately. From zednenem at psualum.com Thu Jun 17 18:03:31 2004 From: zednenem at psualum.com (David Menendez) Date: Thu Jun 17 18:02:09 2004 Subject: [Haskell] Annoying naming clashes In-Reply-To: <20040617103005.JNIF20358.amsfep12-int.chello.nl@POSEIDON> Message-ID: Stefan Holdermans writes: > Well, you've just identified the well-known trade-off between > abstraction and induction. A language extension involving 'views' [4, > 1, 3] has been proposed [2] to deal with this issue. That proposal for views is eight years old. Has there been any movement towards implementing it? Did some technical obsticle arise, or have people simply been busy elsewhere? > [2] Warren Burton, Erik Meijer, Patrick Sansom, Simon Thompson, and > Philip Wadler. Views: An extension to Haskell pattern matching, 1996. > http://www.haskell.org/development/views.html -- David Menendez From john at repetae.net Thu Jun 17 18:33:46 2004 From: john at repetae.net (John Meacham) Date: Thu Jun 17 18:31:31 2004 Subject: [Haskell] Annoying naming clashes In-Reply-To: References: <20040617103005.JNIF20358.amsfep12-int.chello.nl@POSEIDON> Message-ID: <20040617223346.GD8015@momenergy.repetae.net> On Thu, Jun 17, 2004 at 06:03:31PM -0400, David Menendez wrote: > Stefan Holdermans writes: > > > Well, you've just identified the well-known trade-off between > > abstraction and induction. A language extension involving 'views' [4, > > 1, 3] has been proposed [2] to deal with this issue. > > That proposal for views is eight years old. Has there been any movement > towards implementing it? Did some technical obsticle arise, or have > people simply been busy elsewhere? I think it was a couple things, Pattern guards were introduced which were conceptually a whole lot simpler and provided a way to do many of the things views did. http://research.microsoft.com/~simonpj/Haskell/guards.html The other thing is that it is unclear whether they are a good idea, I mean, they would probably be useful to some, but as extensions go, they would be a pretty radical change to the language. Many consider the simplicity and consistancy of pattern matching a virtue. Also, the views proposal is 8 years old, I don't know if anyone has thought much about how they would interact with all the other generally accepted language extensions that have happened in the meantime. I think the moral is, don't hold your breath. and learn pattern guards, they are a really really useful and universal extension to the language. John -- John Meacham - ?repetae.net?john? From alastair at reid-consulting-uk.ltd.uk Thu Jun 17 18:55:56 2004 From: alastair at reid-consulting-uk.ltd.uk (Alastair Reid) Date: Thu Jun 17 18:53:42 2004 Subject: [Haskell] Annoying naming clashes In-Reply-To: <20040617223346.GD8015@momenergy.repetae.net> References: <20040617103005.JNIF20358.amsfep12-int.chello.nl@POSEIDON> <20040617223346.GD8015@momenergy.repetae.net> Message-ID: <200406172355.56481.alastair@reid-consulting-uk.ltd.uk> > [...] learn pattern guards, they are a really really useful > and universal extension to the language. Universal? Ah, universally implemented in GHC! -- Alastair Reid From john at repetae.net Thu Jun 17 19:02:00 2004 From: john at repetae.net (John Meacham) Date: Thu Jun 17 18:59:38 2004 Subject: [Haskell] Annoying naming clashes In-Reply-To: <200406172355.56481.alastair@reid-consulting-uk.ltd.uk> References: <20040617103005.JNIF20358.amsfep12-int.chello.nl@POSEIDON> <20040617223346.GD8015@momenergy.repetae.net> <200406172355.56481.alastair@reid-consulting-uk.ltd.uk> Message-ID: <20040617230200.GE8015@momenergy.repetae.net> On Thu, Jun 17, 2004 at 11:55:56PM +0100, Alastair Reid wrote: > > > [...] learn pattern guards, they are a really really useful > > and universal extension to the language. > > Universal? > > Ah, universally implemented in GHC! really? for some reason I thought they were in nhc and hugs. although, I must admit, I don't spend much time with these other compilers. in that case, consider this a feature request for all other haskell implementations to retroactivly make my statement true. John -- John Meacham - ?repetae.net?john? From rjmh at cs.chalmers.se Fri Jun 18 05:02:53 2004 From: rjmh at cs.chalmers.se (John Hughes) Date: Fri Jun 18 05:00:30 2004 Subject: [Haskell] Monadic Loops In-Reply-To: <003401c4544c$2a4c2ee0$0301a8c0@intranet> References: <003401c4544c$2a4c2ee0$0301a8c0@intranet> Message-ID: <40D2AFBD.6030204@cs.chalmers.se> Vivian McPhail wrote: >Hi, > >I've implemented a Neural Net simulator which needs to repeat a training loop many times. For this I used a while function: > >while test body = do > (cond,res) <- body > if (test cond) then do rs <- while test body > return (res:rs) > else return [res] >However, when I run the program, the interpreter falls over after a few thousand iterations, running out of space. I think that this is because the Monadic implementation of the while loop actually nests functions of type (a -> M b) and there is a maximum ?stack size. > > > As others have pointed out, the problem is that while is not tail recursive, so the stack frame for return (res:rs) remains on the stack during the recursive call: result, you run out of stack. However, this only happens because the monad you are using is strict -- or rather, the implementation of (>>=) is strict. If you use a monad with a lazy bind operator instead, then the recursive call will not be evaluated initially, just bound to rs, and evaluated when rs is used by the called, AFTER the return (res:rs). Result: no deep stack. The advantage of doing this is that the elements of the list are available lazily as they are constructed, and so can be consumed as they are generated. Your solution (using a strict monad), and the tail recursive solution you've been offered, both build the entire list before returning it to the caller. If you are performing many thousands of recursions, and the list points at large structures, then this may give you a problematic space leak. The ST monad comes in strict and lazy versions. Provided that's the monad you're using, or a monad built on top of it, you can switch to the lazy version just by importing Control.Monad.ST.Lazy instead of Control.Monad.ST. Documentation is here: http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control.Monad.ST.Lazy.html If you are using the IO monad, then you achieve the same effect by wrapping the recursive call in unsafeInterleaveIO from System.IO.Unsafe. That will delay its evaluation until rs is evaluated, once again AFTER the enclosing call has returned. But that is -- well -- unsafe. John Hughes PS You can read about lazy state here: http://portal.acm.org/citation.cfm?id=178246&coll=portal&dl=ACM&CFID=22769016&CFTOKEN=85305111 From jleite at di.fct.unl.pt Thu Jun 17 21:33:06 2004 From: jleite at di.fct.unl.pt (=?ISO-8859-1?Q?Jo=E3o?= Leite) Date: Fri Jun 18 05:00:44 2004 Subject: [Haskell] Last CFP: CLIMA V - 5th International Workshop on Computational Logic in Multi-Agent Systems Message-ID: <200406180133.i5I1W96J009515@ns.di.fct.unl.pt> ========================================================================== LAST CALL FOR PAPERS CLIMA V Fifth International Workshop on Computational Logic in Multi-Agent Systems September 29 and 30, 2004, Lisbon, Portugal http://centria.di.fct.unl.pt/~jleite/climaV/index.htm Submission Deadline: June 25th (abstracts due June 22nd) Springer LNCS Proceedings Co-located with JELIA'04 =========================================================================== CALL FOR PAPERS Multi-agent systems are communities of problem-solving entities that can perceive and act upon their environments to achieve their individual goals as well as joint goals. The work on such systems integrates many technologies and concepts in artificial intelligence and other areas of computing. For this reason, over recent years, the agent paradigm gained popularity in many sub-fields of computer science. A full spectrum of multi-agent systems applications have been and are being developed; from search engines to educational aids to electronic commerce and trade, e-procurement, recommendation systems, simulation and routing, to cite only some. Although commonly implemented by means of imperative languages, mainly for reasons of efficiency, the agent concept has recently increased its influence in the research and development of computational logic based systems. Computational logic provides a well-defined, general, and rigorous framework for studying syntax, semantics and procedures, for attending implementations, environments, tools, and standards, and for linking together specification and verification of properties of computational systems. The purpose of this workshop is to discuss techniques, based on computational logic, for representing, programming and reasoning about multi-agent systems in a formal way. Following the workshop on Multi-Agent Systems in Logic Programming affiliated with ICLP'99, the first CLIMA workshop took place in London, UK, affiliated with CL'2000. The 2001 edition of CLIMA, took place in Paphos, Cyprus, affiliated with ICLP'01. CLIMA'02 took place in Copenhagen, Denmark, and was affiliated with ICLP'02 and part of FLOC'02. The fourth edition of the workshop, CLIMA IV, took place in Fort Lauderdale, USA, and was co-located with LPNMR-7 and SAIM'04. We solicit unpublished papers that address formal approaches to multi-agent systems. the approaches as well as being formal must make a significant contribution to the practice of multi-agent systems. relevant techniques include, but are not limited to, the following: * logical foundations of multi-agent systems * knowledge and belief representation and updates in multi-agent systems * agent and multi-agent hypothetical reasoning and learning * extensions of logic programming for multi-agent systems * nonmonotonic reasoning in multi-agent systems * theory and practice of argumentation for agent reasoning and interaction * operational semantics and execution agent models * model checking algorithms, tools, and applications for multi-agent logics * semantics of interaction and agent communication languages * distributed constraint satisfaction in multi-agent systems * temporal reasoning for multi-agent systems * modal logic approaches to multi-agent systems * logic based programming languages for multi-agent systems * distributed theorem proving for multi-agent systems * logic based implementations of multi-agent systems * decision theory for multi-agent systems * specification and verification of formal properties of agent systems SUBMISSION INSTRUCTIONS We welcome and encourage the submission of high quality, original papers, which are not simultaneously submitted for publication elsewhere. Please refer to the workshop web pages for further instructions concerning the submission procedures. IMPORTANT DATES * Submission of Abstracts: June 22nd, 2004 * Submission of Papers: June 25th, 2004 * Notification of Acceptance: July 30th, 2004 * Final version due: September 6th, 2004 * CLIMA IV: September 29-30th, 2004 PROCEEDINGS The post-proceedings of CLIMA will be published by Springer-Verlag as a volume of the Lecture Notes on Artificial Intelligence series. PROGRAM COMMITTEE * José Alferes, New University of Lisbon, Portugal * Gerd Brewka, University of Leipzig, Germany * Jürgen Dix, Technical University of Clausthal, Germany * Klaus Fischer, DFKI, Germany * Michael Fisher, University of Liverpool, UK * James Harland, Royal Melbourne Institute of Technology, Australia * Katsumi Inoue, National Institute of Informatics, Japan * Sverker Janson, Swedish Institute of Computer Science, Sweden * Joăo Leite, New University of Lisbon, Portugal * Yves Lespérance, York University, Canada * John Jules Ch. Meyer, University of Utrecht, The Netherlands * Leora Morgenstern, IBM, USA * Wojciech Penczek, Polish Academy of Sciences, Poland * Jeremy Pitt, Imperial College, UK * Enrico Pontelli, New Mexico State University, USA * Fariba Sadri, Imperial College, UK * Ken Satoh, National Institute of Informatics, Japan * Renate Schmidt, The University of Manchester, UK * Tran Cao Son, New Mexico State University, USA * Francesca Toni, Imperial College, UK * Paolo Torroni, University of Bologna, Italy * Wiebe Van Der Hoek, University of Liverpool, UK * Makoto Yokoo, Kyushu University, Japan * Cees Witteveen, Delft University of Technology, The Netherlands WORKSHOP ORGANIZERS: * Joăo Leite, New University of Lisbon, Portugal (jleite@di.fct.unl.pt) * Paolo Torroni, University of Bologna, Italy (ptorroni@deis.unibo.it) INQUIRIES: Please send program suggestions and inquires to either of the organizers. From kfisher at research.att.com Thu Jun 17 23:40:47 2004 From: kfisher at research.att.com (Kathleen Fisher) Date: Fri Jun 18 05:00:45 2004 Subject: [Haskell] ICFP: Accepted papers Message-ID: <4925CA87-C0D9-11D8-8759-000D93C1F02E@research.att.com> I am pleased to announce that the following papers have been accepted for ICFP 2004 (http://www.cs.indiana.edu/icfp04/). In addition, Paul Graham, John Launchbury, and Ulf Wiger have graciously agreed to give invited talks. The final program will be available from the web site mid-July. Kathleen Fisher *********************************************************** Slideshow: Functional Presentations Robert Bruce Findler and Matthew Flatt Functional Morphology Markus Forsberg and Aarne Ranta Types for Path Correctness for XML Queries Dario Colazzo, Giorgio Ghelli, Paolo Mangh, and Carlo Sartiani Regular Expression Patterns Niklas Broberg, Andreas Farre, and Josef Svenningsson, Multi-return function call Olin Shivers and David Fisher Implementing Functional Logic Languages Using Multiple Threads and Stores Andrew Tolmach, Sergio Antoy, and Marius Nita Generics for the masses Ralf Hinze Scrap more boilerplate: reflection, zips, and generalised casts Ralf Laemmel and Simon Peyton Jones Making a fast curry: Push/enter vs eval/apply for higher-order languages Simon Marlow and Simon Peyton Jones Improving Static Analysis via Partial Evaluation for Embedded Languages David Herman and Philippe Meunier Searching for Deadlocks while Debugging Concurrent Haskell Programs Jan Christiansen and Frank Huch A Nanopass Infrastructure for Compiler Education Dipanwita Sarkar, Oscar Waddell, and R. Kent Dybvig Monadic Regions Matthew Fluet and Greg Morrisett Translating Dependency into Parametricity Stephen Tse and Steve Zdancewic A Type-Theoretic Foundation of Continuations and Prompts Zena Ariola, Hugo Herbelin, and Amr Sabry, Relating Models of Backtracking Mitchell Wand and Dale Vaillancourt Types, potency, and impotency: Why nonlinearity and amnesia make a type system work Peter M?ller Neergaard and Harry Mairson Numbering Matters: First Order Canonical Forms for Second-Order Recursive Types Nadji Gauthier and Fran?ois Pottier Process Logic and Duality Kohei Honda Verification of Safety Properties for Concurrent Assembly Code Dachuan Yu and Zhong Shao A Sound (and Complete) Model for Contracts Matthias Blume and David McAllester ------------------------------------------------------------ From simons at cryp.to Fri Jun 18 05:17:52 2004 From: simons at cryp.to (Peter Simons) Date: Fri Jun 18 05:15:34 2004 Subject: [Haskell] Re: HsDNS -- asynchronous DNS resolver References: <87llimml3y.fsf@peti.cryp.to> <20040617124148.GA3868@students.mimuw.edu.pl> Message-ID: <87llili5rz.fsf@peti.cryp.to> Tomasz Zielonka writes: >> http://cryp.to/hsdns/ > You stole my project's name! I have to admit that I am uncertain whether you are kidding or whether this is a serious complaint, but in case of the latter, I'll change the name to HsADNS or whatever. I can't say I am emotionally invested in how this thing is called, so if it's important to you ... let me know and I'll change it. Peter From t.zielonka at students.mimuw.edu.pl Fri Jun 18 07:09:05 2004 From: t.zielonka at students.mimuw.edu.pl (Tomasz Zielonka) Date: Fri Jun 18 06:36:28 2004 Subject: [Haskell] Re: HsDNS -- asynchronous DNS resolver In-Reply-To: <87llili5rz.fsf@peti.cryp.to> References: <87llimml3y.fsf@peti.cryp.to> <20040617124148.GA3868@students.mimuw.edu.pl> <87llili5rz.fsf@peti.cryp.to> Message-ID: <20040618110904.GA4415@students.mimuw.edu.pl> On Fri, Jun 18, 2004 at 11:17:52AM +0200, Peter Simons wrote: > Tomasz Zielonka writes: > > >> http://cryp.to/hsdns/ > > > You stole my project's name! > > I have to admit that I am uncertain whether you are kidding > or whether this is a serious complaint, but in case of the > latter, I'll change the name to HsADNS or whatever. I can't > say I am emotionally invested in how this thing is called, > so if it's important to you ... let me know and I'll change > it. I am sorry, I forgot the smiley. A bit late, but here it is: ;) Please, keep the current name. Maybe we could have two implementations behind one interface? Best regards, Tom -- .signature: Too many levels of symbolic links From john at repetae.net Fri Jun 18 06:40:05 2004 From: john at repetae.net (John Meacham) Date: Fri Jun 18 06:37:43 2004 Subject: [Haskell] ANNOUNCING: The Haskell Bookstore Message-ID: <20040618104004.GO9008@momenergy.repetae.net> The Haskell bookstore is now open :) The bookstore is an attempt to publish out-of-print books, scientific papers, and technical documentation relating to Haskell and Functional Programming in general which is not otherwise available in print. At the moment, the shop has * Simon Peyton Jones and David Lester's book on functional language implementation * The FFI specification. more titles shall be forthcoming. I am doing this as a non-profit venture, mainly because I really want some of these books in print :) So the cost is simply the printing cost plus expenses which will hopefully keep things afordable for everyone interested. the bookstore is at http://www.cafeshops.com/haskell_books and a wiki page describing it and allowing people to add to a wishlist and faq is at http://haskell.org/hawiki/HaskellBookstore I am always looking for new material, so any aid in tracking down copyright holders or orignal TeX files for anything desired would be apreciated. Plus, improving the documentation such as the GHC manual and FFI spec is doubleplusgood, as I can regularly pull down the cvs versions and keep the books up to date with the latest developments and good documentation benefits the community as a whole. Please let me know as soon as possible if anyone has any trouble with a printed version, as this is print-on-demand, I can incorporate changes to future editions right away. Oh, and I can't really afford to be sued, so if you think I am infringing on your copyright, send me a note before breaking out the lawyers and I will be happy to work something out :) John -- John Meacham - ?repetae.net?john? From GK at ninebynine.org Fri Jun 18 06:46:20 2004 From: GK at ninebynine.org (Graham Klyne) Date: Fri Jun 18 06:56:52 2004 Subject: [Haskell] Pattern guards and algebraic datatypes In-Reply-To: <20040617223346.GD8015@momenergy.repetae.net> References: <20040617103005.JNIF20358.amsfep12-int.chello.nl@POSEIDON> Message-ID: <5.1.0.14.2.20040618111030.00b888b8@127.0.0.1> At 15:33 17/06/04 -0700, John Meacham wrote: >I think it was a couple things, Pattern guards were introduced which >were conceptually a whole lot simpler and provided a way to do many of >the things views did. >http://research.microsoft.com/~simonpj/Haskell/guards.html I like that proposal. In response to: [[ Is this a storm in a teacup? Much huff and puff for a seldom-occurring situation? No! It happens to me ALL THE TIME. The Glasgow Haskell Compiler is absolutely littered with definitions like clunky. I would really welcome feedback on this proposal. Have you encountered situations in which pattern guards would be useful? Can you think of ways in which they might be harmful, or in which their semantics is non-obvious? Are there ways in which the proposal could be improved? And so on. ]] I'll say that in my programming, I would find that feature really useful. For example, in my work on Network.URI, I found I had to change the underlying data type. While I don't think this proposal would deal with the legacy problem, I do think it would make it easier to define an interface that better supports future changes. I notice some similar potential issues with the XML library I'm currently working on: the algebraic data types comprise a considerable part of the package interface, which is not always satisfactory. And a small thought: a current convenience with algebraic data types is the facility to export/import the constructors with (..) notation. I think it would be useful to extend this to accessor functions that are somehow bound to the ADT definition. Hmmm... would this make any sense?: [[ data URI = URI { uriScheme :: String , uriAuthority :: Maybe URIAuth , uriPath :: String , uriQuery :: String , uriFragment :: String } deriving Eq where scheme (URI {uriScheme=""}) = Nothing scheme (URI {uriScheme=a}) = Just a : etc. ]] The idea here being that functions declared in the 'where' block would be included in any export/import of URI(..). Then, also, some way to hide the individual field labels might also be useful to hide the internal structurte from that exposed. ... The other problem I've noticed with ADTs (which I think has been discussed before) is that field labels work like functions to access fields, but there's no corresponding mechanism for selective update using the same name. I could imagine something like: scheme :: a -> b -> (a,b) scheme a' u@(URI {uriScheme=a}) = (a,u {uriScheme=a'}) with auxiliaries: get :: (a -> b -> (a,b)) -> b -> a get f = fst . f undefined update :: (a -> b -> (a,b)) -> a -> b -> b update f a = snd . f a hence s = get scheme uri and uri' = update scheme s uri ... #g ------------ Graham Klyne For email: http://www.ninebynine.org/#Contact From colin at cs.york.ac.uk Fri Jun 18 07:21:50 2004 From: colin at cs.york.ac.uk (Colin Runciman) Date: Fri Jun 18 07:22:05 2004 Subject: [Haskell] Space behaviour & hyperseq In-Reply-To: <11f501c45468$f9193fd0$f551d383@Warcraft> References: <11f501c45468$f9193fd0$f551d383@Warcraft> Message-ID: <40D2D04E.2090501@cs.york.ac.uk> Arjan, >I supervise a student who uses Haskell for simulating neural nets. A lot of >computation goes on there and the program cannot handle as many iterations >as we would like. We have improved performance by a factor of more than ten >by putting strictness annotations in all data types. But the problem is that >there are lists within these data structures and they are not strict. By >using a trick I have now found that making the whole program state strict >the program gets a much better looking heap profile. The trick I use is by >writing a function hyperseq and then applying it before the next iterations >begins: > >hyperseq x y = if x==x then y else error "this is very unlikely" > >This is very expensive and I chose to apply the function only once every 100 >iterations. This gives reasonable performance. > >... >1) Is there a more efficient definition of hyperseq that does not traverse >the data structure twice? The "show" function traverses the structure once >but I found it to be much slower. > > I hit a similar problem with my very first Haskell application! As you say, the brute solution of comparing structures for equality with themselves is very expensive, and may be wrong if some components really should be evaluated lazily. My solution was to introduce a single-method class class Norm a where normal :: a -> Bool The intention is that 'normal' functions are defined in such a way that the result of an application 'normal x' is always true, but computing this truth guarantees that x is evaluated to at least a desired minimal extent. For example, supppose we have data Tree a b = Branch (Tree a) a (Tree a) | Leaf b we might then define instance Norm (Tree a b) where normal (Leaf _) = True normal (Branch _ _ _) = True hiding the Leaf and Branch constructors and providing instead leaf :: Norm b => b -> Tree a b leaf x | normal x = Leaf x branch :: Tree a b -> b -> Tree a b -> Tree a b branch lt x rt | normal lt && normal rt = Branch lt x rt we obtain trees that are path-strict in the branch and leaf structure, do not interfere at all with the lazy evaluation of internal labels at branches but ensure 'normal' evaluation of leaf labels. Of course there are many other possible definitions of 'normal' for trees. All sorts of clever tricks could be programmed into the normalising evaluations. But there should be no need for repeated traversals (let alone repeated double traversals, using ==) of already-evaluated structure. With a suitable instance of Norm, your hyperseq function can be redefined hyperseq :: Norm a => a -> b -> b hyperseq x y | normal x = y Regards Colin R Reference: Colin Runciman, "Tip in Haskell -- another exercise in functional programming", pp 278-292 in Proc. 1991 Glasgow Workshop on Functional Programming, Springer-Verlag, 1992. From waldmann at imn.htwk-leipzig.de Fri Jun 18 07:52:27 2004 From: waldmann at imn.htwk-leipzig.de (Johannes Waldmann) Date: Fri Jun 18 08:18:11 2004 Subject: [Haskell] Space behaviour & hyperseq In-Reply-To: <40D2D04E.2090501@cs.york.ac.uk> References: <11f501c45468$f9193fd0$f551d383@Warcraft> <40D2D04E.2090501@cs.york.ac.uk> Message-ID: <40D2D77B.6000804@imn.htwk-leipzig.de> Colin, Arjan, one further remark on >> hyperseq x y = if x==x then y else error "this is very unlikely" ... > the result of an application 'normal x' is always true ... I understand how this works, but do we agree that it looks outright ugly? We mean one thing (strictness) but we write something quite different (an "obviously useless" computation of the constant True). Can you explain this to students? Would you be proud of it? Reminds me of hacks like { int x = 42; String s = x + ""; } -- -- Johannes Waldmann, Tel/Fax: (0341) 3076 6479 / 6480 -- ------ http://www.imn.htwk-leipzig.de/~waldmann/ --------- From colin at cs.york.ac.uk Fri Jun 18 09:34:00 2004 From: colin at cs.york.ac.uk (Colin Runciman) Date: Fri Jun 18 09:36:53 2004 Subject: [Haskell] Space behaviour & hyperseq In-Reply-To: <40D2D77B.6000804@imn.htwk-leipzig.de> References: <11f501c45468$f9193fd0$f551d383@Warcraft> <40D2D04E.2090501@cs.york.ac.uk> <40D2D77B.6000804@imn.htwk-leipzig.de> Message-ID: <40D2EF48.9000208@cs.york.ac.uk> Johannes, >> the result of an application 'normal x' is always true ... > > I understand how this works, > but do we agree that it looks outright ugly? I don't see why f x | normal x = ... x ... is any more ugly than f x@(x : xs) = ... x ... or (far worse) f ~(x : xs) = ... x ... or strictness annotations, or uses of `seq`, all of which I try to avoid. I prefer to use the ordinary stuff of a programming language to achieve pragmatic ends, so far as possible, rather than adding "magical" decorations. > We mean one thing (strictness) but we write something quite different > (an "obviously useless" computation of the constant True). A 'normal' application doesn't have to mean one thing only: it is polymorphic, allowing distinct degrees of evaluation to be defined for distinct types. The result of a normal application may be "useless" but the effect of computing it can be extremely useful for pragmatic reasons. > Can you explain this to students? Would you be proud of it? I can and have explained it to students. It is nothing wonderful, but it is nothing to be ashamed of. It can even be rather elegant if used with care. Well ... that's my opinion anyway! Colin R From gour at mail.inet.hr Fri Jun 18 08:49:31 2004 From: gour at mail.inet.hr (Gour) Date: Fri Jun 18 11:14:54 2004 Subject: [Haskell] comment on language shootout Message-ID: <20040618124931.GB8111@mail.inet.hr> Any comment from some experienced Haskell programmer about the latest language shootout published on: http://shootout.alioth.debian.org/index.php regarding Haskell (ghc-6.2.1) score? Sincerely, Gour -- Gour | gour@mail.inet.hr Registered Linux User | #278493 GPG Public Key | 8C44EDCD From simonmar at microsoft.com Fri Jun 18 11:58:12 2004 From: simonmar at microsoft.com (Simon Marlow) Date: Fri Jun 18 11:55:48 2004 Subject: [Haskell] comment on language shootout Message-ID: <3429668D0E777A499EE74A7952C382D10203B6C8@EUR-MSG-01.europe.corp.microsoft.com> On 18 June 2004 13:50, Gour wrote: > Any comment from some experienced Haskell programmer about the latest > language shootout published on: > > http://shootout.alioth.debian.org/index.php > > regarding Haskell (ghc-6.2.1) score? I submitted improved versions for some of the benchmarks. My feeling is that the #1 reason for ghc being slower is usually Strings. To really do better we need a good PackedString library combined with PackedString I/O. I believe the current PackedString library is underperforming quite a bit - it's on my queue of things to look into. Cheers, Simon From swest3 at cogeco.ca Fri Jun 18 12:14:28 2004 From: swest3 at cogeco.ca (Scott West) Date: Fri Jun 18 12:11:54 2004 Subject: [Haskell] Convert Expressions to.... Message-ID: <20040618121428.1bf4c913@localhost> Hello all, I was just wondering if anyone had any ideas on how I could create an expression type to produce strings of some sort. So say I have something like (Exp a) `oper` (Exp b), is there a way I could perform some operation on each left/right expression, and then on the whole expression? What I'm ultimately seeking is a way to turn expressions into mathML, or some similar sort of formatting. Thanks for any help you can provide! Regards, Scott From ozone at algorithm.com.au Fri Jun 18 12:22:04 2004 From: ozone at algorithm.com.au (=?ISO-8859-1?Q?Andr=E9_Pang?=) Date: Fri Jun 18 12:19:42 2004 Subject: [Haskell] Re: comment on language shootout In-Reply-To: <20040618124931.GB8111@mail.inet.hr> References: <20040618124931.GB8111@mail.inet.hr> Message-ID: On 18/06/2004, at 10:49 PM, Gour wrote: > Any comment from some experienced Haskell programmer about the latest > language shootout published on: > > http://shootout.alioth.debian.org/index.php Yeah. Language shootouts are nearly worthless. (And I say that as an experienced Haskell programmer who uses and loves Objective-C and Perl for his day job, which are rather different beasts to Haskell.) I groaned when I heard that the shootout was revived, because I didn't think they'd improve on the "benchmarks" used to test the various languages, and they haven't. I can't really be bothered emailing them about the fallacies involved because it's just too tedious to explain, and I'm sure they're convinced they're doing a good deed to the world. About the only good they serve is to show programmers that there are other languages out there, which some people may like to explore. ("Oooo, what's this O'Caml language? Seems to be doing OK in the speed tests ...") They're also good for compiler implementors to find pathological speed cases in their compiler. That's about it. The reason why I think it's all a load of garbage is that a language is more than its benchmarks. Languages are complex things which you cannot measure with simple metrics such as speed, or lines of code, or memory use, combinations thereof, or some insanely complex one which some fool might dream of. No matter how many large flashing disclaimers that language shootout site has, there will be plenty of people who draw conclusions based on the data presented, just by the virtue of the data being there. ("Haskell is slow. Java is better than Perl. Prolog-based languages suck for doing anything!" Yadda yadda yadda ...). For instance, one of Haskell's greatest strengths is that its type system catches so many errors at compile-time that a programs often behaves as intended if it compiles -- certainly more often than plenty of other languages. One of Erlang's great strengths is that it's designed to be robust against bad code, has fantastic support for distributed services, and can be easily dynamically (un)loaded with new code. One of Objective-C's greatest strengths is its extensibility: one can add new methods to existing classes without needing the original source code at all, and inject new classes or override a class' methods at run-time. One of Perl's greatest strengths is built-in support for regular expressions, which makes one-shot string processing programs more trivial to write than in many other languages. One of C++'s greatest strengths is that it's C with better language support for object oriented and generic programming and coping with complexity, while sacrificing no speed. How on earth do you try to factor these things into such a language shootout? You can't. And, despite all the disclaimers on that site, despite all its good intentions, it's just going to give the wrong impression about many languages to many people. I wish that damn language shootout would be shot itself, and be banished for all eternity. -- % Andre Pang : trust.in.love.to.save From diatchki at cse.ogi.edu Fri Jun 18 13:19:33 2004 From: diatchki at cse.ogi.edu (Iavor S. Diatchki) Date: Fri Jun 18 13:17:13 2004 Subject: [Haskell] Re: comment on language shootout In-Reply-To: References: <20040618124931.GB8111@mail.inet.hr> Message-ID: <40D32425.9010907@cse.ogi.edu> hi, of course it is not a _language_ shootout, but rather _language implementation_ shootout (actually not even that..., and yes, i agree that some of the tests are silly, or even non-sensical, e.g. list processing) it still has some interesting results though. for example it points out where our libraries can be improved. as simon pointed out, the strings are one such area. another place where we seem to be slow is in conversion from strings to integers, the one test i rewrote was using "readDec" from the "Numeric" library. when i wrote my own conversion function, the program became nearly twice as fast, indicating that it was spending all its time converting. one thing i find annoying is the "implemented in the same way" restriction. i think it leads to programs, that are simillar to the "automatic" translations available for some web pages, and one essentially gets the same program written in different syntaxes. what would be cool is to have a place where one has many versions of the same program, but each written in the "most natural" way for the particular language --- a kind of "rosetta stone" for programming languages. -iavor Andr? Pang wrote: > On 18/06/2004, at 10:49 PM, Gour wrote: > >> Any comment from some experienced Haskell programmer about the latest >> language shootout published on: >> >> http://shootout.alioth.debian.org/index.php > > > Yeah. Language shootouts are nearly worthless. (And I say that as an > experienced Haskell programmer who uses and loves Objective-C and Perl > for his day job, which are rather different beasts to Haskell.) I > groaned when I heard that the shootout was revived, because I didn't > think they'd improve on the "benchmarks" used to test the various > languages, and they haven't. I can't really be bothered emailing them > about the fallacies involved because it's just too tedious to explain, > and I'm sure they're convinced they're doing a good deed to the world. > > About the only good they serve is to show programmers that there are > other languages out there, which some people may like to explore. > ("Oooo, what's this O'Caml language? Seems to be doing OK in the > speed tests ...") They're also good for compiler implementors to find > pathological speed cases in their compiler. That's about it. > > The reason why I think it's all a load of garbage is that a language > is more than its benchmarks. Languages are complex things which you > cannot measure with simple metrics such as speed, or lines of code, or > memory use, combinations thereof, or some insanely complex one which > some fool might dream of. No matter how many large flashing > disclaimers that language shootout site has, there will be plenty of > people who draw conclusions based on the data presented, just by the > virtue of the data being there. ("Haskell is slow. Java is better > than Perl. Prolog-based languages suck for doing anything!" Yadda > yadda yadda ...). > > For instance, one of Haskell's greatest strengths is that its type > system catches so many errors at compile-time that a programs often > behaves as intended if it compiles -- certainly more often than plenty > of other languages. One of Erlang's great strengths is that it's > designed to be robust against bad code, has fantastic support for > distributed services, and can be easily dynamically (un)loaded with > new code. One of Objective-C's greatest strengths is its > extensibility: one can add new methods to existing classes without > needing the original source code at all, and inject new classes or > override a class' methods at run-time. One of Perl's greatest > strengths is built-in support for regular expressions, which makes > one-shot string processing programs more trivial to write than in many > other languages. One of C++'s greatest strengths is that it's C with > better language support for object oriented and generic programming > and coping with complexity, while sacrificing no speed. > > How on earth do you try to factor these things into such a language > shootout? You can't. And, despite all the disclaimers on that site, > despite all its good intentions, it's just going to give the wrong > impression about many languages to many people. I wish that damn > language shootout would be shot itself, and be banished for all > eternity. > > From oleg at pobox.com Fri Jun 18 15:16:04 2004 From: oleg at pobox.com (oleg@pobox.com) Date: Fri Jun 18 15:17:08 2004 Subject: [Haskell] Re: closure of coercions with classes In-Reply-To: Message-ID: <20040618191604.CB507ABC3@Adric.metnet.navy.mil> > The guts of the question is: can one use the class system to code up > the reflexive, transitive closure Computing the transitive closure of types is possible: http://www.haskell.org/pipermail/haskell-cafe/2003-October/005249.html http://www.haskell.org/pipermail/haskell-cafe/2003-November/005433.html > pair :: STRef ((s1, s2), s3) a -> > STRef (s1, s2) b -> > ST (((s1, s2), s3), s4) (STRefr1 (a, b)) > > which isn't as general as I would like, as it imposes a particular order > on the nested scopes. That problem could be solved by open sums, it seems. The HList paper showed how to achieve that, in current Haskell. > I've experimented with a few different attempts, but in the best case > succeeded only in exhausting stack space while searching for satisfying > instances. Could it be possible to post the complete code for those attempts? I'd like to try a few tricks to avoid the divergence. From jyp_7 at yahoo.com Fri Jun 18 16:05:57 2004 From: jyp_7 at yahoo.com (JP Bernardy) Date: Fri Jun 18 16:03:33 2004 Subject: [Haskell] comment on language shootout Message-ID: <20040618200557.9411.qmail@web41503.mail.yahoo.com> --- Gour wrote: > Any comment from some experienced Haskell programmer > about the latest > language shootout published on: > > http://shootout.alioth.debian.org/index.php > regarding Haskell (ghc-6.2.1) score? I would have liked to re-implement some of the benchmarks, some of them should not be looked at by non-haskell programmers, that would give them an awfulidea of what the language looks like/how it should be used. I haven't found where to submit though. BTW, regex matching might be regarded as a bit biased toward ghc :) Cheers, JP. > > > __________________________________ > Do you Yahoo!? > Take Yahoo! Mail with you! Get it on your mobile > phone. > http://mobile.yahoo.com/maildemo > __________________________________ Do you Yahoo!? Yahoo! Mail is new and improved - Check it out! http://promotions.yahoo.com/new_mail From nad at cs.chalmers.se Fri Jun 18 19:26:41 2004 From: nad at cs.chalmers.se (Nils Anders Danielsson) Date: Fri Jun 18 19:24:17 2004 Subject: [Haskell] ANNOUNCE: Chasing Bottoms Message-ID: Excerpt from the documentation at http://www.cs.chalmers.se/~nad/software/ChasingBottoms/docs/: Chasing Bottoms =============== Do you ever feel the need to test code involving bottoms (e.g. calls to the error function), or code involving infinite values? Then this library could be useful for you. It is usually easy to get a grip on bottoms by showing a value and waiting to see how much gets printed before the first exception is encountered. However, that quickly gets tiresome and is hard to automate using e.g. QuickCheck (http://www.cs.chalmers.se/~rjmh/QuickCheck/). With this library you can do the tests as simply as the following examples show. Testing explicitly for bottoms: > isBottom (head []) True > isBottom bottom True > isBottom (\_ -> bottom) False > isBottom (bottom, bottom) False Comparing finite, partial values: > ((bottom, 3) :: (Bool, Int)) ==! (bottom, 2+5-4) True > ((bottom, bottom) :: (Bool, Int)) approxShow 4 $ (True, bottom) \/! (bottom, b) "Just (True, b)" > approxShow 4 $ (True, bottom) /\! (bottom, b) "(_|_, _|_)" > approxShow 4 $ ([1..] :: [Int]) "[1, 2, 3, _" > approxShow 4 $ (cycle [bottom] :: [Bool]) "[_|_, _|_, _|_, _" Approximately comparing infinite, partial values: > approx 100 [2,4..] ==! approx 100 (filter even [1..] :: [Int]) True > approx 100 [2,4..] /=! approx 100 (filter even [bottom..] :: [Int]) True The code above relies on the fact that bottom, just as error "...", undefined and pattern match failures, yield exceptions. Sometimes we are dealing with properly non-terminating computations, such as the following example, and then it can be nice to be able to apply a timeout. > let primes = unfoldr (\(x:xs) -> Just (x, filter ((/= 0) . (`mod` x)) xs)) [2..] > timeOutMicro 100 (print $ filter ((== 1) . (`mod` 32)) primes) >>= print [97,193,257Nothing > timeOutMicro 100 (print $ take 5 $ filter ((== 1) . (`mod` 32)) primes) >>= print [97,193,257,353Nothing > timeOutMicro 100 (print $ take 5 $ filter ((== 1) . (`mod` 32)) primes) >>= print [97,193,257,353,449] Just () All the type annotations above are required. For the underlying theory and a larger example involving use of QuickCheck, see the article "Chasing Bottoms, A Case Study in Program Verification in the Presence of Partial and Infinite Values" (http://www.cs.chalmers.se/~nad/publications/danielsson-jansson-mpc2004.html). Source code: http://www.cs.chalmers.se/~nad/software/ChasingBottoms/chasing-bottoms.tar.gz. /NAD From paul at activemath.org Fri Jun 18 08:16:56 2004 From: paul at activemath.org (Paul Libbrecht) Date: Sat Jun 19 23:12:49 2004 Subject: [Haskell] MathUI workshop: deadline extension Message-ID: <63FDE748-C121-11D8-A91B-000A95C50B1C@activemath.org> :please distribute: :call for papers: workshop on Mathematical User Interfaces ---------------------------- Sept 18th 2004, Bialowezia, Poland at the Third Mathematical Knowledge Management Conference http://www.activemath.org/~paul/MathUI/ SCOPE The impact of mathematical knowledge management on user interfaces is only begininning to show. In interactive proof construction, some systems are able to suggest suitable theorems to apply to subgoals by harvesting online libraries; in computer algebra, folding/unfolding and automatic completion of terms helps the user with the input of complex expressions. Paradigms on how to use third-party software from within a preferred GUI are emerging and promise to innovate the notion of mathematical workspace. This workshop wants to focus on novel aspects of UI brought forward by the developments in MKM. It would like to bring together researchers and practioneers working with contemporary mathematical user-interfaces, including, but not limited to: - mathematical knowledge presentation - interactivity with mathematical objects - interactive simulations - mathematical objects input and manipulations. - access to mathematical knowledge INVITED TALK The workshop has invited Joris van der Hoeven for a talk about TeXMacs, an open-source WYSYWYG editor for mathematical publications. SUBMISSIONS AND DATES - Presentation proposals should be accompanied with an article or other presentation (for example a video or a mock-up GUI). Proceedings shall be online. - Either: - Submit your presentation proposal until June 30th - Or submit an abstract of your presentation (10 lines to half-a-page) until June 30th and a revised version until July 31st - Expect an answer on August 20th - Enjoy the workshop on Sept 18th PROGRAMME COMMITTEE Paul Cairns UCL Interaction Center, University College London, Great Britain Olga Caprotti Research Institute for Symbolic Computation, Linz, Austria Hanane Naciri Projet Lemme, INRIA Sophia Antipolis, France Norbert Kajler Ecole Nationale Sup?rieure des Mines de Paris, France Paul Libbrecht (organizer) Competence Center for E-Learning, DFKI GmbH, Saarbr?cken, Germany Robert Miner Design Science Inc., Long Beach, California, USA MORE INFORMATION Host Conference: Mathematical Knowledge Management 2004 http://www.mizar.org/MKM2004/ More information can be read from the workshop's web-page http://www.activemath.org/~paul/MathUI/ From greg at eecs.harvard.edu Fri Jun 18 13:25:44 2004 From: greg at eecs.harvard.edu (Greg Morrisett) Date: Sat Jun 19 23:12:51 2004 Subject: [Haskell] Re: comment on language shootout In-Reply-To: <40D32425.9010907@cse.ogi.edu> References: <20040618124931.GB8111@mail.inet.hr> <40D32425.9010907@cse.ogi.edu> Message-ID: <40D32598.6060302@eecs.harvard.edu> Iavor S. Diatchki wrote: > what would be cool is to have a place where > one has many versions of the same program, but each written in the "most > natural" > way for the particular language --- a kind of "rosetta stone" for > programming languages. The ICFP programming contest (and other contests) serve this purpose pretty well. I've found it very instructive to stare at solutions in languages with which I'm not familiar. And the tasks at hand tend to be more realistic (e.g., rendering) than micro-benchmarks. -Greg From vivian.mcphail at paradise.net.nz Sun Jun 20 22:55:22 2004 From: vivian.mcphail at paradise.net.nz (Vivian McPhail) Date: Sun Jun 20 22:52:51 2004 Subject: [Haskell] State Transformers and Control.Monad.ST.Lazy Message-ID: <1087786522.40d64e1a73f2b@www.paradise.net.nz> Hi, >From the very helpful posts of John Hughes and others concerning "Monadic Loops", I've been advised to re-implement my neural net simulator using lazy state threads to avoid crashes to which recursive (and tail-recursive) monads lead. I had been using monad transformers to lift IO operations: data NeuralNet = NN { ... } data NNO a = NNO (NeuralNet -> (a,NeuralNet)) data NNT m a = NNT (NeuralNet -> m (a,NeuralNet)) following the example of a state transformer in "Functional Programming with Overloading and Higher-Order Polymorphism". I am trying to reimplement with data ST s a from Control.Monad.ST.Lazy and "Lazy Functional State Threads" however there is something I think I do not understand, that is the "s" in the ST dataype. The compiler tells me it needs to be instantiated, but I am presuming that a type such as type NNST = ST NeuralNet a is useless because there is no way (from this module) to access that state using the "update" method of the MonadState class. 1. Am I correct in thinking that I need to use a monad transformer lifting from the ST monad to incorporate my NeuralNet datatype 2. Can I merely instantiate ST as ST () a? Thanks in advance. Vivian McPhail From stefano.bistarelli at iit.cnr.it Mon Jun 21 11:42:35 2004 From: stefano.bistarelli at iit.cnr.it (Stefano Bistarelli) Date: Mon Jun 21 12:13:39 2004 Subject: [Haskell] final cfp: soft2004 Message-ID: <065601c457a6$5ffed3a0$43633092@bistarelli> ============================================================================ ======= 6th International Workshop on Soft Constraints and Preferences September 27th, 2004 Toronto, Canada Held in conjunction with 10th International Conference on Principles and Practice of Constraint Programming, CP2004 http://www.sci.unich.it/~bista/organizing/soft-2004/ ============================================================================ ======== Call for Paper ============================================================================ ======== Preferences are ubiquitous in real life: most problems are over-constrained and would not be solvable if we insist that all their requirements are strictly met. Moreover, many problems are more naturally described via preference rather than hard statements. Soft constraints are the way the constraint community has extended his classical framework to deal with the conceept of preferences. However, other frameworks for expressing preferences have been proposed in the last few years in AI or related disciplines, with different features and leading to different results. For example, both qualitative and quantitative preference frameworks are being studied and used to model and solve real-life probleems. This workshop would like to bring together researchers interested in all aspects of preferences and soft constraints, such as: - theoretical frameworks - problem modeling - solving algorithms - languages - preference aggregation - preference elicitation - multi-objective or qualitative optimization - combining/integrating different frameworks and algorithms - comparative studies - real-life applications Submissions This workshop is intended to build on the experience and success of the workshops on soft constraints that have been held at CP99, CP2000, CP2001, CP2002 and CP2003, and on the AAAI 2002 workshop on preferences in AI and CP. Its aim is to provide a forum where researchers currently working in the area of preferences or soft constraints can discuss their most recent ideas and developments and think together about the most promising new directions. Therefore we encourage the presentation of work in progress or on specialized aspects of soft constraints. Papers that bridge the gap between theory and practice are especially welcome. Prospective attendees can submit a paper, which can be up to 15 pages in length. We encourage authors to submit papers electronically in postscript or pdf format. Papers should be formatted using the Lecture Notes in Computer Science (LNCS) style. Please send your submissions by email to stefano.bistarelli@iit.cnr.it using the subject line Soft-2004 Workshop Submission. Although no agreement is yet in place, we will consider the publication of a selection of papers presented at this workshop in a special issue of a journal or in a volume of a serie. Important Dates The proposed schedule of important dates for the workshop is as follows: Paper Submission deadline June 26th Notification of acceptance July 24th Camera-ready version deadline August 14th Workshop Date September 27th Workshop Organizers: Stefano Bistarelli (Primary Contact) Dipartimento di Scienze Universit? degli studi "G. D'Annunzio" di Chieti-Pescara, Italy Email: bista@sci.unich.it Web: http://www.sci.unich.it/~bista/ and Istituto di Informatica e Telematica C.N.R. Pisa, Italy Email: stefano.bistarelli@iit.cnr.it and Francesca Rossi Dipartimento di Matematica Pura ed Applicata Universita' degli Studi di Padova, Italy Email: frossi@math.unipd.it Web: http://www.math.unipd.it/~frossi/ Program Committee: Stefano Bistarelli (University of Pescara, Italy --- C.N.R., Pisa, Italy) Simon De Givry (Institut National de La Recherche Agronomique, Castanet Tolosan Cedex, France) Boi Faltings (EPFL, Switzerland) Carmen Gervet (IC-Parc, Imperial College, UK) Ulrich Junker (ILOG, France) Javier Larrosa (Universitat Polit?cnica de Catalunya, UPC, Barcelona, Spain) Jimmy H. M. Lee (The Chinese University of Hong Kong, Hong Kong) Pedro Meseguer (IIIA-CSIC, Bellaterra, Spain) Barry O'Sullivan (University College Cork, Ireland) Francesca Rossi (University of Padova, Italy) Thomas Schiex (Institut National de La Recherche Agronomique, Castanet Tolosan Cedex, France) Toby Walsh (Cork Constraints Computation Centre, Ireland) From hofte at natlab.research.philips.com Tue Jun 22 05:20:48 2004 From: hofte at natlab.research.philips.com (Tom Hofte) Date: Tue Jun 22 05:18:13 2004 Subject: [Haskell] Reading a directory tree Message-ID: <002801c4583a$34c2ddf0$37ae9182@ddns.htc.nl.philips.com> Hi, I'm looking for a way to iteratively read all the files in a directory and its subdirectories, given the filepath of the top-level dir. For example, I want to find a file, corresponding to a given filename, in a directory and its subdirectories. Is there a way to implement this in Haskell? Kind regards, Tom Hofte -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org//pipermail/haskell/attachments/20040622/b37874b1/attachment.htm From rjmh at cs.chalmers.se Tue Jun 22 05:32:42 2004 From: rjmh at cs.chalmers.se (John Hughes) Date: Tue Jun 22 05:30:06 2004 Subject: [Haskell] Reading a directory tree In-Reply-To: <002801c4583a$34c2ddf0$37ae9182@ddns.htc.nl.philips.com> References: <002801c4583a$34c2ddf0$37ae9182@ddns.htc.nl.philips.com> Message-ID: <1711.217.215.17.71.1087896762.squirrel@mail.medic.chalmers.se> > Hi, > > I'm looking for a way to iteratively read all the files in a directory and > its subdirectories, given the filepath of the top-level dir. > For example, I want to find a file, corresponding to a given filename, in > a directory and its subdirectories. > getDirectoryContents is your friend. It's a function in the standard library Directory, documented here: http://haskell.org/onlinereport/directory.html getDirectoryContents :: FilePath -> IO [FilePath] A FilePath is just a String. John Hughes From rjmh at cs.chalmers.se Tue Jun 22 05:37:27 2004 From: rjmh at cs.chalmers.se (John Hughes) Date: Tue Jun 22 05:34:50 2004 Subject: [Haskell] Reading a directory tree In-Reply-To: <002801c4583a$34c2ddf0$37ae9182@ddns.htc.nl.philips.com> References: <002801c4583a$34c2ddf0$37ae9182@ddns.htc.nl.philips.com> Message-ID: <1745.217.215.17.71.1087897047.squirrel@mail.medic.chalmers.se> > Hi, > > I'm looking for a way to iteratively read all the files in a directory and > its subdirectories, given the filepath of the top-level dir. > For example, I want to find a file, corresponding to a given filename, in > a directory and its subdirectories. > > Is there a way to implement this in Haskell? > Just a supplement to my previous message: you can find better documentation of the Directory library here: http://www.haskell.org/ghc/docs/latest/html/libraries/base/System.Directory.html John Hughes From simons at cryp.to Tue Jun 22 06:33:00 2004 From: simons at cryp.to (Peter Simons) Date: Tue Jun 22 06:30:31 2004 Subject: [Haskell] Re: Reading a directory tree References: <002801c4583a$34c2ddf0$37ae9182@ddns.htc.nl.philips.com> Message-ID: <87oenbubkz.fsf@peti.cryp.to> Tom Hofte writes: > I'm looking for a way to iteratively read all the files > in a directory and its subdirectories, given the filepath > of the top-level dir. Hope this helps: \begin{code} module ReadDirHier ( Entry(..) , name , readDirHier ) where import System.Directory (getDirectoryContents, doesDirectoryExist) import Data.List (isPrefixOf, sort) data Entry = Dir FilePath [Entry] | File FilePath name :: Entry -> FilePath name (Dir p _) = p name (File p) = p -- |Read the complete directory hierarchy starting at 'FilePath' and -- return a tree representing it. The top-most 'Entry' will - -- obviously - be a 'Dir'. Directories contain their sub-entries in -- alphabetic order. The returned tree starts with the 'name' \"@.@\" -- - /not/ with the given 'FilePath'. All file names are relative to -- their current directory. -- -- The function may throw exceptions when I/O fails. readDirHier :: FilePath -> IO Entry readDirHier path = readDirHier' path "." readDirHier' :: FilePath -> FilePath -> IO Entry readDirHier' pre p = do files <- getDirectoryContents $ pre ++ "/" ++ p entries <- mapM toEntry $ sort $ clean files return (Dir p entries) where toEntry x = do isDir <- doesDirectoryExist $ path ++ "/" ++ x if isDir then readDirHier' path x else return (File x) where path = pre ++ "/" ++ p clean xs = [ x | x <- xs, x /= "." -- TODO: This should really be a , x /= ".." -- function provided by the caller. , x /= "CVS" , not (".#" `isPrefixOf` x) ] \end{code} From simons at cryp.to Tue Jun 22 06:38:36 2004 From: simons at cryp.to (Peter Simons) Date: Tue Jun 22 06:36:02 2004 Subject: [Haskell] Re: HsDNS -- asynchronous DNS resolver References: <87llimml3y.fsf@peti.cryp.to> <20040617124148.GA3868@students.mimuw.edu.pl> <87llili5rz.fsf@peti.cryp.to> <20040618110904.GA4415@students.mimuw.edu.pl> Message-ID: <87k6xzubbn.fsf@peti.cryp.to> Tomasz Zielonka writes: > Maybe we could have two implementations behind one > interface? It sure sounds nice, but the problem is that the API is basically nothing more than the data types used to represent DNS queries and answers. My API has just one single function: query. So having the same API comes down to having the same data types in both of our modules ... I don't know whether this is feasible. We could have a common DNS.Datagram module, maybe, which both libraries could use? Also, I am not entirely free to choose the data types I use, because I have to marshal them (efficiently) for ADNS. If it can be done, I am all for it. But I probably wouldn't want to invest too much time into the problem. Once your implementation is stable, I think most people will prefer the pure Haskell version anyway and stick with yours. I thought of HsDNS as an interim solution anyway, it's just a solution that works _now_. Peter From tpledger at ihug.co.nz Tue Jun 22 07:06:02 2004 From: tpledger at ihug.co.nz (Tom Pledger) Date: Tue Jun 22 06:58:07 2004 Subject: [Haskell] State Transformers and Control.Monad.ST.Lazy References: <1087786522.40d64e1a73f2b@www.paradise.net.nz> Message-ID: <40D8129A.7020201@ihug.co.nz> Vivian McPhail wrote: >Hi, > >>From the very helpful posts of John Hughes and others concerning >"Monadic Loops", I've been advised to re-implement my neural net >simulator using lazy state threads to avoid crashes to which recursive >(and tail-recursive) monads lead. > >I had been using monad transformers to lift IO operations: > >data NeuralNet = NN { ... } > >data NNO a = NNO (NeuralNet -> (a,NeuralNet)) > >data NNT m a = NNT (NeuralNet -> m (a,NeuralNet)) > >following the example of a state transformer in "Functional Programming >with Overloading and Higher-Order Polymorphism". > >I am trying to reimplement with > >data ST s a > >from Control.Monad.ST.Lazy and "Lazy Functional State Threads" > >however there is something I think I do not understand, that is the "s" in >the ST dataype. > The s is a safety mechanism, to ensure that you don't share an STRef or STArray between two state threads. It is usually instantiated/substituted where the runST function is applied. You don't supply a substitution for s; runST does. (The memoisation library which uses ST () is unusual in that respect.) Normal use of ST for your neural net example would be: do nnRef <- newSTRef (NN { ... }) -- set the initial NeuralNet state --from here on, you pass nnRef around as a parameter Control.Monad.State (as opposed to ST) may be a closer match for the NNO and NNT types. Regards, Tom From R.E.Jones at kent.ac.uk Tue Jun 22 06:23:35 2004 From: R.E.Jones at kent.ac.uk (Richard Jones) Date: Tue Jun 22 07:00:43 2004 Subject: [Haskell] Garbage Collection & Memory Management Summer School Message-ID: Please excuse this spam-style mailing. I've also attached a poster in the hope that you might it useful. Richard Jones Garbage Collection & Memory Management Summer School 20-21 July 2004, Canterbury, UK The performance of today's memory-hungry applications depends on efficient dynamic memory management, whether managed explicitly through new/delete or automatically by a garbage collector. With the increasing use of managed code, whether Java Virtual Machines or Microsoft's Common Language Runtime, the economic importance of automatic memory management has never been greater. The Summer Schoool provides participants with an opportunity to hear leading practitioners from both industry and universities. The school is directed at postgraduate research students, academics who wish to get involved in this field and industrial researchers and developers who want to apply state of the art memory management techniques to real problems. The presenters include David Bacon (IBM TJ Watson Research Center), Emery Berger (U. Massachusetts), Hans Boehm (HP), Dave Detlefs (Sun Microsystems), Rick Hudson (Intel), Richard Jones (U. Kent, Canterbury), Eliot Moss (U. Massachusetts), Ryan Sciampacone (IBM Ottawa). The registration fee for the 2 day Summer School is 130 GBP (free of VAT) and includes all workshop materials, lunches and refreshments, and the Summer School Dinner on 20th July. Bed and breakfast accommodation is also available in en-suite accommodation on campus at a rate of 30 GBP per night. For more details, see http://www.mm-net.org.uk/school/ or mail school@mm-net.org.uk The Summer School is organised by the UK Memory Management Network (http://www.mm-net.org.uk). We are grrateful for the kind support of the Engineering and Physical Sciences Research Council (http://www.epsrc.ac.uk). -------------- next part -------------- A non-text attachment was scrubbed... Name: flyer.pdf Type: application/pdf Size: 135705 bytes Desc: flyer.pdf Url : http://www.haskell.org//pipermail/haskell/attachments/20040622/e7a66d80/flyer-0001.pdf From marcello at liacs.nl Tue Jun 22 06:47:02 2004 From: marcello at liacs.nl (M.M. Bonsangue) Date: Tue Jun 22 07:00:44 2004 Subject: [Haskell] Call for Participation: FMCO 2004 Message-ID: <200406221047.i5MAl2O13943@pc157aa.liacs.nl> ********************* CALL FOR PARTICIPATION ******************** Third International Symposium on Formal Methods for Components and Objects (FMCO 2004) The objective of this symposium is to bring together top researchers in the area of software engineering to discuss the state-of-the-art and future applications of formal methods in the development of large component-based and object-oriented software systems. DATES 2 - 5 November 2004 PLACE Lorentz Center, Leiden University, Leiden, The Netherlands URL http://fmco.liacs.nl/fmco04.html Early registration fee applies for registration before 20/09/2004 !!! Participation is limited to about 80 people, based on a first-in first-served policy. For more information about participation and registration see the FMCO site at http://fmco.liacs.nl/fmco04.html or consult either F.S. de Boer (frb@cwi.nl) or M.M. Bonsangue (marcello@liacs.nl). PRELIMINARY PROGRAM TUESDAY 2nd, November 2004 8:45 - 9:00 Welcome 9:00 - 10:00 Keynote: Robin Milner (Cambridge University, UK) 10:00 - 10:30 Break 10:30 - 11:15 Rocco de Nicola (University of Firenze, IT) 11:15 - 12:00 Eugenio Moggi (Genova University, IT) 12:00 - 13:30 Lunch break 13:30 - 14:30 Keynote: Kim Bruce (Williams College, USA) 14:30 - 15:00 Break 15:00 - 15:45 Julian Rathke (Sussex University, UK) 15:45 - 16:00 Break 16:00 - 16:45 Martin Steffen (Kiel University, DE) 16:45 - 17:30 Marcello Bonsangue (LIACS, NL) WEDNESDAY 3rd, November 2004 9:00 - 10:00 Keynote: Tom Henzinger (University of California, Berkeley, USA) 10:00 - 10:30 Break 10:30 - 11:15 Susanne Graf (Verimag, FR) 11:15 - 12:00 Wang Yi (Uppsala University, SE) 12:00 - 13:15 Lunch break 13:15 - 14:15 Keynote: Thomas Ball (Microsoft Research at Redmond, USA) 14:15 - 14:30 Break 14:30 - 15:15 Frits Vaandrager (Nijmegen University, NL) 15:15 - 16:00 Wolfgang Weck (Oberon Microsystems, CH) 17:00 - 19:15 Social Event 19:30 - Dinner THURSDAY 4th, November 2004 9:00 - 10:00 Keynote: Kim Larsen (Aalborg University, DK) 10:00 - 10:30 Break 10:30 - 11:15 Ed Brinksma (University of Twente, NL) 11:15 - 12:00 Andreas Podelski (Max Plank Inst. for Informatics, DE) 12:00 - 13:30 Lunch break 13:30 - 14:30 Keynote: Chris Hankin (Imperial College, UK) 14:30 - 15:00 Break 15:00 - 15:45 David Naumann (Stevens Institute of Technology, USA) 15:45 - 16:30 Tobias Nipkow (Munchen University, DE) 16:30 - 16:45 Break 16:45 - 17:30 Liu Zhiming (UNU-IIST, Macao) FRIDAY 5th, November 2004 9:00 - 10:00 Keynote: Samson Abramsky (Oxford University, UK) 10:00 - 10:30 Break 10:30 - 11:15 Luca de Alfaro (UC Santa Cruz, USA) 11:15 - 12:00 Luis Barbosa (Minho University, PT) 12:00 - 13:30 Lunch break 13:30 - 14:30 Keynote: Reinhard Wilhelm (Saarland University, DE) 14:30 - 15:00 Break 15:00 - 15:45 Olaf Owe (University of Oslo, NO) 15:45 - 16:30 Pierre Cointe (Ecole des Mines de Nantes, FR) ORGANIZING COMMITTEE F.S. de Boer (CWI and Utrecht University) M.M. Bonsangue (LIACS-Leiden University) S. Graf (Verimag) W.P. de Roever (CAU) From amelende at escuelaing.edu.co Tue Jun 22 08:00:49 2004 From: amelende at escuelaing.edu.co (Alfonso) Date: Tue Jun 22 07:58:11 2004 Subject: [Haskell] (no subject) Message-ID: <20040622115809.7A12C3687C3@www.haskell.org> Hello dear haskellers: My name is Alfonso Mel?ndez I work in Computer Science in a Colombian University. Right now, I am developing an application for discrete mathematics and I need to comunicate Java with Haskell, more precisely I use Java for the interface of the application and from here I need to call several Haskell Functions. In Haskell.org there are two libraries ( Java Bridge and JNI) that communicate Haskell with Java (but not viceversa). Is there and easy and direct way to do this job? Thank you!!! Alfonso Mel?ndez Direcci?n de Proyectos Facultad de Ingenier?a de Sistemas Escuela Col de Ingenier?a Tels: 676266,6763888, Ext: 224, 371 Cel: (315) 8938216 ##################################################################################### This e-mail message has been scanned for Viruses and Content and cleared by NetIQ MailMarshal ##################################################################################### -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org//pipermail/haskell/attachments/20040622/6965fe98/attachment.htm From gwright at comcast.net Tue Jun 22 10:03:27 2004 From: gwright at comcast.net (Gregory Wright) Date: Tue Jun 22 10:00:53 2004 Subject: [Haskell] Reading a directory tree In-Reply-To: <002801c4583a$34c2ddf0$37ae9182@ddns.htc.nl.philips.com> References: <002801c4583a$34c2ddf0$37ae9182@ddns.htc.nl.philips.com> Message-ID: Hi Tom, Attached is a haskell file I wrote when I was learning how to use the directory functions. It builds a tree structure corresponding to the directory tree and finds the files that end in ".txt". It then sorted the files in order of modification time. As you can guess from the program, it was for managing weblog entries in Blosxom. It's beginner-ish code, but you can probably adapt it to your needs. Note that the top level directory name "dir" is hardcoded into the program. Best Wishes, Greg On Jun 22, 2004, at 5:20 AM, Tom Hofte wrote: > Hi, > ? > I'm looking for a way to iteratively read all the files in a directory > and > its subdirectories, given the filepath of the top-level dir. > For example, I want to find a file, corresponding to a?given > filename,?in a directory and its subdirectories. > ? > Is there a way to implement this in Haskell? > ? > Kind regards, > ? > Tom Hofte > ? > _______________________________________________ > Haskell mailing list > Haskell@haskell.org > http://www.haskell.org/mailman/listinfo/haskell > dirtree.hs: -- -- walk a directory tree and find all of the files ending in .txt -- module Main (main) where import Monad import Directory import Text.Regex import List -- -- dirTree returns a tree with nodes containing file -- information or directory information and a subdirectory. -- data DTree = FileNode String | DirNode String [DTree] addPrefix d str = do return (d ++ str) addSuffix d str = do return (str ++ d) scanDir d = do dentries <- getDirectoryContents d files <- mapM (addPrefix d) dentries ffiles <- filterM doesFileExist files -- directory names require extra processing: we must delete the "." and ".." entries -- and add a trailing "/" dirs <- filterM (\x -> do return (x /= "." && x /= "..")) dentries ddirs <- mapM (addPrefix d) dirs dddirs <- mapM (addSuffix "/") ddirs subdirs <- filterM doesDirectoryExist dddirs subDTrees <- mapM scanDir subdirs return (DirNode d ((map (\f -> FileNode f) ffiles) ++ subDTrees)) -- walk a directory tree, printing the contents showDTree (FileNode fname) = do print fname showDTree (DirNode dname ds) = do print dname mapM showDTree ds return () -- given a directory tree, find the files that end in ".txt" findTxt (DirNode dname ds) = concat (map findTxt ds) findTxt (FileNode fname) = if (isTextFile fname) then [fname] else [] -- given a file name, see if it ends in ".txt" isTextFile f = (matchRegex regexp f) /= Nothing where regexp = mkRegex ".*txt" printIfMatched f = if (isTextFile f) then do print f else do return () dir = "/Users/gwright/Desktop/Blosxom/docs/" timeSortedFiles d = do directoryTree <- scanDir d showDTree directoryTree textFiles <- do return (findTxt directoryTree) modTimes <- mapM getModificationTime textFiles fs <- do return (sortBy (\(f1,t1) (f2,t2) -> compare t1 t2) (zip textFiles modTimes)) return (map fst fs) main = do fs <- timeSortedFiles dir fs' <- do return (take 1 fs) mapM (\f -> do c <- readFile f; putStr c) fs' return () -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: text/enriched Size: 3746 bytes Desc: not available Url : http://www.haskell.org//pipermail/haskell/attachments/20040622/27a3f90e/attachment.bin From glynn.clements at virgin.net Tue Jun 22 11:56:34 2004 From: glynn.clements at virgin.net (Glynn Clements) Date: Tue Jun 22 12:16:04 2004 Subject: [Haskell] Reading a directory tree In-Reply-To: <002801c4583a$34c2ddf0$37ae9182@ddns.htc.nl.philips.com> References: <002801c4583a$34c2ddf0$37ae9182@ddns.htc.nl.philips.com> Message-ID: <16600.22194.882784.745854@cerise.nosuchdomain.co.uk> Tom Hofte wrote: > I'm looking for a way to iteratively read all the files in a directory > and > its subdirectories, given the filepath of the top-level dir. > For example, I want to find a file, corresponding to a given filename, > in a directory and its subdirectories. > > Is there a way to implement this in Haskell? BTW, one other caveat (which applies to all of the examples so far): doesDirectoryExist doesn't distinguish between directories and symlinks to directories. Consequently, any directory-traversal algorithm which uses doesDirectoryExist to identify directories will behave incorrectly in the presence of symlinks. In the worst case, you can get into an infinite loop. The only alternative is to use the functions from the Posix library (getSymbolicLinkStatus and isDirectory) instead, e.g.: > import Posix > > doesDirectoryReallyExist :: FilePath -> IO Bool > doesDirectoryReallyExist path = do > stat <- getSymbolicLinkStatus > return $ isDirectory stat -- Glynn Clements From glynn.clements at virgin.net Tue Jun 22 11:38:14 2004 From: glynn.clements at virgin.net (Glynn Clements) Date: Tue Jun 22 12:16:07 2004 Subject: [Haskell] Reading a directory tree In-Reply-To: <002801c4583a$34c2ddf0$37ae9182@ddns.htc.nl.philips.com> References: <002801c4583a$34c2ddf0$37ae9182@ddns.htc.nl.philips.com> Message-ID: <16600.21094.929838.590640@cerise.nosuchdomain.co.uk> Tom Hofte wrote: > I'm looking for a way to iteratively read all the files in a directory > and > its subdirectories, given the filepath of the top-level dir. > For example, I want to find a file, corresponding to a given filename, > in a directory and its subdirectories. > > Is there a way to implement this in Haskell? This is somewhat simpler than the other examples which have been given. > import Monad > import Directory > > scanDir :: FilePath -> IO [FilePath] > scanDir dir = do > names <- getDirectoryContents dir > let names' = filter ((/= '.') . head) names > let paths = map ((dir ++ "/") ++) names' > dirs <- filterM doesDirectoryExist paths > files <- filterM doesFileExist paths > rest <- mapM scanDir dirs > return $ files ++ concat rest One caveat: (scanDir "/") isn't handled correctly; you will get an extra slash, i.e. "//usr", "//bin" etc. Not that I'd recommend using this code for scanning an entire filesystem, due to performance issues. -- Glynn Clements From Keith.Wansbrough at cl.cam.ac.uk Tue Jun 22 16:02:48 2004 From: Keith.Wansbrough at cl.cam.ac.uk (Keith Wansbrough) Date: Tue Jun 22 16:00:13 2004 Subject: [Haskell] Reading a directory tree In-Reply-To: Your message of "Tue, 22 Jun 2004 16:56:34 BST." <16600.22194.882784.745854@cerise.nosuchdomain.co.uk> Message-ID: > BTW, one other caveat (which applies to all of the examples so far): > doesDirectoryExist doesn't distinguish between directories and > symlinks to directories. Consequently, any directory-traversal > algorithm which uses doesDirectoryExist to identify directories will > behave incorrectly in the presence of symlinks. In the worst case, you > can get into an infinite loop. symlinks aren't necessary to give an infinite loop: you can have upwards hard links as well (at least on *nix). You have to keep a list of inodes you've already visited (per filesystem, of course). --KW 8-) -- Keith Wansbrough http://www.cl.cam.ac.uk/users/kw217/ University of Cambridge Computer Laboratory. From duncan.coutts at worcester.oxford.ac.uk Tue Jun 22 16:12:27 2004 From: duncan.coutts at worcester.oxford.ac.uk (Duncan Coutts) Date: Tue Jun 22 16:09:48 2004 Subject: [Haskell] Reading a directory tree In-Reply-To: References: Message-ID: <1087935146.6824.47.camel@localhost> On Tue, 2004-06-22 at 21:02, Keith Wansbrough wrote: > > BTW, one other caveat (which applies to all of the examples so far): > > doesDirectoryExist doesn't distinguish between directories and > > symlinks to directories. Consequently, any directory-traversal > > algorithm which uses doesDirectoryExist to identify directories will > > behave incorrectly in the presence of symlinks. In the worst case, you > > can get into an infinite loop. > > symlinks aren't necessary to give an infinite loop: you can have > upwards hard links as well (at least on *nix). You have to keep a > list of inodes you've already visited (per filesystem, of course). I believe hard linked directories are banned to avoid this problem. This is true on Linux at least, I don't know what POSIX specifies. Duncan From glynn.clements at virgin.net Tue Jun 22 19:31:02 2004 From: glynn.clements at virgin.net (Glynn Clements) Date: Tue Jun 22 19:29:46 2004 Subject: [Haskell] Reading a directory tree In-Reply-To: <1087935146.6824.47.camel@localhost> References: <1087935146.6824.47.camel@localhost> Message-ID: <16600.49462.95404.457241@cerise.nosuchdomain.co.uk> Duncan Coutts wrote: > > > BTW, one other caveat (which applies to all of the examples so far): > > > doesDirectoryExist doesn't distinguish between directories and > > > symlinks to directories. Consequently, any directory-traversal > > > algorithm which uses doesDirectoryExist to identify directories will > > > behave incorrectly in the presence of symlinks. In the worst case, you > > > can get into an infinite loop. > > > > symlinks aren't necessary to give an infinite loop: you can have > > upwards hard links as well (at least on *nix). You have to keep a > > list of inodes you've already visited (per filesystem, of course). > > I believe hard linked directories are banned to avoid this problem. Most modern Unices disallow the creation of additional hard links to directories, so the only "upward" links are the "." entry and the ".." entries for each subdirectory (which I specifically filtered in my example[1]). [1] Actually, I filtered anything beginning with a "."; I should have pointed that out. To change that, replace: let names' = filter ((/= '.') . head) names with: let names' = filter (`notElem` [".", ".."]) names Unices which do allow the creation of hard links to directories only allow this for root, and programs which perform directory traversal frequently fall down on such cases; tracking visited directories tends to be the exception rather than the norm. The usual solution is to assume that root knows what they're doing (and if they don't, tough) and ignore the issue. OTOH, directory-traversal code which follows symlinks will fall down far more readily, as symlinks to directories can be created on all platforms which allow symlinks, and require no special privileges. [On early Linux distributions, it was quite common for /etc/inet to be a symlink to /etc, as programs often disagreed as to whether certain configuration files belonged in /etc or /etc/inet. Attempting to back-up the Linux filesystem via Samba with a Windows backup tool would result in an "end of tape" error somewhere around /etc/inet/inet/inet/inet/....] > This is true on Linux at least, I don't know what POSIX specifies. I don't know about POSIX, but Unix98 says: [http://www.opengroup.org/onlinepubs/009695399/functions/link.html] DESCRIPTION ... If path1 names a directory, link() shall fail unless the process has appropriate privileges and the implementation supports using link() on directories. ... ERRORS ... [EPERM] The file named by path1 is a directory and either the calling process does not have appropriate privileges or the implementation prohibits using link() on directories. ... RATIONALE Linking to a directory is restricted to the superuser in most historical implementations because this capability may produce loops in the file hierarchy or otherwise corrupt the file system. This volume of IEEE Std 1003.1-2001 continues that philosophy by prohibiting link() and unlink() from doing this. Other functions could do it if the implementor designed such an extension. There isn't a macro or sysconf/pathconf option to query whether the platform allows links to directories. -- Glynn Clements From fjh007 at galois.com Tue Jun 22 21:44:12 2004 From: fjh007 at galois.com (Fergus Henderson) Date: Tue Jun 22 23:25:13 2004 Subject: [Haskell] modern language design, stone age tools Message-ID: <20040623014412.GA23457@evariste.galois.com> \begin{gripe} Seeing as Haskell is apparently such a popular language these days, I don't suppose a working debugger would be too much to ask for, would it? Or even just a decent call stack trace when a program terminates with an exception? In case you're wondering, yes I have already tried using Hat and Buddha. But I'm trying to debug a real application, not a toy one, and neither Hat nor Buddha support enough of Haskell. Buddha doesn't even come close, as far as I can tell, and Hat lacks support for library modules such as Data.Word. I've also tried using ghc's profiling to get stack traces, but that doesn't work very well either. Firstly, the stack traces that you get only include function names, not line numbers. Secondly, the stack traces are often incomplete, for reasons that I don't fully understand. One likely cause is tail call optimization. (Is there any option to switch off tail call optimization? I didn't see any such option in the ghc man page.) Thirdly, profiling seems to be incompatible with the use of ghci; there doesn't seem to be any easy way to build a workspace so that you can get stack traces and use ghci in that workspace at the same time. And ghc is slow enough (even on a 3.2GHz Pentium 4) that recompiling the whole workspace is highly unpalettable. There's a hell of a lot of languages out there that _do_ support decent stack traces when an exception is thrown. What's the point of using a high-level functional language if it means you're stuck with poor library support and/or stone-age tools? \end{gripe} -- Fergus J. Henderson | "I have always known that the pursuit Galois Connections, Inc. | of excellence is a lethal habit" Phone: +1 503 626 6616 | -- the last words of T. S. Garp. From ketil+haskell at ii.uib.no Wed Jun 23 03:21:55 2004 From: ketil+haskell at ii.uib.no (Ketil Malde) Date: Wed Jun 23 03:19:20 2004 Subject: [Haskell] modern language design, stone age tools In-Reply-To: <20040623014412.GA23457@evariste.galois.com> (Fergus Henderson's message of "Tue, 22 Jun 2004 18:44:12 -0700") References: <20040623014412.GA23457@evariste.galois.com> Message-ID: Fergus Henderson writes: > Seeing as Haskell is apparently such a popular language these days, > I don't suppose a working debugger would be too much to ask for, would it? Hah. You're not supposed to debug, just stare at the code until you become enlightened (why did you think it was called Buddha, anyway)? :-) > I've also tried using ghc's profiling to get stack traces, but that doesn't > work very well either. So you know about +RTS -xc. > Thirdly, profiling seems to be incompatible with the use of ghci; there > doesn't seem to be any easy way to build a workspace so that you can > get stack traces and use ghci in that workspace at the same time. You can compile with: -prof -auto-all -hisuf p.hi -osuf p.o This will create separate object and interface files for profiling. I haven't really tried juggling GHCi in between, but I think it would ignore those. (Or did you want GHCi to use the profiling info to get the stack traces?) > And ghc is slow enough (even on a 3.2GHz Pentium 4) that recompiling > the whole workspace is highly unpalettable. Compile without -O? Avoid large source files, in particular with large embedded data structures? But yes, it's slow. -kzm -- If I haven't seen further, it is by standing in the footprints of giants From Robert.Ennals at cl.cam.ac.uk Wed Jun 23 04:27:26 2004 From: Robert.Ennals at cl.cam.ac.uk (Robert Ennals) Date: Wed Jun 23 04:24:53 2004 Subject: [Haskell] modern language design, stone age tools In-Reply-To: Your message of Tue, 22 Jun 2004 18:44:12 -0700. <20040623014412.GA23457@evariste.galois.com> Message-ID: I wrote such a debugger as part of my PhD work. It is called "hsdebug" and you can read the Haskell Workshop paper on it here: http://www.cambridge.intel-research.net/~rennals/hw2003.pdf Unfortunately, HsDebug depends on Optimistic Evaluation, and it seems unlikely that Optimistic Evaluation will appear in a release version of GHC (too hard to maintain, and I've gone off to work for Intel Research). HsDebug is a GDB-style debugger which takes advantage of the fact that Optimistic Evaluation makes programs evaluate in a largely-strict evaluation order. It also uses a trick called "transient tail frames" to allow tail calls to be visible in stack traces. HsDebug can debug any GHC-compilable Haskell program, including GHC itself. -Rob > \begin{gripe} > > Seeing as Haskell is apparently such a popular language these days, > I don't suppose a working debugger would be too much to ask for, would it? > Or even just a decent call stack trace when a program terminates with an exception? > > In case you're wondering, yes I have already tried using Hat and Buddha. > But I'm trying to debug a real application, not a toy one, and neither Hat > nor Buddha support enough of Haskell. Buddha doesn't even come close, > as far as I can tell, and Hat lacks support for library modules such as Data.Word. > > I've also tried using ghc's profiling to get stack traces, but that doesn't > work very well either. Firstly, the stack traces that you get only include > function names, not line numbers. Secondly, the stack traces are often > incomplete, for reasons that I don't fully understand. One likely cause is > tail call optimization. (Is there any option to switch off tail call optimization? > I didn't see any such option in the ghc man page.) > Thirdly, profiling seems to be incompatible with the use of ghci; there > doesn't seem to be any easy way to build a workspace so that you can > get stack traces and use ghci in that workspace at the same time. > And ghc is slow enough (even on a 3.2GHz Pentium 4) that recompiling > the whole workspace is highly unpalettable. > > There's a hell of a lot of languages out there that _do_ support decent > stack traces when an exception is thrown. > > What's the point of using a high-level functional language if it means > you're stuck with poor library support and/or stone-age tools? > > \end{gripe} > > -- > Fergus J. Henderson | "I have always known that the pursuit > Galois Connections, Inc. | of excellence is a lethal habit" > Phone: +1 503 626 6616 | -- the last words of T. S. Garp. > _______________________________________________ > Haskell mailing list > Haskell@haskell.org > http://www.haskell.org/mailman/listinfo/haskell > From simonmar at microsoft.com Wed Jun 23 05:23:01 2004 From: simonmar at microsoft.com (Simon Marlow) Date: Wed Jun 23 05:20:22 2004 Subject: [Haskell] modern language design, stone age tools Message-ID: <3429668D0E777A499EE74A7952C382D10207B8D4@EUR-MSG-01.europe.corp.microsoft.com> On 23 June 2004 09:27, Robert Ennals wrote: > I wrote such a debugger as part of my PhD work. It is called > "hsdebug" and you can read the Haskell Workshop paper on it here: > > http://www.cambridge.intel-research.net/~rennals/hw2003.pdf > > Unfortunately, HsDebug depends on Optimistic Evaluation, and it seems > unlikely that Optimistic Evaluation will appear in a release version > of GHC (too hard to maintain, and I've gone off to work for Intel > Research). > > HsDebug is a GDB-style debugger which takes advantage of the fact that > Optimistic Evaluation makes programs evaluate in a largely-strict > evaluation order. It also uses a trick called "transient tail frames" > to allow tail calls to be visible in stack traces. > > HsDebug can debug any GHC-compilable Haskell program, including GHC > itself. We would be delighted if someone would take Robert's hsdebug and port it to the non-speculative version of the compiler. In fact, this is one of the items on the GHC Task list: http://sourceforge.net/pm/task.php?func=detailtask&project_task_id=98684 &group_id=8032&group_project_id=31802 It would make a great student project, or a summer hack for someone with lots of spare time... Cheers, Simon From ka2_mail at yahoo.com Wed Jun 23 05:42:11 2004 From: ka2_mail at yahoo.com (Krasimir Angelov) Date: Wed Jun 23 05:39:31 2004 Subject: [Haskell] modern language design, stone age tools In-Reply-To: <3429668D0E777A499EE74A7952C382D10207B8D4@EUR-MSG-01.europe.corp.microsoft.com> Message-ID: <20040623094211.46851.qmail@web40505.mail.yahoo.com> --- Simon Marlow wrote: > We would be delighted if someone would take Robert's > hsdebug and port it > to the non-speculative version of the compiler. In > fact, this is one of > the items on the GHC Task list: > > http://sourceforge.net/pm/task.php?func=detailtask&project_task_id=98684 > &group_id=8032&group_project_id=31802 > > It would make a great student project, or a summer > hack for someone with > lots of spare time... I have read the Robert's paper but I can't understand how hsdebug can work with lazy evaluation. Krasimir __________________________________ Do you Yahoo!? Yahoo! Mail is new and improved - Check it out! http://promotions.yahoo.com/new_mail From k.schupke at imperial.ac.uk Wed Jun 23 05:55:58 2004 From: k.schupke at imperial.ac.uk (MR K P SCHUPKE) Date: Wed Jun 23 05:53:20 2004 Subject: [Haskell] modern language design, stone age tools Message-ID: <200406230955.i5N9twa25770@aprilia.ee.ic.ac.uk> This may not be the right answer to the question (which is of course lets write a debugger) - But I have never used a debugger, and find them more or less the most unfriendly and useless things You either end up single stepping through a million lines of code, or you find the error is of a complex non-localised kind anyway. I find inserting my own debug code into an application to be a much more fruitful way of keeping track of errors. Using conditional compiliation all this extra code can be removed from a finished app. The only problem with this approach in Haskell is that you sometimes have to lift a function into the IO monad for debugging... Keean. From Malcolm.Wallace at cs.york.ac.uk Wed Jun 23 06:48:58 2004 From: Malcolm.Wallace at cs.york.ac.uk (Malcolm Wallace) Date: Wed Jun 23 06:51:45 2004 Subject: [Haskell] modern language design, stone age tools In-Reply-To: <20040623014412.GA23457@evariste.galois.com> References: <20040623014412.GA23457@evariste.galois.com> Message-ID: <20040623114858.0a45552b.Malcolm.Wallace@cs.york.ac.uk> > Seeing as Haskell is apparently such a popular language these days, > I don't suppose a working debugger would be too much to ask for, would it? I agree. > In case you're wondering, yes I have already tried using Hat and Buddha. > But I'm trying to debug a real application, not a toy one, and neither Hat > nor Buddha support enough of Haskell. Well, Hat only promises Haskell'98, and it actually delivers somewhat more. It is too much to ask for application developers to stick to agreed standards? :-) In fact, I often use Hat to debug real applications, such as the nhc98 compiler, HaXml library code, cpphs, etc.. Where an application demands more of Hat than it currently delivers, we try to extend Hat to cope. We just need two simple things: user feedback, and resources. :-) > There's a hell of a lot of languages out there that _do_ support decent > stack traces when an exception is thrown. As I'm sure you know, getting a meaningful stack trace from a lazy program is rather difficult. The actual stack at the time of failure is next to useless. You really want to see a reconstruction of a strictified evaluation order. That's why HsDebug uses optimistic evaluation, and why Hat builds redex trails. > What's the point of using a high-level functional language if it means > you're stuck with poor library support and/or stone-age tools? If companies are willing to invest in development, they will get the tools they want. Regards, Malcolm From k.schupke at imperial.ac.uk Wed Jun 23 07:34:20 2004 From: k.schupke at imperial.ac.uk (MR K P SCHUPKE) Date: Wed Jun 23 07:31:47 2004 Subject: [Haskell] modern language design, stone age tools Message-ID: <200406231134.i5NBYKP25864@aprilia.ee.ic.ac.uk> >Unless, of course, you have: >1) A large program operating on a large body of data that takes a long time to debugs logs go to a file, grep and awk let you quickly find things >3) A complex library written by someone else which contains a bug or makes before calling out print a funtion trace like: function "f" called from "reified location" with arguments ... returned "value" >4) this is what assert statements are for as in: assert (x>0) function-which-assumes x>0 For large project development - the development cycle should go along these lines... 1) functional specification 2) modularise 3) design interfaces for components 4) build testbench for components 5) code components... I have missed out the iterations for simplicity. Note the testbench should be built before the module - this includes analysis for linear regions and corner cases... The testbench will log each test along with the results. Testbenches should be provided with third party components - if they are not they should be built as part of the development process. I find if you do the above and put adequate debug logging in your code the need for a separate debugger is minimal... To get slightly more technical all the debugger does is run the code with full internal visibility (all states visible) - by adding debug statements you can increase visibility to the same level. logging all these debug outputs to a file gives you the same observability as single stepping, but it is much quicker to run the program at full speed and search the file. Prining out the full program state (or scoped variables) at any point is equivalent to a breakpoint. Consider this as a suggestion of how to cope without a debugger - until you find one you like... Keean. From alastair at reid-hoffmann.net Wed Jun 23 07:11:11 2004 From: alastair at reid-hoffmann.net (Alastair Reid) Date: Wed Jun 23 07:52:03 2004 Subject: [Haskell] modern language design, stone age tools In-Reply-To: <200406230955.i5N9twa25770@aprilia.ee.ic.ac.uk> References: <200406230955.i5N9twa25770@aprilia.ee.ic.ac.uk> Message-ID: <200406231211.11144.alastair@reid-hoffmann.net> MR K P SCHUPKE writes: > You either end up single stepping through a million lines of code, > or you find the error is of a complex non-localised kind anyway. Or you find that inserting a breakpoint (or waiting to hit an exception), examining data structures which are either in scope or in the scope of the callers(*) tells you exactly what has gone wrong. When writing in other languages, I find this is the most common scenario - though, of course, it is the non-localised heisenbugs that I remember most vividly. * By 'callers' I mean the code that contains the application of the function to an argument not the code that first forced evaluation of the resulting application node. For example, if I have 'let f x = (x+1,x-1) in fst(f 3)', then the caller of + is f not fst or the entire expression. > I find inserting my own debug code into an application to be a much > more fruitful way of keeping track of errors. Unless, of course, you have: 1) A large program operating on a large body of data that takes a long time to hit the bug. 2) A bug that only shows up some of the time and the program is interactive which makes it hard (or tedious) to repeat the bug. 3) A complex library written by someone else which contains a bug or makes assumptions about the arguments passed to it. 4) A division by 0, call to head, etc. where the resulting error message provides absolutely no guidance about where the error is in your 30,000 line program forcing you to grep for all uses of the offending operation both in your program and in any libraries it uses. [I may have left out a few other scenarios where being able to investigate the problem interactively and without already knowing where to look and what to look for is useful.] > The only problem with [inserting debugging code by hand] in Haskell is > that you sometimes have to lift a function into the IO monad for > debugging... I find the trace function works very well for this. It's interactive debugging that I really miss. -- Alastair Reid From GK at ninebynine.org Wed Jun 23 12:22:10 2004 From: GK at ninebynine.org (Graham Klyne) Date: Wed Jun 23 12:48:52 2004 Subject: [Haskell] modern language design, stone age tools In-Reply-To: <20040623114858.0a45552b.Malcolm.Wallace@cs.york.ac.uk> References: <20040623014412.GA23457@evariste.galois.com> <20040623014412.GA23457@evariste.galois.com> Message-ID: <5.1.0.14.2.20040623170431.02571210@127.0.0.1> At 11:48 23/06/04 +0100, Malcolm Wallace wrote: >If companies are willing to invest in development, they will get the >tools they want. Hmmm... chickens and eggs. I don't see a lot of *companies* using Haskell right now. And probably they won't until the tools they want are available (and more...) :-( I think the biggest problem with Haskell debugging is visibility of intermediate values. I sometimes end up planting Debug.Trace calls in the code, but that can be clumsy -- one of the reasons I develop in Hugs rather than GHC is the speed of recompilation when adding transient code like this. (Simple) facilities I'd like to see to help with debugging include: - A common version of Debug.Trace that is part of the standard prelude (i.e. no additional imports needed). - A common version of assert that is part of the standard prelude, which implementations are free to elide. - "Remote observation": a system like Hugs might provide a command option (i.e. without code modification) to observe evaluation of a named function in evaluation of a larger program. Using the "observe" functions I found to be rather awkward because if too many observations are coded they get mixed up, so I don't use them at all. But if a simple top-level command could observe named functions then it would be easy to use more selectively. Also, a convention for embedding test cases in module code which can be checked by the compiler is a possibility that I think was mentioned here some time ago. #g ------------ Graham Klyne For email: http://www.ninebynine.org/#Contact From fjh007 at galois.com Wed Jun 23 13:39:08 2004 From: fjh007 at galois.com (Fergus Henderson) Date: Wed Jun 23 13:36:29 2004 Subject: [Haskell] modern language design, stone age tools In-Reply-To: <200406230955.i5N9twa25770@aprilia.ee.ic.ac.uk> References: <200406230955.i5N9twa25770@aprilia.ee.ic.ac.uk> Message-ID: <20040623173908.GA29291@evariste.galois.com> On 23-Jun-2004, MR K P SCHUPKE wrote: > This may not be the right answer to the question (which is of > course lets write a debugger) - But I have never used a debugger, > and find them more or less the most unfriendly and useless things So how do you debug problems like "Prelude.head: empty list" in large programs? -- Fergus J. Henderson | "I have always known that the pursuit Galois Connections, Inc. | of excellence is a lethal habit" Phone: +1 503 626 6616 | -- the last words of T. S. Garp. From fjh007 at galois.com Wed Jun 23 13:46:30 2004 From: fjh007 at galois.com (Fergus Henderson) Date: Wed Jun 23 13:43:50 2004 Subject: [Haskell] modern language design, stone age tools In-Reply-To: References: <20040623014412.GA23457@evariste.galois.com> Message-ID: <20040623174630.GB29291@evariste.galois.com> On 23-Jun-2004, Ketil Malde wrote: > > Thirdly, profiling seems to be incompatible with the use of ghci; there > > doesn't seem to be any easy way to build a workspace so that you can > > get stack traces and use ghci in that workspace at the same time. > > You can compile with: -prof -auto-all -hisuf p.hi -osuf p.o > This will create separate object and interface files for profiling. Thanks! That is a useful tip. -- Fergus J. Henderson | "I have always known that the pursuit Galois Connections, Inc. | of excellence is a lethal habit" Phone: +1 503 626 6616 | -- the last words of T. S. Garp. From k.schupke at imperial.ac.uk Wed Jun 23 13:52:32 2004 From: k.schupke at imperial.ac.uk (MR K P SCHUPKE) Date: Wed Jun 23 13:49:57 2004 Subject: [Haskell] modern language design, stone age tools Message-ID: <200406231752.i5NHqWR27759@aprilia.ee.ic.ac.uk> >So how do you debug problems like "Prelude.head: empty list" >in large programs? I normally dont use head, but instead code: case x of (a0:_) -> _ -> fail for precisely this reason - and the fact that I dont like bindings that can fail... Keean. From k.schupke at imperial.ac.uk Wed Jun 23 14:03:37 2004 From: k.schupke at imperial.ac.uk (MR K P SCHUPKE) Date: Wed Jun 23 14:00:57 2004 Subject: [Haskell] modern language design, stone age tools Message-ID: <200406231803.i5NI3bS27773@aprilia.ee.ic.ac.uk> >Hmmm... chickens and eggs. I don't see a lot of *companies* using Haskell Actually I have used Haskell in commercial projects... and am continuing to do so. My development environment is Vim and GHC. Same one I have used for C/C++ VHDL Perl, and anything else... It is not that lack of GUI tools, but just the lack of coders that is the problem (or the price)... With my consultants hat on, looking at starting a project we ask how much is it going to cost to get a coder fluent in this language and how easily can one be found at short notice. I just think the intellectual barriers to becomming a Haskell coder are a bit higher (understanding monads etc) - meaning less people can do it. I know plenty of real world developers using other languages that also do not use debuggers very much if at all. The only fix I can see it when the world wakes up to the fact that side effects and weak typing lead to buggy programs, and realise that is unacceptable. Unfortunately in business a buggy program is often good enough. Basically if it is delivered on time is can be full of bugs - but the customer won;t notice them all right away - so you can get paid, and just fix those the customer finds really annoying. This can be cheaper than trying to produce 100% correct code. Keean. From fjh007 at galois.com Wed Jun 23 14:58:22 2004 From: fjh007 at galois.com (Fergus Henderson) Date: Wed Jun 23 14:55:42 2004 Subject: [Haskell] modern language design, stone age tools In-Reply-To: References: <20040623173908.GA29291@evariste.galois.com> Message-ID: <20040623185822.GA29633@evariste.galois.com> On 23-Jun-2004, Hal Daume III wrote: > On Wed, 23 Jun 2004, Fergus Henderson wrote: > > > On 23-Jun-2004, MR K P SCHUPKE wrote: > > > This may not be the right answer to the question (which is of > > > course lets write a debugger) - But I have never used a debugger, > > > and find them more or less the most unfriendly and useless things > > > > So how do you debug problems like "Prelude.head: empty list" > > in large programs? > > Wasn't addressed to me, but here's what I do: > > write the following function: > > head_ x [] = error ("head_: " ++ show x) > head_ _ l = head l > > and then replace each occurance of "head" with "head_ 1" or "head_ 2" > etc., so I can know where it failed. Well, there are quite a lot of such occurrences in the code that I'm working on: bash$ find . -name \*.hs -o -name \*.lhs | xargs grep -w head | wc -l 130 Replacing all of those occurrences by hand is going to be very very tedious and somewhat time-consuming. Doing it with a script would be better, but that's not a trivial task. Even once that is done, there's no guarantee it will actually help to find the problem. After all, the problem might well be arising from a call to "head" in one of ghc's standard libraries: bash$ find ~/ghc6-6.2/hslibs \*.hs -o -name \*.lhs | xargs grep -w head | wc -l 104 So not only do I have to edit my own code, and the libraries written by my colleagues, I also need to edit the ghc library code, and figure out how to build and reinstall the ghc libraries. That could take a long time. After all that, hopefully I will finally know which function called "head" with an empty list. But even then there's still no guarantee that I've actually found the source of the problem; the real problem might be in that function's caller, or the caller's caller, etc. So I might have to go through the whole process again. > (it is rather sad that this is the best approach i could come up > with...basically tries to get around the [lack of/uselessness of/inability > to use with ghci] stack traces) Yes :-( -- Fergus J. Henderson | "I have always known that the pursuit Galois Connections, Inc. | of excellence is a lethal habit" Phone: +1 503 626 6616 | -- the last words of T. S. Garp. From haskell at alexjacobson.com Wed Jun 23 15:38:42 2004 From: haskell at alexjacobson.com (S. Alexander Jacobson) Date: Wed Jun 23 15:37:41 2004 Subject: [Haskell] modern language design, stone age tools In-Reply-To: <20040623185822.GA29633@evariste.galois.com> References: <20040623173908.GA29291@evariste.galois.com> <20040623185822.GA29633@evariste.galois.com> Message-ID: It would be really nice if you could pass an error message down to every function that might fail. e.g. using implicit parameters*: myFunc 0 x = head x with ?failMsg="myfunc 0 caused the error" Head would be defined as e.g. head [] = fail $ "empty list.\n" ++ ?failMsg head (x:xs) = x It would be even nicer if lineNumber was automatically packed in the failMsg so the output of myFunc [] would be Prelude.head: emptyList. [Line ???] MyModule.myFunc: "myfunc 0 caused the error" [Line 50] But, just being able to pass a msg would make debugging LOADS easier (eliminating much of the need for a debugger to supply a stack trace). Since implicit parameters are part of the type system, it would be even cooler to be able to identify all the functions in your code that may fail (i.e. that carry ?failMsg). You can then target your debugging on those functions. Does this make any sense? -Alex- * I've never actually used implicit parameters. I just swiped the syntax I saw skimming: http://www.cse.ogi.edu/~mbs/pub/implicit_parameters/ _________________________________________________________________ S. Alexander Jacobson mailto:me@alexjacobson.com tel:917-770-6565 http://alexjacobson.com On Wed, 23 Jun 2004, Fergus Henderson wrote: > On 23-Jun-2004, Hal Daume III wrote: > > On Wed, 23 Jun 2004, Fergus Henderson wrote: > > > > > On 23-Jun-2004, MR K P SCHUPKE wrote: > > > > This may not be the right answer to the question (which is of > > > > course lets write a debugger) - But I have never used a debugger, > > > > and find them more or less the most unfriendly and useless things > > > > > > So how do you debug problems like "Prelude.head: empty list" > > > in large programs? > > > > Wasn't addressed to me, but here's what I do: > > > > write the following function: > > > > head_ x [] = error ("head_: " ++ show x) > > head_ _ l = head l > > > > and then replace each occurance of "head" with "head_ 1" or "head_ 2" > > etc., so I can know where it failed. > > Well, there are quite a lot of such occurrences in the code that I'm working > on: > > bash$ find . -name \*.hs -o -name \*.lhs | xargs grep -w head | wc -l > 130 > > Replacing all of those occurrences by hand is going to be very very > tedious and somewhat time-consuming. Doing it with a script would be > better, but that's not a trivial task. > > Even once that is done, there's no guarantee it will actually help to > find the problem. After all, the problem might well be arising from a > call to "head" in one of ghc's standard libraries: > > bash$ find ~/ghc6-6.2/hslibs \*.hs -o -name \*.lhs | xargs grep -w head | wc -l > 104 > > So not only do I have to edit my own code, and the libraries written by > my colleagues, I also need to edit the ghc library code, and figure out > how to build and reinstall the ghc libraries. That could take a long time. > > After all that, hopefully I will finally know which function called > "head" with an empty list. But even then there's still no guarantee > that I've actually found the source of the problem; the real problem > might be in that function's caller, or the caller's caller, etc. So I > might have to go through the whole process again. > > > (it is rather sad that this is the best approach i could come up > > with...basically tries to get around the [lack of/uselessness of/inability > > to use with ghci] stack traces) > > Yes :-( > > -- > Fergus J. Henderson | "I have always known that the pursuit > Galois Connections, Inc. | of excellence is a lethal habit" > Phone: +1 503 626 6616 | -- the last words of T. S. Garp. > _______________________________________________ > Haskell mailing list > Haskell@haskell.org > http://www.haskell.org/mailman/listinfo/haskell > From k.schupke at imperial.ac.uk Wed Jun 23 15:56:15 2004 From: k.schupke at imperial.ac.uk (MR K P SCHUPKE) Date: Wed Jun 23 15:53:41 2004 Subject: [Haskell] modern language design, stone age tools Message-ID: <200406231956.i5NJuFx27825@aprilia.ee.ic.ac.uk> I like to write programs so functions cannot fail... so head should really be: maybeHead :: [a] -> Maybe a maybeHead (a:_) = Just a maybeHead _ = Nothing etc... The the calling function can do something like: case maybeHead x of Just y -> Nothing -> fail "failed in..." This way you can pass the failure back up to somewhere where its meaningful. In my opinion you should either be encoding failure in the return type, or using exceptions... anything else is just bad coding. Finally use guards (that can be conditionally compiled out) before functions that might fail: if null x then fail "sesible error message" else ... Keean. From alex at alexjacobson.com Wed Jun 23 16:24:06 2004 From: alex at alexjacobson.com (S. Alexander Jacobson) Date: Wed Jun 23 16:21:21 2004 Subject: [Haskell] modern language design, stone age tools In-Reply-To: <200406231956.i5NJuFx27825@aprilia.ee.ic.ac.uk> References: <200406231956.i5NJuFx27825@aprilia.ee.ic.ac.uk> Message-ID: Thank you for the programming practice recomendation, but I would still prefer to have something like the implicit parameters solution I described. The solution you describe forces you to put code in functions to handle cases that are outside its domain. Usually I just want to know what function are calling with the pathological input. e.g. quadratic a b c = read $ show ((-b + root)/2/a),(-b - root)/2/a) where root = sqrt(b*b - 4*a*c) I want to know which function is passing in things to make the root imaginary or a==0. I don't want to rewrite this function so it handles these exceptions explicitly. -Alex- _________________________________________________________________ S. Alexander Jacobson mailto:me@alexjacobson.com tel:917-770-6565 http://alexjacobson.com On Wed, 23 Jun 2004, MR K P SCHUPKE wrote: > I like to write programs so functions cannot fail... > so head should really be: > > maybeHead :: [a] -> Maybe a > maybeHead (a:_) = Just a > maybeHead _ = Nothing > > etc... > > The the calling function can do something like: > > case maybeHead x of > Just y -> > Nothing -> fail "failed in..." > > This way you can pass the failure back up to somewhere where > its meaningful. > > In my opinion you should either be encoding failure in the > return type, or using exceptions... anything else is just > bad coding. > > Finally use guards (that can be conditionally compiled out) > before functions that might fail: > > if null x then fail "sesible error message" else ... > > Keean. > From alastair at reid-hoffmann.net Wed Jun 23 16:43:46 2004 From: alastair at reid-hoffmann.net (Alastair Reid) Date: Wed Jun 23 16:41:15 2004 Subject: [Haskell] modern language design, stone age tools In-Reply-To: References: <20040623173908.GA29291@evariste.galois.com> <20040623185822.GA29633@evariste.galois.com> Message-ID: <200406232143.46032.alastair@reid-hoffmann.net> On Wednesday 23 June 2004 20:38, S. Alexander Jacobson wrote: > It would be really nice if you could pass an > error message down to every function that might > fail. e.g. using implicit parameters*: > > myFunc 0 x = head x with ?failMsg="myfunc 0 caused the error" Interesting. Two variations on that: 1) Getting a 'stack' trace (i.e., a list of ancestors) can be more useful than just knowing the immediate ancestor so you might want myFunc to also take an implicit parameter and to add that parameter to what it says: myFunc 0 x = head x with ?failMsg="myfunc 0 caused the error but myFunc was called because " ++ ?failMsg [I can't remember if with acts as a let or a letrec. The intention is to use the ?failMsg passed implicitly to myFunc] 2) If you don't want to put errors in the type system, you could instead use exceptions something along the lines of: myFunc 0 x = mapException (\ err -> show err ++ "when invoked by myFunc 0") (head x) [Not quite type correct but hopefully clear enough. The idea is to combine the exception value returned with some extra information about the context with the idea that whoever called myFunc might add extra information. Ideally, the Exception type would be recursive so we could build chains of exceptions without having to use Show.] -- Alastair Reid From k.schupke at imperial.ac.uk Wed Jun 23 16:44:44 2004 From: k.schupke at imperial.ac.uk (MR K P SCHUPKE) Date: Wed Jun 23 16:42:03 2004 Subject: [Haskell] modern language design, stone age tools Message-ID: <200406232044.i5NKiiG27862@aprilia.ee.ic.ac.uk> >Thank you for the programming practice recomendation, Sorry if it seemed like that... I was really trying to suggest practical measures that someone could use in the absence of a debugger - but I do feel that 'commercial quality' code should be bullet proof, and of a different calibre to code for personal use, or academic research. Keean. From john at repetae.net Wed Jun 23 18:26:35 2004 From: john at repetae.net (John Meacham) Date: Wed Jun 23 18:23:55 2004 Subject: [Haskell] modern language design, stone age tools In-Reply-To: <20040623173908.GA29291@evariste.galois.com> References: <200406230955.i5N9twa25770@aprilia.ee.ic.ac.uk> <20040623173908.GA29291@evariste.galois.com> Message-ID: <20040623222635.GB9582@momenergy.repetae.net> On Wed, Jun 23, 2004 at 10:39:08AM -0700, Fergus Henderson wrote: > On 23-Jun-2004, MR K P SCHUPKE wrote: > > This may not be the right answer to the question (which is of > > course lets write a debugger) - But I have never used a debugger, > > and find them more or less the most unfriendly and useless things > > So how do you debug problems like "Prelude.head: empty list" > in large programs? enable template haskell and use $head where $head is defined to generate 'head' with the error annotated with the current line number and file. John -- John Meacham - ?repetae.net?john? From john at repetae.net Wed Jun 23 18:29:45 2004 From: john at repetae.net (John Meacham) Date: Wed Jun 23 18:27:05 2004 Subject: [Haskell] modern language design, stone age tools In-Reply-To: <200406232143.46032.alastair@reid-hoffmann.net> References: <20040623173908.GA29291@evariste.galois.com> <20040623185822.GA29633@evariste.galois.com> <200406232143.46032.alastair@reid-hoffmann.net> Message-ID: <20040623222945.GC9582@momenergy.repetae.net> On Wed, Jun 23, 2004 at 09:43:46PM +0100, Alastair Reid wrote: > 2) If you don't want to put errors in the type system, you could instead use > exceptions something along the lines of: > > myFunc 0 x = mapException > (\ err -> show err ++ "when invoked by myFunc 0") > (head x) > > [Not quite type correct but hopefully clear enough. The idea is to combine > the exception value returned with some extra information about the context > with the idea that whoever called myFunc might add extra information. > Ideally, the Exception type would be recursive so we could build chains of > exceptions without having to use Show.] Yes, I do something very similar to this in ginsu, what would be really really nice is if Exception were extended with AnnotatedException String Exception and the various routines like isIOError were modified to 'look through' these annotations. adding stack traces just where you think it might be useful becomes quite easy then. John -- John Meacham - ?repetae.net?john? From john at repetae.net Wed Jun 23 18:54:35 2004 From: john at repetae.net (John Meacham) Date: Wed Jun 23 18:51:58 2004 Subject: [Haskell] modern language design, stone age tools In-Reply-To: <200406231752.i5NHqWR27759@aprilia.ee.ic.ac.uk> References: <200406231752.i5NHqWR27759@aprilia.ee.ic.ac.uk> Message-ID: <20040623225435.GD9582@momenergy.repetae.net> On Wed, Jun 23, 2004 at 06:52:32PM +0100, MR K P SCHUPKE wrote: > >So how do you debug problems like "Prelude.head: empty list" > >in large programs? > for precisely this reason - and the fact that I dont like bindings > that can fail... Note that pattern matching rather than deconstruction functions have a number of benefits, not just relating to error messages, consider two functions which use the head of their argument. f xs = ... head xs ... g (x:_) = ... x ... now, g is superior to f in several ways, 1) the error message generated if the pattern fails will have the file name, line number and name of function 2) everything but the head of xs may be garbage collected right away since there is no reference to the rest of the list! This can cure some nasty space leaks and is vital in certain cases. 3) even the simplest compiler will realize g is stirct in its first argument and take advantage of the numerous optimizations that entails. A good compiler may figure out 2 and 3 with f, but it can't always, and why take the chance it won't? All of these benefits apply to deconstructing more complicated types too, so using pattern matching for deconstruction is just a good habit to get into. John -- John Meacham - ?repetae.net?john? From simonpj at microsoft.com Thu Jun 24 04:03:54 2004 From: simonpj at microsoft.com (Simon Peyton-Jones) Date: Thu Jun 24 04:01:13 2004 Subject: [Haskell] modern language design, stone age tools Message-ID: <4B93206CA3C55D4F96A61C9B1DC80DE3014DEA33@EUR-MSG-03.europe.corp.microsoft.com> Switching on profiling (-prof -auto-all) does essentially just this. The cost centre stack is just like an implicit parameters, only one that does not show up in the types. Since there really is some extra parameter passing going on, you really do need to recompile (all) the code. That's a nuisance, but it's a price that I can't see how to avoid in a call-by-need language. Simon | -----Original Message----- | From: haskell-bounces@haskell.org [mailto:haskell-bounces@haskell.org] On Behalf Of Alastair Reid | Sent: 23 June 2004 21:44 | To: S. Alexander Jacobson | Cc: haskell@haskell.org | Subject: Re: [Haskell] modern language design, stone age tools | | On Wednesday 23 June 2004 20:38, S. Alexander Jacobson wrote: | > It would be really nice if you could pass an | > error message down to every function that might | > fail. e.g. using implicit parameters*: | > | > myFunc 0 x = head x with ?failMsg="myfunc 0 caused the error" | | Interesting. Two variations on that: | | 1) Getting a 'stack' trace (i.e., a list of ancestors) can be more | useful than just knowing the immediate ancestor so you might want | myFunc to also take an implicit parameter and to add that | parameter to what it says: | | myFunc 0 x = head x | with ?failMsg="myfunc 0 caused the error but myFunc was called because " | ++ ?failMsg | | [I can't remember if with acts as a let or a letrec. The intention is | to use the ?failMsg passed implicitly to myFunc] | | 2) If you don't want to put errors in the type system, you could instead use | exceptions something along the lines of: | | myFunc 0 x = mapException | (\ err -> show err ++ "when invoked by myFunc 0") | (head x) | | [Not quite type correct but hopefully clear enough. The idea is to combine | the exception value returned with some extra information about the context | with the idea that whoever called myFunc might add extra information. | Ideally, the Exception type would be recursive so we could build chains of | exceptions without having to use Show.] | | -- | Alastair Reid | _______________________________________________ | Haskell mailing list | Haskell@haskell.org | http://www.haskell.org/mailman/listinfo/haskell From ketil+haskell at ii.uib.no Thu Jun 24 04:42:10 2004 From: ketil+haskell at ii.uib.no (Ketil Malde) Date: Thu Jun 24 04:39:29 2004 Subject: [Haskell] modern language design, stone age tools In-Reply-To: <200406232044.i5NKiiG27862@aprilia.ee.ic.ac.uk> (MR K. P. SCHUPKE's message of "Wed, 23 Jun 2004 21:44:44 +0100 (BST)") References: <200406232044.i5NKiiG27862@aprilia.ee.ic.ac.uk> Message-ID: MR K P SCHUPKE writes: >>Thank you for the programming practice recomendation, > Sorry if it seemed like that... Huh - I thought that was sincere; certainly I am happy to learn about sensible (or not) practices that others find useful. > but I do feel that 'commercial quality' code should be bullet proof, > and of a different calibre to code for personal use, or academic > research. I'm not so sure adding stuff to handle exceptions/errors is the way to go. I've developed 'commercial quality' code (in the 'real world', too), and the exception handling stuff tended IMO to be extensive, intrusive, and serving to cover up errors, rather than fix them. There are just too many things that can conceivably go wrong to adress them all in advance. Better programmers than me will probably disagree, but for now I've filed exception handling together with shared-everything threading (C/POSIX-style) as too difficult to get right to be worthwhile. -kzm -- If I haven't seen further, it is by standing in the footprints of giants From simonmar at microsoft.com Thu Jun 24 05:01:16 2004 From: simonmar at microsoft.com (Simon Marlow) Date: Thu Jun 24 04:58:35 2004 Subject: [Haskell] modern language design, stone age tools Message-ID: <3429668D0E777A499EE74A7952C382D1020B9C38@EUR-MSG-01.europe.corp.microsoft.com> On 23 June 2004 18:39, Fergus Henderson wrote: > On 23-Jun-2004, MR K P SCHUPKE wrote: >> This may not be the right answer to the question (which is of >> course lets write a debugger) - But I have never used a debugger, >> and find them more or less the most unfriendly and useless things > > So how do you debug problems like "Prelude.head: empty list" > in large programs? The two most useful techniques, both have which have already been suggested by others are: 1. Compile with -prof -auto-all and run with +RTS -xc. 2. Use the mapException trick to annotate exceptions as they travel up the stack (see Alastair Reid's message). (1) doesn't work that well, as you noticed. For example, sometimes the exception will stop at a CAF, due to the way cost centres work in GHC. I'd really like us to do better here - keeping track of the call stack in a lazy higher-order language has turned out to be surprisingly tricky. (2) requires that you add lots of annotations to your code, so it's not entirely satisfactory for that reason. Even if we had an interactive debugger, getting a good call stack is still going to be a hard problem. Cheers, Simon From alastair at reid-hoffmann.net Thu Jun 24 05:30:59 2004 From: alastair at reid-hoffmann.net (Alastair Reid) Date: Thu Jun 24 05:28:27 2004 Subject: [Haskell] modern language design, stone age tools In-Reply-To: <3429668D0E777A499EE74A7952C382D1020B9C38@EUR-MSG-01.europe.corp.microsoft.com> References: <3429668D0E777A499EE74A7952C382D1020B9C38@EUR-MSG-01.europe.corp.microsoft.com> Message-ID: <200406241030.59758.alastair@reid-hoffmann.net> > [...] > 2. Use the mapException trick to annotate exceptions as they > travel up the stack (see Alastair Reid's message). > [...] > (2) requires that you add lots of annotations to your code, so it's not > entirely satisfactory for that reason. Would it be possible to generalise ghc's -prof-all mechanism so that annotations could be added automatically. For example, suppose I have an annotation function Debug.Callstack.callstack :: ModuleName -> LineNumber -> a -> a Then, if I compile with: ghc -annotate=Debug.Callstack.callstack Foo.hs then ghc could add import Debug.Callstack(callstack) to the import list and transform every top level function body as follows: foo (x:xs) = .. foo [] = ... => foo arg = callstack "Foo" -- module name 42 -- line number (foo' arg) foo' (x:xs) = .. foo' [] = .. -- Alastair From simonmar at microsoft.com Thu Jun 24 05:50:29 2004 From: simonmar at microsoft.com (Simon Marlow) Date: Thu Jun 24 05:47:47 2004 Subject: [Haskell] modern language design, stone age tools Message-ID: <3429668D0E777A499EE74A7952C382D1020B9CE3@EUR-MSG-01.europe.corp.microsoft.com> On 24 June 2004 10:31, Alastair Reid wrote: >> [...] >> 2. Use the mapException trick to annotate exceptions as they >> travel up the stack (see Alastair Reid's message). [...] >> (2) requires that you add lots of annotations to your code, so it's >> not entirely satisfactory for that reason. > > Would it be possible to generalise ghc's -prof-all mechanism so that > annotations could be added automatically. For example, suppose I have > an annotation function > > Debug.Callstack.callstack :: ModuleName -> LineNumber -> a -> a > > Then, if I compile with: > > ghc -annotate=Debug.Callstack.callstack Foo.hs > > then ghc could add > > import Debug.Callstack(callstack) > > to the import list and transform every top level function body > as follows: > > foo (x:xs) = .. > foo [] = ... > => > foo arg = callstack > "Foo" -- module name > 42 -- line number > (foo' arg) > foo' (x:xs) = .. > foo' [] = .. Yes, this could be done. I should have mentioned though: this technique gives you the lazy call stack, whereas what you probably want is the strict call stack (which is what GHC's profiler tries to give you). Getting the lazy call stack is easy from a debugger, we don't need to annotate the program to do that, but we might want to add source locations in the form of debug info to the object file in a similar way to C compilers. It may be that giving programmers access to the lazy call stack is a heck of a lot better than nothing. Cheers, Simon From k.schupke at imperial.ac.uk Thu Jun 24 06:54:29 2004 From: k.schupke at imperial.ac.uk (MR K P SCHUPKE) Date: Thu Jun 24 06:51:46 2004 Subject: [Haskell] modern language design, stone age tools Message-ID: <200406241054.i5OAsTw28581@aprilia.ee.ic.ac.uk> With reference to "mapException", I thought this seemed a good idea. I like the 'AnnotatedException' idea... this is much better than concatenating strings... However for not I thought I would test it as is, but it doesn't work as I thought - perhaps someone could point out where I have gone wrong. 1) this works: main :: IO () main = do a <- getLine hPutStrLn $ showInt (fst . head . readDec $ a :: Int) `Exception.catch` (\e -> throw $ ErrorCall $ showString "Urk :" $ show e) 2) this doesn't work: main :: IO () main = mapException (\x -> ErrorCall $ showString "Urk :" $ show x) $ do a <- getLine hPutStrLn $ showInt (fst . head . readDec $ a :: Int) Keean. (using GHC-6.2) From simonmar at microsoft.com Thu Jun 24 07:09:16 2004 From: simonmar at microsoft.com (Simon Marlow) Date: Thu Jun 24 07:06:33 2004 Subject: [Haskell] modern language design, stone age tools Message-ID: <3429668D0E777A499EE74A7952C382D1020B9D7E@EUR-MSG-01.europe.corp.microsoft.com> On 24 June 2004 11:54, MR K P SCHUPKE wrote: > With reference to "mapException", I thought this seemed a good idea. > I like the 'AnnotatedException' idea... this is much better than > concatenating strings... However for not I thought I would test it > as is, but it doesn't work as I thought - perhaps someone could > point out where I have gone wrong. > > 1) this works: > > main :: IO () > main = do > a <- getLine > hPutStrLn $ showInt (fst . head . readDec $ a :: Int) > `Exception.catch` (\e -> throw $ ErrorCall $ showString "Urk :" $ > show e) > > 2) this doesn't work: > > main :: IO () > main = mapException (\x -> ErrorCall $ showString "Urk :" $ show x) $ > do a <- getLine > hPutStrLn $ showInt (fst . head . readDec $ a :: Int) This is due to the nature of exceptions in Haskell. Evaluating the expression (do a <- getLine; hPutStrLn ...) does not do any IO, and it doesn't raise any exceptions, so the mapException doesn't get to annotate any exceptions. What you really wanted here was (untested) mapExceptionIO :: IO a -> (Exception -> Exception) -> IO a mapExceptionIO io f = catch io (\e -> throwIO (f e)) probably we should have this in Control.Exception too. Cheers, Simon From alastair at reid-hoffmann.net Thu Jun 24 07:59:36 2004 From: alastair at reid-hoffmann.net (Alastair Reid) Date: Thu Jun 24 07:57:05 2004 Subject: [Haskell] modern language design, stone age tools In-Reply-To: <3429668D0E777A499EE74A7952C382D1020B9D7E@EUR-MSG-01.europe.corp.microsoft.com> References: <3429668D0E777A499EE74A7952C382D1020B9D7E@EUR-MSG-01.europe.corp.microsoft.com> Message-ID: <200406241259.36209.alastair@reid-hoffmann.net> > This is due to the nature of exceptions in Haskell. Evaluating the > expression (do a <- getLine; hPutStrLn ...) does not do any IO, and it > doesn't raise any exceptions, so the mapException doesn't get to > annotate any exceptions. Urgh, so the automatic annotation I suggested suffers from two problems: 1) It gives the call by name call stack when we usually want the call by value call stack. 2) It would have to be done in a type-sensitive way. Functions which return an IO result need to be annotated with mapExceptionIO while others need to be annotated with mapException. (For that matter, anyone defining 'sum = foldr (+) 0' will want a 3rd variant of mapException for use with CAFs whose value is a 1,2,3,etc-argument function.) Hmmmm, I'll bet Oleg can come up with a cunning pattern of type classes for this purpose :-). -- Alastair Reid From alex at alexjacobson.com Thu Jun 24 16:57:23 2004 From: alex at alexjacobson.com (S. Alexander Jacobson) Date: Thu Jun 24 16:54:29 2004 Subject: [Haskell] modern language design, stone age tools In-Reply-To: <4B93206CA3C55D4F96A61C9B1DC80DE3014DEA33@EUR-MSG-03.europe.corp.microsoft.com> References: <4B93206CA3C55D4F96A61C9B1DC80DE3014DEA33@EUR-MSG-03.europe.corp.microsoft.com> Message-ID: Hmm, those options don't work with ghci (where you are more likely to be debugging). Also, is there a way to get the typesystem to tell you which functions may fail i.e. which functions have failMsg as an implicit parameter? -Alex- _________________________________________________________________ S. Alexander Jacobson mailto:me@alexjacobson.com tel:917-770-6565 http://alexjacobson.com On Thu, 24 Jun 2004, Simon Peyton-Jones wrote: > Switching on profiling (-prof -auto-all) does essentially just this. The > cost centre stack is just like an implicit parameters, only one that > does not show up in the types. > > Since there really is some extra parameter passing going on, you really > do need to recompile (all) the code. That's a nuisance, but it's a > price that I can't see how to avoid in a call-by-need language. > > Simon > > | -----Original Message----- > | From: haskell-bounces@haskell.org [mailto:haskell-bounces@haskell.org] > On Behalf Of Alastair Reid > | Sent: 23 June 2004 21:44 > | To: S. Alexander Jacobson > | Cc: haskell@haskell.org > | Subject: Re: [Haskell] modern language design, stone age tools > | > | On Wednesday 23 June 2004 20:38, S. Alexander Jacobson wrote: > | > It would be really nice if you could pass an > | > error message down to every function that might > | > fail. e.g. using implicit parameters*: > | > > | > myFunc 0 x = head x with ?failMsg="myfunc 0 caused the error" > | > | Interesting. Two variations on that: > | > | 1) Getting a 'stack' trace (i.e., a list of ancestors) can be more > | useful than just knowing the immediate ancestor so you might want > | myFunc to also take an implicit parameter and to add that > | parameter to what it says: > | > | myFunc 0 x = head x > | with ?failMsg="myfunc 0 caused the error but myFunc was called > because " > | ++ ?failMsg > | > | [I can't remember if with acts as a let or a letrec. The intention > is > | to use the ?failMsg passed implicitly to myFunc] > | > | 2) If you don't want to put errors in the type system, you could > instead use > | exceptions something along the lines of: > | > | myFunc 0 x = mapException > | (\ err -> show err ++ "when invoked by myFunc 0") > | (head x) > | > | [Not quite type correct but hopefully clear enough. The idea is to > combine > | the exception value returned with some extra information about the > context > | with the idea that whoever called myFunc might add extra > information. > | Ideally, the Exception type would be recursive so we could build > chains of > | exceptions without having to use Show.] > | > | -- > | Alastair Reid > | _______________________________________________ > | Haskell mailing list > | Haskell@haskell.org > | http://www.haskell.org/mailman/listinfo/haskell > From oleg at pobox.com Thu Jun 24 22:03:44 2004 From: oleg at pobox.com (oleg@pobox.com) Date: Thu Jun 24 22:04:27 2004 Subject: [Haskell] Exceptions in types and exception-free programming Message-ID: <20040625020344.421CDABC3@Adric.metnet.navy.mil> S. Alexander Jacobson wrote: > Also, is there a way to get the typesystem to > tell you which functions may fail i.e. which > functions have failMsg as an implicit parameter? Generally speaking, that is not that easy. If we have a functional composition (foo . bar), we wish its type to reflect the _union_ of exceptions that can be raised in 'foo' and in 'bar'. Union types are hard to get. That's why in Ocaml, for example, exceptions aren't the part of a function signature. The good news is that we already have union types in Haskell -- to a large extent. To an extent enough to put exceptions into the types. The following are two approaches. They aren't perfect -- but that's a start. A better way however is to statically assure that no exception can occur. That is possible to achieve in Haskell today -- and improve efficiency of the code in the process due to elimination of run-time checks. The end of the message gives an example. The first approach applies only to polymorphic functions. Also we have to watch for monomorphic restriction (but we all know that). And it also works in GHC only, because GHC is lazy when it comes to constraint resolution (which is a good thing, IMHO). > {-# OPTIONS -fglasgow-exts #-} > {-# OPTIONS -fallow-undecidable-instances #-} > > module TER where > > class CERROR a c where > darn:: a -> c-> String -> b > > instance Show a => CERROR a c where > darn label _ msg = error $ "Error: " ++ (show label) ++ " " ++ msg > > > data EHead = EHead deriving Show > data ETail = ETail deriving Show > data EJust = EJust deriving Show > > myhead x@([]) = darn EHead x "head of an empty list" > myhead (x:_) = x > > mytail x@([]) = darn ETail x "tail of an empty list" > mytail (_:xs) = xs Now, if we ask GHCi for the type of myhead, we get *TER> :t myhead myhead :: forall a. (CERROR EHead [a]) => [a] -> a As we can see, the exception is apparent right in the function type. We can define > ht x = myhead $ mytail $ mytail x *TER> :t ht ht :: forall a. (CERROR ETail [a], CERROR EHead [a]) => [a] -> a We can see that we indeed have a union of exceptions that can be raised in different sub-expressions of ht. A more involved example: > myjust (Just a) = a > myjust x = darn EJust x "Just nothing" > > foo x = myjust $ myhead $ mytail $ myjust x *TER> :t foo foo :: forall b. (CERROR EJust (Maybe [Maybe b]), CERROR ETail [Maybe b], CERROR EHead [Maybe b], CERROR EJust (Maybe b)) => Maybe [Maybe b] -> b *TER> foo (Just [Nothing,Just 2]) 2 *TER> foo (Just [Nothing]) *** Exception: Error: EHead head of an empty list The second method involves the use of implicit parameters. It works both in GHC and in Hugs, and can work with monomorphic functions too. But is has some other drawback (although that depends on the point of view) > idarn _ msg = error msg > > myhead1 [] = idarn ?e_head "head of an empty list" > myhead1 (x:_) = x > > mytail1 x@([]) = idarn ?e_tail "tail of an empty list" > mytail1 (_:xs) = xs > > ht1 x = myhead1 $ mytail1 $ mytail1 x If we check for the type of ht1 (e.g., in Hugs), we get TER> :t ht1 ht1 :: (?e_tail :: a, ?e_head :: b) => [c] -> c That is, ht1 can fail because it tries to get either the head or the tail of an empty list. Again, we get the true _union_ of exceptions. Alas, we can't invoke ht1 in a simple way any more. We've got to bind the errors. TER> let ?e_head = undefined; ?e_tail = undefined in ht1 [1,2] Program error: head of an empty list TER> let ?e_head = undefined; ?e_tail = undefined in ht1 [1,2,3] 3 It seems that the best way to cope with exceptions is to assure statically that they cannot occur at all -- in large segments of code. We don't need to change Haskell. Haskell already can "fake it" quite believably. Indeed, let us consider a segment of the code assert x msg = if x then (not x) else error msg foo x | assert (not (null x)) "non-empty-list in ..." = undefined foo x = ... body_foo x ... Obviously, when the second clause is about to executed, _we_ know that x is a non-empty list. Alas, that fact is not reflected in the type of x. And it cannot in the above case. Indeed, what if we change the order of clauses by mistake: foo x = ... body_foo x ... foo x | assert (not (null x)) "non-empty-list in ..." = undefined To the typechecker, the order of clauses makes no difference. Yet it does to the executioneer. There is however a way to make the assurances statically certain. We should re-write the code as with_non_empty_list x foo where with_non_empty_list:: [a] -> NonemptyList [a] does the run-time check -- and generates the run-time error. But, if the check succeeded, we know that the list is not empty. That information can be encoded statically, and be used within the body of foo. If NonemptyList is a newtype, no run-time overhead occurs. Moreover, within the body of foo we can use unsafe versions of head and tail when applied to 'x' because we are statically assured 'x' is non-empty. We cannot avoid run-time checks -- yet we can (greatly) reduce their quantity and improve confidence in the code. The paper about number-parameterized types (being considered for JFP, I guess?) shows a more involved example: list reversal with an accumulator. Here's a simple code: > newtype NonEmpty a = NonEmpty [a] -- the NonEmpty constructor should > -- be hidden (not exported from its module) > > head' (NonEmpty a) = head a -- no error can occur! Can use unsafe version > tail' (NonEmpty a) = tail a -- no error can occur! Can use unsafe version > > -- trusted function: the only one that can use NonEmpty constructor. > fork_list_len f g x = if null x then f else g (NonEmpty x) > > revers x = revers' x [] > where > revers' x accum = fork_list_len accum (g accum) x > g accum x = revers' (tail' x) ((head' x):accum) That is a complex example as the sizes of all the lists involved change on every iteration. The function is recursive. And yet it is possible to type the function in Haskell _and_ statically assure that all applications of head and tail are safe! There are some run-time checks, in fork_list_len. But first, we had to do that check anyway, according to our algorithm. And second, each iteration does one list size check but two applications of list deconstructors. If functions head' and tail' do no run-time checks (as they should not), then we save one size check per iteration. So, it is possible to achieve both efficiency and safety at the same time! From romat at mizar.org Thu Jun 24 20:13:15 2004 From: romat at mizar.org (Roman Matuszewski) Date: Thu Jun 24 22:22:23 2004 Subject: [Haskell] Call for Participation - MKM 2004 (Bialowieza, Poland) In-Reply-To: References: Message-ID: Please post - apologies for multiple copies. ============================================ MKM 2004 Third International Conference on MATHEMATICAL KNOWLEDGE MANAGEMENT http://mizar.org/MKM2004 September 19 - 21, 2004 Bialowieza - Poland Registration to MKM 2004 is open: the deadline for early registration is August 12, 2004 CALL FOR PARTICIPATION Mathematical Knowledge Management is a new field in the intersection of mathematics and computer science. IMPORTANT DATES Early registration deadline: August 12, 2004 Late registration deadline: September 7, 2004 Conference: September 19 - September 21, 2004 AFFILIATED WORKSHOPS - September 18, 2004 - Mathematical User-Interfaces, organized by Paul Libbrecht, - 30 Years of Mizar, organized by Grzegorz Bancerek. MKM 2004 Conference - list of accepted papers in alphabetical order: 1. Adaptive Access to a Proof Planner (Erica Melis, Andreas Meier, Martin Pollet) 2. A Graph-Based Approach towards Discerning Inherent Structures in a Digital Library of Formal Mathematics (Lori Lorigo, Jon Kleinberg, Richard Eaton, Robert Constable) 3. An Architecture for Distributed Mathematical Web Services (Elena Smirnova, Clare So, Stephen Watt) 4. An Environment for Building Mathematical Knowledge Libraries (Florina Piroi, Bruno Buchberger) 5. An Investigation on the Dynamics of Direct-Manipulation Editors for Mathematics (Luca Padovani, Riccardo Solmi) 6. A Path to Faithful Formalizations of Mathematics (Gueorgui Jojgov, Rob Nederpelt) 7. C-CoRN, the Constructive Coq Repository at Nijmegen (Luis Cruz-Filipe, Herman Geuvers, Freek Wiedijk) 8. Copyright Issues for MKM (Andrew Adams, James Davenport) 9. CPoint: Dissolving the Author's Dilemma (Andrea Kohlhase, Michael Kohlhase) 10. Efficient Ambiguous Parsing of Mathematical Formulae (Claudio Sacerdoti Coen, Stefano Zacchiroli) 11. Efficient Retrieval of Mathematical Statements (Andrea Asperti, Matteo Selmi) 12. Extraction of Logical Structure from Articles in Mathematics (Koji Nakagawa, Akihiro Nomura, Masakazu Suzuki) 13. Finding and Analyzing Differential Equations on the Web (Dirk Draheim, Winfried Neun, Dima Suliman) 14. Flexible Encoding of Mathematics on the Computer (Fairouz Kamareddine, Manuel Maarek, Joe Wells) 15. Formalizing Set Theory as It is Actually Used (Arnon Avron) 16. Improving Mizar Texts with Properties and Requirements (Adam Naumowicz, Czeslaw Bylinski) 17. Informalising Formal Mathematics: the latent semantics of the Mizar library (Paul Cairns) 18. Integrated semantic browsing of the Mizar Mathematical Library for authoring Mizar articles (Josef Urban, Grzegorz Bancerek) 19. Intuitive and Formal Representations: The Case of Matrices (Martin Pollet, Volker Sorge, Manfred Kerber) 20. Managing Heterogeneous Theories within a Mathematical Knowledge Repository (Adam Grabowski, Markus Moschner) 21. Mathematical Libraries as Proof Assistant Environments (Claudio Sacerdoti Coen) 22. Mathematical Service Matching Using Description Logic and OWL (Olga Caprotti, Mike Dewar, Daniele Turi) 23. Modeling Interactivity for Mathematics Learning by Demonstration (Miguel A. Mora, Roberto Moriyon, Francisco Saiz) 24. On diagrammatic representation of mathematical knowledge (Zenon Kulpa) 25. Predicate Logic with Sequence Variables and Sequence Function Symbols (Temur Kutsia, Bruno Buchberger) 26. Rough Concept Analysis -- Theory Development in Mizar (Adam Grabowski, Christoph Schwarzweller) 27. The Categorial Type of OpenMath Objects (Andreas Strotmann) 28. Theorem Proving and Proof Verification in the System SAD (Alexander Lyaletski, Andrey Paskevich, Konstantin Verchinine) RELATED LINKS MKM Consortium, http://monet.nag.co.uk/mkm/consortium.html MKM 2001, http://www.risc.uni-linz.ac.at/institute/conferences/MKM2001/ MKM 2003, http://www.cs.unibo.it/MKM03/ MKM NET, http://monet.nag.co.uk/mkm/ MKM Symposium 2003, http://www.macs.hw.ac.uk/~fairouz/mkm-symposium03/ NA-MKM 2002, http://imps.mcmaster.ca/na-mkm-2002/ NA-MKM 2004, http://imps.mcmaster.ca/na-mkm-2004/ ================================================================== Questions should be sent to Conference Chair: Roman Matuszewski, mailto:romat@mizar.org http://mizar.org/people/romat/ From hdaume at ISI.EDU Fri Jun 25 12:42:51 2004 From: hdaume at ISI.EDU (Hal Daume III) Date: Fri Jun 25 12:40:31 2004 Subject: [Haskell] randomgen for foreign random functions Message-ID: Hi All -- Say I have a foreign function: foreign import ccall "statistical_c.h gengam" c_gengam :: CDouble -> CDouble -> IO CDouble that returns a random value parameterized by the two CDoubles. clearly this must happen in IO since the return value will be different each time, and some global state stuff is getting modified on the C side to facilitate future random # generation. However, I would like to wrap this into an essentially pure function, ala the Random class. basically, i want to wrap this up as something like: gengam :: RandomGen g => g -> Double -> Double -> (g, Double) analogously to the normal random # generation stuff. is there a safe way to do this? one option, of course, is just to unsafePerformIO it and {-# NOINLINE #-} the call, but that is rather, uhm, unsafe, I believe. it seems to me that something like this should be possible. Any thoughts? - Hal -- Hal Daume III | hdaume@isi.edu "Arrest this man, he talks in maths." | www.isi.edu/~hdaume From glynn.clements at virgin.net Fri Jun 25 16:14:13 2004 From: glynn.clements at virgin.net (Glynn Clements) Date: Fri Jun 25 16:13:32 2004 Subject: [Haskell] randomgen for foreign random functions In-Reply-To: References: Message-ID: <16604.34709.703949.900685@cerise.nosuchdomain.co.uk> Hal Daume III wrote: > Say I have a foreign function: > > foreign import ccall "statistical_c.h gengam" c_gengam :: CDouble -> CDouble -> IO CDouble > > that returns a random value parameterized by the two CDoubles. clearly > this must happen in IO since the return value will be different each time, > and some global state stuff is getting modified on the C side to > facilitate future random # generation. > > However, I would like to wrap this into an essentially pure function, ala > the Random class. basically, i want to wrap this up as something like: > > gengam :: RandomGen g => g -> Double -> Double -> (g, Double) > > analogously to the normal random # generation stuff. > > is there a safe way to do this? one option, of course, is just to > unsafePerformIO it and {-# NOINLINE #-} the call, but that is rather, uhm, > unsafe, I believe. it seems to me that something like this should be > possible. > > Any thoughts? What were you planning on doing with the "g" parameter? In order to (safely) have the above type, the behaviour of gengam would have to be such that, if called repeatedly with the same arguments (including the g), it would return the same (g, Double) tuple each time. AFAICT, unless you can get at c_gengam's state, you can't (safely) get the Haskell version out of the IO monad. OTOH, if you have a means to set the seed, you could combine the two into a pure function, and thus provide a pure (non-IO) Haskell interface. E.g. if you had: void seedgam(int seed) { srand(seed); } double gengam(double lo, double hi) { return lo + rand() * (hi - lo) / RAND_MAX; } you could either combine them in C: double do_gengam(int seed, double lo, double hi) { seedgam(seed); return gengam(lo, hi); } import that as a pure function: foreign import ccall "statistical_c.h do_gengam" c_do_gengam :: CInt -> CDouble -> CDouble -> CDouble and interface to it as: gengam g lo hi = (g', c_gengam seed lo hi)) where (seed, g') = next g or import them individually as: foreign import ccall "statistical_c.h seedgam" c_seedgam :: CInt -> IO () foreign import ccall "statistical_c.h gengam" c_gengam :: CDouble -> CDouble -> IO CDouble and (safely) use unsafePerformIO, e.g. gengam g lo hi = (g', x) where x = unsafePerformIO $ do seedgam seed x <- c_gengam lo hi (seed, g') = next g [Although, in the second approach, I presume that you would need addtional code for multi-threaded use.] -- Glynn Clements From Janwillem.Maessen at Sun.COM Fri Jun 25 16:27:59 2004 From: Janwillem.Maessen at Sun.COM (Jan-Willem Maessen) Date: Fri Jun 25 16:25:14 2004 Subject: [Haskell] randomgen for foreign random functions In-Reply-To: References: Message-ID: <1088195278.2072.56.camel@localhost.localdomain> On Fri, 2004-06-25 at 12:42, Hal Daume III wrote: > Hi All -- > > Say I have a foreign function: > > foreign import ccall "statistical_c.h gengam" c_gengam :: CDouble -> CDouble -> IO CDouble > > that returns a random value parameterized by the two CDoubles. clearly > this must happen in IO since the return value will be different each time, > and some global state stuff is getting modified on the C side to > facilitate future random # generation. > > However, I would like to wrap this into an essentially pure function, ala > the Random class. basically, i want to wrap this up as something like: > > gengam :: RandomGen g => g -> Double -> Double -> (g, Double) > > analogously to the normal random # generation stuff. You could use an Arbitrary Splittable Supplies library. See "ioSupply" on: http://csg.lcs.mit.edu/~earwig/haskell-lib/index.html You identify two reasons you need IO here (state and foreign function call). Unfortunately, it sounds like they're not so easily separable in this case (unless you're always passing in the same two Double arguments, but I suspect you aren't). So, you could use unsafePerformIO along with the library above, or you could look at the source code (which also uses unsafePerformIO internally) and figure out how to poach bits as appropriate. -Jan-Willem Maessen > > is there a safe way to do this? one option, of course, is just to > unsafePerformIO it and {-# NOINLINE #-} the call, but that is rather, uhm, > unsafe, I believe. it seems to me that something like this should be > possible. > > Any thoughts? > > - Hal > From hdaume at ISI.EDU Fri Jun 25 16:38:07 2004 From: hdaume at ISI.EDU (Hal Daume III) Date: Fri Jun 25 16:35:40 2004 Subject: [Haskell] randomgen for foreign random functions In-Reply-To: <16604.34709.703949.900685@cerise.nosuchdomain.co.uk> Message-ID: > What were you planning on doing with the "g" parameter? Well, one thought would be to use some type class magicery to try to use this to ensure linearity, but I have no idea how to go about that. Another thing that had crossed my mind was to use unsafeInterleaveIO to generate an infinite list of random #s according to the IO function and store these in g and then just take 1 off the head at each call...I don't know whether this is safe or not, though. > AFAICT, unless you can get at c_gengam's state, you can't (safely) get > the Haskell version out of the IO monad. OTOH, if you have a means to > set the seed, you could combine the two into a pure function, and thus > provide a pure (non-IO) Haskell interface. E.g. if you had: Hrm. Getting at its state is really a bother and, while I probably could, it would make me a very unhappy camper. > [Although, in the second approach, I presume that you would need > addtional code for multi-threaded use.] I don't care about multi-threaded use. - Hal -- Hal Daume III | hdaume@isi.edu "Arrest this man, he talks in maths." | www.isi.edu/~hdaume From Jeremy.Gibbons at comlab.ox.ac.uk Fri Jun 25 12:15:21 2004 From: Jeremy.Gibbons at comlab.ox.ac.uk (Jeremy Gibbons) Date: Fri Jun 25 17:37:53 2004 Subject: [Haskell] MPC2004: Final call for participation Message-ID: <200406251615.i5PGFLEi006410@mercury.comlab.ox.ac.uk> MPC 2004 7th International Conference on MATHEMATICS OF PROGRAM CONSTRUCTION 12-14 July, 2004, Stirling, Scotland, UK http://www.cs.cornell.edu/Projects/MPC2004 Organised in conjunction with AMAST and CMPP FINAL CALL FOR PARTICIPATION The final registration deadline for MPC2004 is 29th June. Accommodation is still available, but places are limited. To register, please follow the link from the conference web page, at the URL above. (Our apologies if you receive multiple copies of this announcement.) Jeremy Gibbons on behalf of the MPC programme committee -- Jeremy.Gibbons@comlab.ox.ac.uk Oxford University Computing Laboratory, TEL: +44 1865 283508 Wolfson Building, Parks Road, FAX: +44 1865 273839 Oxford OX1 3QD, UK. URL: http://www.comlab.ox.ac.uk/oucl/people/jeremy.gibbons.html From icsm04 at ai.univ-paris8.fr Sat Jun 26 20:33:57 2004 From: icsm04 at ai.univ-paris8.fr (Software Maintenance) Date: Sun Jun 27 22:02:03 2004 Subject: [Haskell] Invitation to ICSM 2004, the 20th International Conference on Software Maintenance Message-ID: <200406270033.i5R0XvD22751@bach.ai.univ-paris8.fr> Attend ICSM 2004, the International Conference on Software Maintenance, 11-14 September 2004 in Chicago IL USA. Held continuously since 1983, ICSM, the International Conference on Software Maintenance, is the major international conference in the field of software and systems maintenance, evolution, and management. ICSM is the 20th in this series of international conferences. See www.cs.iit.edu/~icsm2004 for registration and details. Or email Publicity Co-Chair Nicholas Zvegintzov at zvegint@softwaremanagement.com with a request for all details. Register on-line at www.cs.iit.edu/~icsm2004, tab "Registration". Accommodation and the conference itself will be at the historic Palmer House Hilton Hotel in downtown Chicago, near the lakeside. See www.cs.iit.edu/~icsm2004, tab "Hotel Reservation". The ICSM 2004 program (www.cs.iit.edu/~icsm2004, tab "Program Information") includes: * 3 days (September 12-14) of 15 Technical Sessions featuring 48 research and empirical papers * 2 Industrial Applications Sessions featuring state-of-the-art descriptions, experience reports, and survey reports from real projects, industrial practices and models * 3 Tools Sessions featuring commercial and research tools with hands-on demonstrations * 2 Panel Sessions: Test-Driven Development and Software Maintenance Evolution and Maintenance of Web Service Applications * The PhD Dissertation Session presenting doctoral research in software maintenance and evolution * Keynotes by Bill Woodworth (Corporate Director of IBM Software Test and Development Excellence) and Victor R. Basili (Professor of Computer Science at the University of Maryland and the Executive Director of the Fraunhofer Center - Maryland) * 4 Tutorials (September 11): Management of Maintenance and Evolution Meta-programming in XVCL for Enhanced Changeability Program Transformation Systems: Theory and Practice for Software Generation, Maintenance and Reengineering Developing Software for Safety Critical Systems: When Failure is not an Option ICSM 2004 is associated with: 10th International Symposium on Software Metrics (http://swmetrics.org/) 6th International Workshop on Web Site Evolution (http://www.websiteevolution.org) 4th International Workshop on Source Code Analysis and Manipulation (http://www.brunel.ac.uk/%7Ecsstmmh2/scam2004/) 9th IEEE Workshop on Empirical Studies of Software Maintenance (WESS 04) (http://www.ise.gmu.edu/wess04/) General Chair is Panos Linos, Butler University, USA, with Program Co-Chairs Mark Harman, Brunel University, UK, and Bogdan Korel, Illinois Institute of Technology, USA. The Conference is sponsored by IEEE Computer Society's Technical Council on Software Engineering (TCSE) in cooperation with Illinois Institute of Technology. ICSM 2004 The International Conference on Software Maintenance 11-14 September 2004 The Palmer House Hilton Hotel Chicago IL USA http://www.cs.iit.edu/~icsm2004/ From simonpj at microsoft.com Mon Jun 28 03:59:24 2004 From: simonpj at microsoft.com (Simon Peyton-Jones) Date: Mon Jun 28 03:56:32 2004 Subject: [Haskell] randomgen for foreign random functions Message-ID: <4B93206CA3C55D4F96A61C9B1DC80DE301521E21@EUR-MSG-03.europe.corp.microsoft.com> | Say I have a foreign function: | | foreign import ccall "statistical_c.h gengam" c_gengam :: CDouble -> CDouble -> IO CDouble | | that returns a random value parameterized by the two CDoubles. clearly | this must happen in IO since the return value will be different each time, | and some global state stuff is getting modified on the C side to | facilitate future random # generation. | | However, I would like to wrap this into an essentially pure function, ala | the Random class. basically, i want to wrap this up as something like: | | gengam :: RandomGen g => g -> Double -> Double -> (g, Double) | | analogously to the normal random # generation stuff. There's a standard approach, originally due to Lennart Augustsson. Have a single function that generates an infinite supply mkSupply :: IO Supply The Supply is a tree data Supply = Supply Int Supply Supply So splitting and generation are easy. But how do you generate an infinite tree? By using your side-effecting function plus unsafeInterleaveIO. (This function is better behaved then unsafePerformIO; no need for NOINLINE nonsense.) Here's the code from GHC's unique supply (you can ignore all the unboxed stuff. The genSymZh thing is the equivalent to your gengam. You still need the tree so that if you split the same random supply twice, you get the same thing: let (g1,g2) = split g in .. is the same as let g1 = fst (split g); g2 = snd (split g) in ... Simon mkSplitUniqSupply (C# c#) = let mask# = (i2w (ord# c#)) `uncheckedShiftL#` (i2w_s 24#) -- This is one of the most hammered bits in the whole compiler mk_supply# = unsafeInterleaveIO ( mk_unique >>= \ uniq -> mk_supply# >>= \ s1 -> mk_supply# >>= \ s2 -> return (MkSplitUniqSupply uniq s1 s2) ) mk_unique = genSymZh >>= \ (W# u#) -> return (I# (w2i (mask# `or#` u#))) in mk_supply# From Janwillem.Maessen at Sun.COM Mon Jun 28 10:05:39 2004 From: Janwillem.Maessen at Sun.COM (Jan-Willem Maessen - Sun Labs East) Date: Mon Jun 28 10:02:44 2004 Subject: [Haskell] randomgen for foreign random functions In-Reply-To: <4B93206CA3C55D4F96A61C9B1DC80DE301521E21@EUR-MSG-03.europe.corp.microsoft.com> References: <4B93206CA3C55D4F96A61C9B1DC80DE301521E21@EUR-MSG-03.europe.corp.microsoft.com> Message-ID: <40E025B3.1020007@sun.com> Simon Peyton-Jones wrote (in response to Hal Daume): > | basically, i want to wrap this up as something like: > | > | gengam :: RandomGen g => g -> Double -> Double -> (g, Double) > | > | analogously to the normal random # generation stuff. > > There's a standard approach, originally due to Lennart Augustsson. > > Have a single function that generates an infinite supply > mkSupply :: IO Supply Note that Simon's code is essentially isomorphic to the splittable supply library referenced in my last message---but the library gives a few more knobs you can turn. Simon, you left out the declaration for "MkSplitUniqSupply"! -Jan From ijones at syntaxpolice.org Mon Jun 28 11:08:38 2004 From: ijones at syntaxpolice.org (Isaac Jones) Date: Mon Jun 28 11:02:52 2004 Subject: [Haskell] Reading a directory tree In-Reply-To: <16600.21094.929838.590640@cerise.nosuchdomain.co.uk> (Glynn Clements's message of "Tue, 22 Jun 2004 16:38:14 +0100") References: <002801c4583a$34c2ddf0$37ae9182@ddns.htc.nl.philips.com> <16600.21094.929838.590640@cerise.nosuchdomain.co.uk> Message-ID: <87pt7j7ma1.fsf@syntaxpolice.org> [Followups to libraries@haskell.org] This thread makes me want to mention that I'm starting to put together a little library of useful path-based functions (I started it based on OS.Path in Python). Not sure how to organize it, exactly, since some things that might make sense here are already in System.Directory (and some things in there don't make sense in there) and some things may require Posix, and so should be split off into a separate module. My basic requirement is that they should be functions useful for system administration. We've sucked in some functions in from GHC and from Cabal[1]. It would be nice if we could just have a dumping ground for related functions that people have written. For now, if you have darcs[2], you can say: darcs get http://www.syntaxpolice.org/darcs_repos/OS.Path/ (And if you don't have darcs, you can browse around inside there with a web browser to get an idea of how it's shaping up.) That'll download the tree. You can make changes and additions, then use "darcs send" to email the changes to me. I think we should just dump together a bunch of these functions and worry about organizing it later (wiki-style). Here's a function[3] I wrote that's similar to what's mentioned here. It builds a tree out of a file directory. I'd like a function like "walk"[4] that walks this tree and executes an IO action (like printing out all the .txt files or something). It doesn't have to be based on Tree. peace, isaac ------------------------------------------------------------ [1] http://www.haskell.org/cabal [2] http://abridgegame.org/darcs/ [3] -- |Create a tree out of the given starting point. If the starting -- point is a directory, we recurse down and give the entire -- sub-structure, otherwise, we return a single node. -- I think it only requires Posix to test whether this is a directory, -- maybe we can do this with System.Directory? makeDirectoryTree :: FilePath -- ^Starting point (file or directory) -> IO (Tree (FilePath, Bool)) makeDirectoryTree path' = makeDirTree' Nothing path' where makeDirTree' :: Maybe FilePath -- ^Parent Dir -> FilePath -- ^Starting point -> IO (Tree (FilePath, Bool)) makeDirTree' parentIn pathIn = do let fullPath = case parentIn of Just pi' -> (dropLast pi' pathSeparator) ++ [pathSeparator] ++ pathIn Nothing -> pathIn isDir <- pathIsDirectory fullPath contents <- if isDir then getDirectoryContents fullPath else return [] subForest <- mapM (makeDirTree' (Just fullPath)) [c | c <- contents, c /= ".", c /= ['.', pathSeparator] , c /= ['.', '.', pathSeparator], c /= ".."] return $ Node (pathIn, isDir) subForest -- FIX: probably better not to use "error" here, but rather let exception occur. pathIsDirectory :: FilePath -> IO Bool pathIsDirectory p = do existsP <- doesFileExist p existsP2 <- doesDirectoryExist p when (not (existsP || existsP2)) (error $ "File does not exist: " ++ show p) status <- getFileStatus p return $ isDirectory status dropLast [] _ = [] dropLast (h:[]) toDrop | h == toDrop = [] | otherwise = [h] dropLast (h:t) toDrop = h:(dropLast t toDrop) [4] -- |Apply the given function in each directory starting at the -- root. use 'makeDirectoryTree'? FIX: how do we handle symlinks? walk :: FilePath -- ^root -> (FilePath -- current directory -> [FilePath] -- list of files in the directory -> IO a) -- ^visit function (current dir, list of files) -> IO (Tree a) From haskell at davidb.org Tue Jun 29 11:21:00 2004 From: haskell at davidb.org (David Brown) Date: Tue Jun 29 11:22:40 2004 Subject: [Haskell] Reading a directory tree In-Reply-To: <87pt7j7ma1.fsf@syntaxpolice.org> References: <002801c4583a$34c2ddf0$37ae9182@ddns.htc.nl.philips.com> <16600.21094.929838.590640@cerise.nosuchdomain.co.uk> <87pt7j7ma1.fsf@syntaxpolice.org> Message-ID: <20040629152100.GA24380@davidb.org> On Mon, Jun 28, 2004 at 11:08:38AM -0400, Isaac Jones wrote: > My basic requirement is that they should be functions useful for > system administration. > > We've sucked in some functions in from GHC and from Cabal[1]. It would > be nice if we could just have a dumping ground for related functions > that people have written. Functions that recursively iterate directories should _never_ follow symlinks as if they were directories (possibly optionally). It is rarely what is wanted. To fix this, use getSymbolicLinkStatus instead of getFileStatus. For directory iteration, the called function will usually need to know at least some information about each file. Since you have to get a FileStatus for each file anyway, you might as well pass it to each child. Also, it is important to handle errors that happen during iteration. If you try statting, or reading something incorrect, you can cause exceptions, which will need to be handled. SlurpDirectory has some useful code (in darcs), but is fairly specific to darcs. It is actually fairly challenging to come up with useful directory iteration that is generic. What about filtering? Dave Brown From kh at dcs.st-and.ac.uk Tue Jun 29 12:09:57 2004 From: kh at dcs.st-and.ac.uk (kh@dcs.st-and.ac.uk) Date: Tue Jun 29 12:08:55 2004 Subject: [Haskell] Announcement: Summer School on Memory Management Message-ID: [Posted on behalf of Richard Jones, the Summer School Organiser. Kevin] The 2004 UK Memory Management Network will hold a Summer School on Garbage Collection and Memory Management on 20-21 July at the University of Kent, Canterbury, UK (South-East England -- close to the EuroStar route from the continent, change at Ashford International, then 20 mins. by train; or travel direct by normal train from London). Full details including the programme are at: http://www.mm-net.org.uk/school There are lots of good speakers including Eliot Moss, Hans Boehm, David Bacon and Emery Berger. The registration fee is pounds 130 before July 9th; pounds 156 thereafter, and you can register online. Best Wishes, Kevin From duncan.coutts at worcester.oxford.ac.uk Tue Jun 29 13:22:19 2004 From: duncan.coutts at worcester.oxford.ac.uk (Duncan Coutts) Date: Tue Jun 29 13:18:59 2004 Subject: [Haskell] Help in understanding a type error involving forall and class constraints Message-ID: <1088529739.10068.91.camel@localhost> Here's a small bit of code that involves some fairly hairy class overloadings (ghc's mutable unboxed array classes) The code builds an array in the ST monad by creating a mutable array then assigning to each element and finally freezing the array and returning an immutable array. Firstly the bit that does most of the work (in the ST monad). We have a MArray class constraint because we're working generically on any mutable unboxed array. Its not completely generic however since we know we're working in the ST monad with unboxed ST arrays 'STUArray'. buildUArray' :: (Ix i, MArray (STUArray s) a (ST s)) => (i,i) -> (i -> a) -> ST s (STUArray s i a) buildUArray' bounds f = do arr <- newArray_ bounds mapM_ (\i -> writeArray arr i (f i)) (range bounds) return arr Now the wrapper which freezes the mutable array and gives us back an immutable array (still in the ST monad). We gain an extra IArray class constraint. buildUArray :: (MArray (STUArray s) a (ST s), Ix i, IArray UArray a) => (i, i) -> (i -> a) -> ST s (UArray i a) buildUArray bounds f = do arr <- buildUArray' bounds f unsafeFreeze arr This all typechecks fine. Now lastly we want to run this state thread monad to get the resultant 'UArray i a' foo :: (MArray (STUArray s) a (ST s), Ix i, IArray UArray a) => (i, i) -> (i -> a) -> UArray i a foo bounds f = runST (buildUArray bounds f) At first this seems like it ought to be the right type (it does discard the 's' type), but ghc complains: No instance for (MArray (STUArray s) a (ST s)) arising from use of `buildUArray' at BuildArray.hs:25:22-32 Probable fix: Add (MArray (STUArray s) a (ST s)) to the expected type of an expression Or add an instance declaration for (MArray (STUArray s) a (ST s)) In the first argument of `runST', namely `(buildUArray bounds f)' In the definition of `foo': foo bounds f = runST (buildUArray bounds f) I get the same error if I leave off the type signature for 'foo'. The error message suggests I add a class constraint that I've already added. I suspect there's a name clash and the 's' it means is not the same as the 's' that I've already got. Anyone have an idea what's wrong? My guess is that it's related to the nested forall type of runST. We need to express a class constraint on a type that is universally quantified but that doesn't escape to the top level of the functions type. If this is the case, it doesn't do any good to add the 'MArray (STUArray s) a (ST s)' constraint because 's' does not exist at this level of type scope (it just introduces a shadowing). So how would I write a constraint that involves 's'? Duncan Ps. similar code that uses normal (not unboxed) arrays works fine, but is has less complicated class constraints: buildArray :: Ix i => (i,i) -> (i -> a) -> Array i a buildArray bounds f = runST (do arr <- buildArray' bounds f unsafeFreeze arr) where buildArray' :: Ix i => (i,i) -> (i -> a) -> ST s (STArray s i a) buildArray' bounds f = do arr <- newArray_ bounds mapM_ (\i -> writeArray arr i (f i)) (range bounds) return arr From k.schupke at imperial.ac.uk Tue Jun 29 13:42:19 2004 From: k.schupke at imperial.ac.uk (MR K P SCHUPKE) Date: Tue Jun 29 13:39:24 2004 Subject: [Haskell] Help in understanding a type error involving forall and class constraints Message-ID: <200406291742.i5THgJi04892@aprilia.ee.ic.ac.uk> Erm, something I remember about needing MArrays... Here's something which does the same thing (cooks and MArray then freezes it - also using STUArray... The neat thing is MArray is a class, so you can swap between STUArray and STArray implementations without changing code. This is the classic dynamic programming version of string difference: distString :: String -> String -> Int distString s0 s1 = runST (difST s0 s1) difST :: MArray (STUArray s) Int (ST s) => String -> String -> ST s Int difST s0 s1 = do b@(_,br) <- return $ (\x1 y1 -> ((0,0),(x1,y1))) (length s0) (length s1) d <- newArray b 0 :: ST s (STUArray s (Int,Int) Int) mdiff d s0 s1 readArray d br mMin :: Int -> Int -> Int -> Int mMin i j k = min (min i j) k costDelete :: Char -> Int costDelete _ = 1 costInsert :: Char -> Int costInsert _ = 1 costReplace :: Char -> Char -> Int costReplace _ _ = 1 mdiff :: MArray a Int m => a (Int,Int) Int -> String -> String -> m () mdiff (d :: a e i) s0 s1 = do writeArray d (0,0) 0 foreach 1 s0 $ \x a -> do dx <- readArray d (x-1,0) writeArray d (x,0) (dx+costDelete a) foreach 1 s1 $ \y b -> do dy <- readArray d (0,y-1) writeArray d (0,y) (dy+costInsert b) foreach 1 s0 $ \x a -> do foreach 1 s1 $ \y b -> do dx <- readArray d (x-1,y) dy <- readArray d (x,y-1) dxy <- readArray d (x-1,y-1) writeArray d (x,y) $ mMin (dx+costDelete a) (dy+costInsert b) (if a==b then dxy else dxy+costReplace a b) where foreach :: MArray a Int m => Int -> String -> (Int -> Char -> m ()) -> m () foreach _ [] _ = return () foreach i (c0:cs) f = do f i c0 foreach (i+1) cs f ------------------------------------ Keean. From duncan.coutts at worcester.oxford.ac.uk Tue Jun 29 18:18:54 2004 From: duncan.coutts at worcester.oxford.ac.uk (Duncan Coutts) Date: Tue Jun 29 18:15:34 2004 Subject: [Haskell] Help in understanding a type error involving forall and class constraints In-Reply-To: <200406291742.i5THgJi04892@aprilia.ee.ic.ac.uk> References: <200406291742.i5THgJi04892@aprilia.ee.ic.ac.uk> Message-ID: <1088547534.10068.113.camel@localhost> On Tue, 2004-06-29 at 18:42, MR K P SCHUPKE wrote: > Erm, something I remember about needing MArrays... Here's something > which does the same thing (cooks and MArray then freezes it - also using > STUArray... The neat thing is MArray is a class, so you can swap between > STUArray and STArray implementations without changing code. I tried generalising the type to not mention which of STUArray and STArray I'm using. Letting ghc infer the type gives this type, unfortunately annotating the function with this type gives a type error!! Compiler/typechecker bug perhaps? buildUArray bounds f = do arr <- buildUArray' bounds f unsafeFreeze arr ghc infers this type: buildUArray :: forall a i b s array. (MArray (array s) a (ST s), Ix i, IArray b a) => (i, i) -> (i -> a) -> ST s (b i a) however if one add this annotation I get the same error message I got originally: Could not deduce (MArray (array1 s) a (ST s)) from the context (MArray (array s) a (ST s), Ix i, IArray b a) arising from use of `unsafeFreeze' at BuildArray.hs:25 Probable fix: Add (MArray (array1 s) a (ST s)) to the type signature(s) for `buildUArray' Or add an instance declaration for (MArray (array1 s) a (ST s)) In the result of a 'do' expression: unsafeFreeze arr In the definition of `buildUArray': buildUArray bounds f = do arr <- buildUArray' bounds f unsafeFreeze arr > This is the classic dynamic programming version of string difference: [snip] The difference with your example cod is that I return the array itself rather than a value calculated using the array. With your code, as soon as we try to return the array too, I run into the same problem. Duncan From k.schupke at imperial.ac.uk Tue Jun 29 18:38:15 2004 From: k.schupke at imperial.ac.uk (MR K P SCHUPKE) Date: Tue Jun 29 18:35:20 2004 Subject: [Haskell] Help in understanding a type error involving forall and class constraints Message-ID: <200406292238.i5TMcF505000@aprilia.ee.ic.ac.uk> Try this: distString :: String -> String -> Int distString s0 s1 = let a = runST (difST s0 s1) in a!(1,1) difST :: MArray (STUArray s) Int (ST s) => String -> String -> ST s (UArray (Int,Int) Int) difST s0 s1 = do b@(_,br) <- return $ (\x1 y1 -> ((0,0),(x1,y1))) (length s0) (length s1) d <- newArray b 0 :: ST s (STUArray s (Int,Int) Int) mdiff d s0 s1 -- readArray d br unsafeFreeze d Keean. From duncan.coutts at worcester.oxford.ac.uk Tue Jun 29 18:56:03 2004 From: duncan.coutts at worcester.oxford.ac.uk (Duncan Coutts) Date: Tue Jun 29 18:52:39 2004 Subject: [Haskell] Help in understanding a type error involving forall and class constraints In-Reply-To: <200406292238.i5TMcF505000@aprilia.ee.ic.ac.uk> References: <200406292238.i5TMcF505000@aprilia.ee.ic.ac.uk> Message-ID: <1088549762.10068.129.camel@localhost> On Tue, 2004-06-29 at 23:38, MR K P SCHUPKE wrote: > Try this: > > distString :: String -> String -> Int > distString s0 s1 = let a = runST (difST s0 s1) > in a!(1,1) > > difST :: MArray (STUArray s) Int (ST s) => String -> String -> ST s (UArray (Int,Int) Int) > difST s0 s1 = do > b@(_,br) <- return $ (\x1 y1 -> ((0,0),(x1,y1))) (length s0) (length s1) > d <- newArray b 0 :: ST s (STUArray s (Int,Int) Int) > mdiff d s0 s1 > -- readArray d br > unsafeFreeze d However if we generalise a bit from an array of Int to an array of any (suitable) type: difST :: MArray (STUArray s) a (ST s) => String -> String -> ST s (UArray (Int,Int) a) (I'm not claiming this generalisation makes sense in this example!) Then we get the problem when we use difST in distString. Could not deduce (MArray (STUArray s) a (ST s)) from the context () arising from use of `difST' at BuildArray.hs:55 Probable fix: Add (MArray (STUArray s) a (ST s)) to the expected type of an expression Or add an instance declaration for (MArray (STUArray s) a (ST s)) In the first argument of `runST', namely `(difST s0 s1)' In the definition of `a': a = runST (difST s0 s1) In the definition of `distString': distString s0 s1 = let a = runST (difST s0 s1) in a ! (1, 1) Where as there was an instance MArray (STUArray s) Int (ST s) there is of course no instance for an arbitrary 'a' (only instances for many specific unboxable types). So because there is no instance in scope we gain an extra class constraint, but I cannot find the right place to add an annotation. Duncan From k.schupke at imperial.ac.uk Wed Jun 30 03:35:06 2004 From: k.schupke at imperial.ac.uk (MR K P SCHUPKE) Date: Wed Jun 30 03:32:12 2004 Subject: [Haskell] Help in understanding a type error involving forall and class constraints Message-ID: <200406300735.i5U7Z6905365@aprilia.ee.ic.ac.uk> > Then we get the problem when we use difST in distString. I no such problem. The Glorious Glasgow Haskell Compilation System, version 6.3 ghc -H32m -Wall -O2 -fvia-C -optc-O2 -optc-march=pentium3 -optc-mfpmath=sse -fexcess-precision -fliberate-case-threshold100 -funbox-strict-fields -threaded -c Diff.hs -i../.. -syslib net +RTS -K100000000 Diff.hs: Warning: Module `Data.Array.MArray' is imported, but nothing from it is used (except perhaps instances visible in `Data.Array.MArray') Diff.hs:159:13: Warning: Defined but not used: br ...??... Of course the obvious way to have somewhere to put the class is to turn the let into a function: for example like: distString :: String -> String -> Int distString s0 s1 = f (runST (difST s0 s1)) f :: IArray a Int => a (Int,Int) Int -> Int f a = a!(1,1) ... or a non polymorphic version: f :: UArray (Int,Int) Int -> Int f a = a!(1,1) Keean. From qinsc at comp.nus.edu.sg Tue Jun 29 22:07:27 2004 From: qinsc at comp.nus.edu.sg (QIN Shengchao) Date: Wed Jun 30 05:23:35 2004 Subject: [Haskell] ICTAC2004 Call for papers: Deadline is Approaching soon Message-ID: [Appologies if you received multiple copies] CALL FOR CONTRIBUTION: ICTAC 2004 FIRST INTERNATIONAL COLLOQUIUM ON THEORETICAL ASPECTS OF COMPUTING Guiyang, China 20 - 24 September 2004 http://www.iist.unu.edu/ICTAC2004 --- It is planned to publish the accepted papers after the conference in revised full version in the Springer Lecture Notes in Computer Science series --- Your submission is an appreciated support to the UNU-IIST (http://www.iist.unu.edu) mission to help developing countries to advance their education and research in computer science --- The colloquium program will include very 6 good tutorials AIMS AND OBJECTIVES The International Institute for Software Technology of the United Nations University (UNU-IIST) decides to found an International Colloquium on Theoretical Aspects of Computing (ICTAC). The aim of the colloquium is to bring together practitioners and researchers from academia, industry and government to present research results, and exchange experience, ideas, and solutions for their problems in theoretical aspects of computing. We believe that this will help the developing countries to strengthen their research, teaching and development in computer science and engineering, to improve the links between developing countries and developed countries, and to establish collaboration in research and education. The technical program lasts five days including two days for tutorials and three days for a workshop. We plan to organize such a colloquium every 18 months jointly with a UNU-IIST training school in a developing country, and each time there will be a theme and a focus. The school participants will also attend the technical program of the colloquium. A small registration fee will be charged to cover meals tutorial handouts and proceedings only. There will be also a limited amount of grant that participants, tutorial and workshop speakers from developing countries can apply. Application should be submitted together with their tutorial proposals or papers to the workshop. The first ICTAC will be jointly organized by the Guizhou Academy of Sciences and UNU-IIST during 20-24 September 2004. SCOPE AND TOPICS ICTAC 2004 calls for tutorials in the areas of theoretical aspects of computing including automata, languages, software engineering and formal methods and solicits research papers for the workshop related to, but not limited to, the following principal topics: * automata theory and formal languages * principle and semantics of programming languages * logics and their applications * software architectures and their description languages * formal techniques in MDA * software specification, refinement and verification * model checking and theorem proving *formal techniques in software testing * models of object and component system * coordination and feature interaction * integration of formal and engineering methods * service-oriented development * document-driven development * models of concurrency, security and mobility * theory of parallel, distributed and internet-based (Grid) computing *Boolean satisfiability (SAT) * real-time and embedded systems * type and category theory in computer science SUBMISSIONS OF TUTORIAL PROPOSALS Proposals should be approximately five pages and must include the following information: * contents including abstract and syllabus/contents * duration of the tutorial (2 hours - 6 hours) * intended audience including prerequisites * biography of presenter * any special requirements (e.g., software/hardware for tool demo, software/hardware requirements for participants) Please send proposals (in postscript or PDF format) via email directly to the Program Chair Zhiming Liu at lzm@iist.unu.edu. SUBMISSIONS TO THE WORKSHOP Submissions to the workshop must not have been published or be concurrently considered for publication elsewhere. All submissions will be judged on the basis of originality, contribution to the field, technical and presentation quality, and relevance to the workshop. It is planned to publish the accepted papers after the conference in revised full version in the Springer Lecture Notes in Computer Science series (http://www.springer.de/comp/lncs/index.html) Papers should be written in English and not exceed 15 pages in LNCS format: see. http://www.springer.de/comp/lncs/authors.html for details. Further information and instructions about submissions can be found on the colloquium website http://www.iist.unu.edu/ICTAC2004. Authors are strongly encouraged to use this website to submit their papers in electronic form. IMPORTANT DATES Submission deadline of papers: 05 July 2004 Notification of acceptance: 09 August 2004 Final version due: 30 August 2004 Submission deadline of tutorial proposal 21 June 2004 Notification of acceptance 12 July 2004 Tutorials 20, 21 September 2004 Workshop 22 - 24 September 2004 INVITED SPEAKERS Jos Luiz Fiadeiro (University of Leicester, UK) Jifeng He (UNU-IIST, Macao) K. Rustan M. Leino (Microsoft Research, WA, USA) Huimin Lin (Institute of Software, CAS, Beijing, China) Program Committee Chairs Keijiro Araki (Kyushu University, Japan) Zhiming Liu (UNU/IIST, Macao SAR China) Publicity Chairs Bernhard Aichernig (UNU/IIST, Macao) Dan Li (Academy of Sciences, Guizhou, China) Finance Chair Danning Li (Academy of Sciences, Guizhou, China) Organization Chair Danning Li (Academy of Sciences, Guizhou, China) Advisory Committee Dines Bj?rner (Denmark), Manfred Broy (Germany), Jose Luiz Fiadeiro (University of Leicester, UK), Jifeng He (UNU-IIST), Mathai Joseph (India), Shaoying Liu (Japan), Zhiming Liu (UNU-IIST), Jim Woodcock (UK) Program Committee Luis S. Barbosa (University of Minho, Portugal) Gabriel Baum (National University of La Plata, Argentina) Hubert Baumeister (LMU, Munich, Germany) Jonathan Bowen (London South Bank University, UK) Cristian S. Calude (University of Auckland, New Zealand) Ana Cavalcanti (University of Kent, UK) Wei Ngan Chin (NUS, Singapore) Jim Davies (Oxford University, UK) Henning Dierks (University of Oldenburg, Germany) Jin Song Dong (NUS, Singapore) Wan Fokkink (CWI, the Netherlands) Michael R. Hansen (DTU, Lyngby, Denmark) James Harland (RMIT University, Melbourne, Australia) Jozef Hooman (Embedded Systems Institute, Eindhoven, the Netherlands) Guoxing Huang (ECNU, Shanghai, China) Purush Iyer (North Carolina State University, USA) Ryszard Janicki (McMaster University, Ontario, Canada,) Michael Johnson( Macquarie University, Sydney, Australia) Fabrice Kordon (University of Paris VI, France) Maciej Koutny (University of Newcastle upon Tyne, UK) Kung-Kiu Lau (Manchester University, UK) Antnia Lopes (University of Lisbon, Portugal) Jian Lu (Nanjing University, China) Andrea Maggiolo-Schettini (University of Pisa, Italy) Huaikou Miao (Shanghai University, China) Paniti Netinant (Bangkok University, Thailand) Paritosh Pandya (TIFR, Mumbai, India) Zongyan Qiu (Peking University, Beijing, China) Anders P. Ravn (Aalborg University, Denmark) Gianna Reggio (University of Genova, Italy) Riadh Robbana (LIP2/EPT, Tunisia) Augusto Sampaio (Federal Univ of Pernambuco, Recife, Brazil) Bernhard Schatz (TU Munchen, Germany) Irek Ulidowski (University of Leicester, UK) Miroslav Velev (Carnegie Mellon University, USA) Ji Wang (National Lab for Parallel and Distributed Processing, China) Wang Yi (Uppsala University, Swiden) Jian Zhang (Institute of Software, CAS, China) Mingyi Zhang (Academic of Sciences, Guizhou, China) Hongjun Zheng (Semantics Designs Inc, USA) From undisclosed-mailadress at informatik.uni-hamburg.de Wed Jun 30 05:35:52 2004 From: undisclosed-mailadress at informatik.uni-hamburg.de (MOCA'04) Date: Wed Jun 30 09:13:22 2004 Subject: [Haskell] CfP: Two Workshops in Aarhus, October 2004 (CPN'04 and MOCA'04) Message-ID: <40E28978.5D9ABAE2@informatik.uni-hamburg.de> Dear Colleagues, Below please find information about two workshops in Aarhus, Denmark, Oktober 8-13 2004. Please notice that the deadline for submission of papers is August 1. CPN'04 Fifth Workshop and Tutorial on Practical Use of Coloured Petri Nets and the CPN Tools October 8-11, 2004 MOCA'04 Third Workshop on Modelling of Objects, Components, and Agents October 11-13, 2004 The two workshop have a joint full-day tutorial: UML and Coloured Petri Nets Johan Lilius, ?bo Akademi University, Finland Jianli Xu, Nokia Research Center, Helsinki, Finland Didier Buchs and Levi L?cio, University of Geneva, Switzerland Moverover, the CPN workshop has a full-day tutorial: Application of Coloured Petri Nets to Protocols Jonathan Billington, University of South Australia, Australia Lars M. Kristensen, University of Aarhus, Denmark For more information, please see: http://www.daimi.au.dk/CPnets/workshop04/ Kurt Jensen Daniel Moldt -- Daniel Moldt Universit?t Hamburg Fachbereich Informatik, TGI Vogt-Koelln-Str. 30 http://www.daimi.au.dk/CPnets/workshop04/ D-22527 Hamburg From klusch at dfki.de Wed Jun 30 07:28:07 2004 From: klusch at dfki.de (Matthias Klusch) Date: Wed Jun 30 09:13:23 2004 Subject: [Haskell] Call for Participation: CIA 2004 Cooperative Information Agents Message-ID: <40E2A3C7.2080100@dfki.de> [Apologies if you receive this message more than once due to cross-posting to relevant mailing lists] +++ First Call for Participation +++ Dear colleague(s), we would like to very cordially invite you to join us at the eighth international workshop on Cooperative Information Agents (CIA 2004) to be held in Erfurt, Germany, from September 27 - 29, 2004. For more information please visit http://www.dfki.de/~klusch/cia2004/ Matthias Klusch, Sascha Ossowski, Vipul Kashyap, Rainer Unland (CIA 2004 Co-Chairs) _______________________________________________________ CIA 2004 PRELIMINARY PROGRAM _______________________________________________________ Monday, September 27 ==================== 9:15 Welcome 9:30 - 10:30 INVITED TALK Agents and OWL-S. Terry Payne (UK) 10:45 - 13:30 Session 1: Information Agents and P2P Computing ----------------------------------------------- 10:45 - 11:15 Design and Implementation of Agent Community based Peer-to-Peer Information Retrieval Tsunenori Mine, Daisuke Matsuno, Akihiro Kogo, Makoto Amamiya (Japan) 11:15 - 11:45 Towards Monitoring of Group Interactions and Social Roles via Overhearing Silvia Rossi, Paolo Busetta (Italy) 11:45 - 12:00 Coffee Break 12:00 - 12:30 A Probabilistic Approach to Predict Peers' Performance in P2P Networks Zoran Despotovic, Karl Aberer (Switzerland) 12:30 - 13:00 Personalizing Information Retrieval with Multi-Agent Systems Fabr?cio Enembreck, Jean-Paul Barth?s, Braulio Coelho ?vila (Brazil) 13:00 - 13:30 (Part of Session 6: Cooperation in Open Environments) Auction Equilibrium Strategies for Task Allocation in Uncertain Environments David Sarne, Meirav Hadad, Sarit Kraus (Israel) 13:30 - 14:30 Lunch Break 14:30 - 15:30 INVITED TALK Agent-Based Distributed Data Mining: Current Pleasures, and Future Directions. Hillol Kargupta (USA) 15:45 - 17:15 Session 2: Communication ------------------------ 15:45 - 16:15 On the Impact of Agent Communication Languages on the Implementation of Agent Systems Juan Manuel Serrano, Sascha Ossowski (Spain) 16:15 - 16:45 Reasoning about Communication:A Practical Approach based on Empirical Semantics Felix Fischer, Michael Rovatsos (Germany) 16:45 - 17:15 The Evolution of Probabilistic Reciprocity in a Multi-agent Environment with Neighborhoods Enda Ridge, Michael G. Madden, Gerard J. Lyons (Ireland) Tuesday, September 28 ===================== 9:00 - 10:00 NOD 2004 Keynote Talk (Jim Koplien) 10:00 - 10:15 Coffee Break 10:15 - 13:30 Session 3: Recommender Agents, and Systems ------------------------------------------ 10:15 - 10:45 Collaboration Analysis in Recommender Systems using Social Networks Jordi Palau, Miquel Montaner, Beatriz L?pez, Josep Llu?s De la Rosa (Spain) 10:45 - 11:15 Qualitative Analysis of User-based and Item-based Prediction Algorithms for Recommendation Agents Manos Papagelis, Dimitris Plexousakis (Greece) 11:15 - 11:45 CIA 2004 System Innovation Award Finalists (1) Running system demonstration; Q&A 11:45 - 12:00 Coffee Break 12:00 - 13:30 CIA 2004 System Innovation Award Finalists (2) Running system demonstrations; Q&A; 13:15 Public voting 13:30 - 14:30 Lunch Break 14:30 - 15:15 INVITED TALK Society-Centred Design for Socially Embedded Multi-Agent Systems. Toru Ishida (Japan) 15:15 - 15:30 Coffee Break 15:30 - 17:00 Session 4: Information Agents and Mobile Computing -------------------------------------------------- 15:30 - 16:00 Agents that Coordinate Devices, Services, and Humans in Ubiquitous Computing Akio Sashima, Noriaki Izumi, Koichi Kurumatani (Japan) 16:00 - 16:30 Multi-Agent Technology as an Enabler of Computer Supported Cooperative Work for the Mobile Workforce Habin Lee, Patrik Mihailescu, John Shepherdson (UK) 16:30 - 17:00 A-globe: Agent Platform with Inaccessibility and Mobility Support David Sisl?k, Milan Rollo, Michal P?chou?ek (Czech Republic) 17:00 - 17:15 Coffee Break 17:15 - 18:45 Session 5: Industrial Applications ---------------------------------- 17:15 - 17:45 Supply Chain Management using Cooperative Multi-Agent Mode Keonsoo Lee, Wonil Kim, Minkoo Kim (South Korea) 17:45 - 18:15 An agent simulation model for the Qu?bec Forest Supply chain Thierry Moyaux, Brahim Chaib-draa, Sophie D'Amours (Canada) 18:15 - 18:45 Performance analysis of multiagent industrial system Tomasz Babczynski, Zofia Kruczkiewicz, Jan Magott (Poland) 19:30 - 20:30 NOD 2004 NetTogetherMeeting (Welcome Reception) Wednesday, September 29 ======================= 9:00 - 10:00 NOD 2004 Keynote Talk 10:00 - 10:15 Coffee Break 10:15 - 11:45 Session 6: Cooperation in Open Environments ------------------------------------------- 10:15 - 10:45 The RoleX Environment for Multi-Agent Cooperation Giacomo Cabri, Luca Ferrari, Letizia Leonardi (Italy) (re-scheduled for Monday, 13:00 - 13:30) Auction Equilibrium Strategies for Task Allocation in Uncertain Environments David Sarne, Meirav Hadad, Sarit Kraus (Israel) 10:45 - 11:15 Agent's Multiple Inquiries for Enhancing the Partnership Formation Process David Sarne, Sarit Kraus (Israel) 11:15 - 11:45 Special Report Rational Cooperative Agents in Open Environments Matthias Klusch (Germany) 11:45 - 12:00 Coffee Break 12:00 - 13:00 CIA 2004 Open Discussion ------------------------ 13:00 - 13:30 Closing of CIA 2004 ------------------- - CIA 2004 Best Paper Award Giving - CIA 2004 System Innovation Award Giving - CIA 2005 Announcement 13:30 - 14:30 Lunch Break 14:30 -15:15 NOD 2004 Invited Talk 15:15 - 15:30 Coffee Break 15:30 - 19:00 In-Depth CIA 2004 Tutorial -------------------------- Semantic Web Services and Agents Terry Payne (UK) In between: Coffee break 17:00 - 17:15 20:30 - 21:30 NOD 2004 NetObjectNight (Social Event) ================================================================== CIA 2004 is co-sponsored by tranSIT GmbH, Germany Whitestein Technologies, Switzerland Spanish Association for Artificial Intelligence (AEPIA), Spain URJC Decision Engineering Lab (DMR), Spain AgentLink III, EU FP6 Coordinating Action ================================================================== For more information about the workshop please contact Matthias Klusch klusch@dfki.de Phone: +49-681-302-5297 http://www.dfki.de/~klusch/ From hdaume at ISI.EDU Wed Jun 30 09:47:49 2004 From: hdaume at ISI.EDU (Hal Daume III) Date: Wed Jun 30 09:45:34 2004 Subject: [Haskell] for large x, log (x::Integer) :: Double Message-ID: i'm looking for an accurate way to take the log of a very large integer, for example: let x :: Integer = 1301427272151881160612765560226881966218101403436917787184856303672382623256898455416763978959067300249652773943715743032733292602624834984761739233232794619193611954735720284761058146899246611113236700853600891798968920775344491685185906922596026543915321367577774522912315930144523472702386240645993859368230855941019371447058664115974032571881072431604651385520393674840678811793554266595013773947434115579588912967969680150473258236727830867832149867100437142705476716669039640252677955201589378051836112800268367331455296715904387732836350613539218249950829555418397197909288345303407194983545308212828662999623279222913080214196287140117582811769188486693208227570257136851945943408206281672555558289460256867016896063334140640075708083581866297494610834545554864846306383014549439540479675828018496049574066533167553894586573246931377586176000 this # is approximately 10^850. not surprisingly, if i do: log (fromIntegral x) :: Double i get "Infinity". i can think of several ways to try to combat this: (1) divide x by something large (10^850) and then take the log of the integer part (requires finding that x ~ 10^850 by some search method); (2) multiply x by something large (10^10) and then take the log of this *as an Integer* and then convert that to a double. has anyone encountered this problem before? surely there must be a "good way" to do this... - hal -- Hal Daume III | hdaume@isi.edu "Arrest this man, he talks in maths." | www.isi.edu/~hdaume From hoakley at btconnect.com Wed Jun 30 14:56:00 2004 From: hoakley at btconnect.com (Howard Oakley) Date: Wed Jun 30 14:53:07 2004 Subject: [Haskell] for large x, log (x::Integer) :: Double In-Reply-To: Message-ID: On 30/6/04 14:47, Hal Daume III wrote: > i'm looking for an accurate way to take the log of a very large integer, > for example: > > let x :: Integer = > 130142727215188116061276556022688196621810140343691778718485630367238262325689 > 845541676397895906730024965277394371574303273329260262483498476173923323279461 > 919361195473572028476105814689924661111323670085360089179896892077534449168518 > 590692259602654391532136757777452291231593014452347270238624064599385936823085 > 594101937144705866411597403257188107243160465138552039367484067881179355426659 > 501377394743411557958891296796968015047325823672783086783214986710043714270547 > 671666903964025267795520158937805183611280026836733145529671590438773283635061 > 353921824995082955541839719790928834530340719498354530821282866299962327922291 > 308021419628714011758281176918848669320822757025713685194594340820628167255555 > 828946025686701689606333414064007570808358186629749461083454555486484630638301 > 4549439540479675828018496049574066533167553894586573246931377586176000 > > this # is approximately 10^850. Hal, Based on the old manual way of doing this, I would first obtain the log10 value. This is easiest if you can convert the number to a string: - if the original number is an integer, the string length gives you the exponent, which in log10 forms the integer part of the result - then take the first few digits of the string, concat '0.' in front, convert to a double, and obtain the log10 of that, which forms the decimal part of the result. And given the log10, if you want loge or ln then all you have to do is multiply by loge(10), if I remember correctly. Howard. Dr Howard Oakley The Works columnist for MacUser magazine (UK) http://www.macuser.co.uk/ From hoakley at btconnect.com Wed Jun 30 15:08:39 2004 From: hoakley at btconnect.com (Howard Oakley) Date: Wed Jun 30 15:05:49 2004 Subject: [Haskell] for large x, log (x::Integer) :: Double In-Reply-To: Message-ID: On 30/6/04 19:56, Howard Oakley wrote: > - if the original number is an integer, the string length gives you the > exponent, which in log10 forms the integer part of the result Well, almost. The string length is actually 1 greater than the integer part of the result, as log10(1) = 0.0, and log10(10) = 1.0, if the dusty room at the back of my mind is not deceiving me :-) Howard. Dr Howard Oakley The Works columnist for MacUser magazine (UK) http://www.macuser.co.uk/ From GK at ninebynine.org Wed Jun 30 15:06:50 2004 From: GK at ninebynine.org (Graham Klyne) Date: Wed Jun 30 15:21:56 2004 Subject: [Haskell] for large x, log (x::Integer) :: Double In-Reply-To: Message-ID: <5.1.0.14.2.20040630195253.03122d90@127.0.0.1> At 06:47 30/06/04 -0700, Hal Daume III wrote: >i'm looking for an accurate way to take the log of a very large integer, This may not help, but just in case... there is an effective (approximate) algorithm for computing a log-gamma function, documented in "Numerical Recipies" by Press/Flannery/Teukolsky/Vetterling. If you want more info, I have an implementation in Mathematica somewhere, and could dig out a more specific reference. The alternative way I'd consider involves building a power series of (2^(2^i)) and performing a compare-and-divide-and-sum so that you get n and x in 2^n*x, for x in the range (0.0..1.0) (or any other range that you may choose). #g -- At 06:47 30/06/04 -0700, Hal Daume III wrote: >i'm looking for an accurate way to take the log of a very large integer, >for example: > > let x :: Integer = > 1301427272151881160612765560226881966218101403436917787184856303672382623256898455416763978959067300249652773943715743032733292602624834984761739233232794619193611954735720284761058146899246611113236700853600891798968920775344491685185906922596026543915321367577774522912315930144523472702386240645993859368230855941019371447058664115974032571881072431604651385520393674840678811793554266595013773947434115579588912967969680150473258236727830867832149867100437142705476716669039640252677955201589378051836112800268367331455296715904387732836350613539218249950829555418397197909288345303407194983545308212828662999623279222913080214196287140117582811769188486693208227570257136851945943408206281672555558289460256867016896063334140640075708083581866297494610834545554864846306383014549439540479675828018496049574066533167553894586573246931377586176000 > >this # is approximately 10^850. > >not surprisingly, if i do: > > log (fromIntegral x) :: Double > >i get "Infinity". > >i can think of several ways to try to combat this: (1) divide x by >something large (10^850) and then take the log of the integer part >(requires finding that x ~ 10^850 by some search method); (2) multiply x >by something large (10^10) and then take the log of this *as an Integer* >and then convert that to a double. > >has anyone encountered this problem before? surely there must be a "good >way" to do this... > > > - hal > >-- > Hal Daume III | hdaume@isi.edu > "Arrest this man, he talks in maths." | www.isi.edu/~hdaume > >_______________________________________________ >Haskell mailing list >Haskell@haskell.org >http://www.haskell.org/mailman/listinfo/haskell ------------ Graham Klyne For email: http://www.ninebynine.org/#Contact From k.schupke at imperial.ac.uk Wed Jun 30 15:42:27 2004 From: k.schupke at imperial.ac.uk (MR K P SCHUPKE) Date: Wed Jun 30 15:39:29 2004 Subject: [Haskell] for large x, log (x::Integer) :: Double Message-ID: <200406301942.i5UJgRf05817@aprilia.ee.ic.ac.uk> I would think to take an accurate (depends how you define accurate) arbitrary precision floating point is needed... gmp 2 supports this, but does not have a log function. The power series is the way calculators do it... you could always write a small library of operations on pairs of Integers to do arbitrary precision floating point, then use the power series. Keean. From steve at fenestra.com Wed Jun 30 17:19:48 2004 From: steve at fenestra.com (Steve Schafer) Date: Wed Jun 30 17:17:01 2004 Subject: [Haskell] for large x, log (x::Integer) :: Double In-Reply-To: References: Message-ID: On Wed, 30 Jun 2004 06:47:49 -0700 (PDT), Hal Daume III wrote: >i'm looking for an accurate way to take the log of a very large integer, >for example: The standard algorithm works along these lines: (Assume for the purposes of discussion that your numbers are represented in some kind of binary notation.) 0) Call your integer i. 1) Compute d, the smallest power of 2 that is greater than i. 2) Compute the floating-point quotient q = i / d. This will be a value between 0.5 and 1.0. 3) Compute n, the base-2 log of d. (This is trivial, since d is a power of 2.) 4) Use your CPU's built-in floating-point unit to compute g, the base-2 log of q. (For an Intel CPU, see the FYL2X instruction. If q is very close to 1, you may want to use the FYL2XP1 instruction instead to preserve more significant bits; in that case, pass it q - 1 rather than q.) 5) The base-2 log of i then simply n + g, and you can convert that to another base b by multiplying it by the base-2 log of b (or, equivalently, by dividing it by the base-b log of 2). If your integer is stored in some other fashion (i.e., not binary), then you'll want to adjust the divisor and the logarithm base appropriately. The idea is that you want to choose your initial divisor so that it is a power of the base, where the value of that base is chosen to make the process of computing the quotient q efficent and accurate. Steve Schafer Fenestra Technologies Corp http://www.fenestra.com/ From haskell at sleepingsquirrel.org Wed Jun 30 18:07:00 2004 From: haskell at sleepingsquirrel.org (Greg Buchholz) Date: Wed Jun 30 18:01:47 2004 Subject: [Haskell] for large x, log (x::Integer) :: Double Message-ID: <20040630220700.GA542@sleepingsquirrel.org> -- Inspired from Mr. Howard Oakley. Might not qualify as "good", -- but with this function I get log10(x)=849.114419903382 main = do print(show(log10(x))) x = 1301427272151881160612765560226881966218101403436917787184856303672382623256898455416763978959067300249652773943715743032733292602624834984761739233232794619193611954735720284761058146899246611113236700853600891798968920775344491685185906922596026543915321367577774522912315930144523472702386240645993859368230855941019371447058664115974032571881072431604651385520393674840678811793554266595013773947434115579588912967969680150473258236727830867832149867100437142705476716669039640252677955201589378051836112800268367331455296715904387732836350613539218249950829555418397197909288345303407194983545308212828662999623279222913080214196287140117582811769188486693208227570257136851945943408206281672555558289460256867016896063334140640075708083581866297494610834545554864846306383014549439540479675828018496049574066533167553894586573246931377586176000 log10 :: Integer -> Double log10 n = let i = length(show(n)) - 1 t = take 12 (show(n)) r = read(t) f = r / 10 ^ (length(t) - 1) in fromIntegral(i) + log(f)/log(10) --Greg Buchholz