[Haskell-cafe] Efficient or predictable Ord for Typeable
Simon PJ wrote (snipped): This unfortunate observabilty of an ordering (or hash value) that is needed only for efficient finite maps, is very annoying. I wish I knew a way round it. As it is we can pick a) expose Ord/Hash, but have unpredictable results b) not have Ord/Hash, but have inefficient maps In this case there is a simple solution. Simply define newtype FastUnpredictableInstances a = FastUnpredictableInstances a and define the fast Ord and Hash only for FastUnpredictableInstances. People who manage to type all that then have no grounds to grumble if they get bitten. For something as basic as implementing execution contexts, FastUnpredictableInstances is acceptable. ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ACIO versus Execution Contexts
Hello George, I've been looking at your global variables library. As far as I can tell it seems to be aimed at solving a rather different problem from that the top-level - bindings are aimed at. So I don't think you can really compare them. One is not a substitute for the other. In particular, the purpose of top level - bindings IMO is *not* to provide global variables (though they could be abused this way). If you consider the example.. userInit - oneShot realInit ..the top level MVar created is not global. It doesn't even scope over an entire module, it's buried in a closure. This kind of use would be pretty typical I think. Even when you do have top level IORefs (or more complex mutable data structures) scoping over an entire module, generally they won't be exported by that module. Instead access is strictly limited to a few carefully defined IO actions, and these are exported. Also, we don't want different threads to have their own versions of these. They are for use in situations where you need to represent state associated with a genuinely unique resource (eg top level stateful C library or hardware IO device). So in such situations it's both unnecessary and downright dangerous to provide a newResourceState constructor and pass this to releted IO routines as a parameter. But in the absence of such a constructor, how can the state exist at all, unless one allows top level - bindings? This is the problem I think we're trying to solve with the top level - proposal. On Monday 29 Nov 2004 1:19 pm, George Russell wrote: Questions - 1. Is there anything people would like to do with ACIO for which execution contexts would not be practical? Yes, see above. Big problems with execution contexts (at least as currently proposed) IMO are.. 1- Use of multiple dictionaries breaks the uniqueness property of top level - bindings. 2- Constraint of one dictionary entry per type is particularly severe I think, especially as it's not statically checkable. 3- Variables are anonymous and can only be got at via IO monad. With top level - bindings, the bound variables are perfectly ordinary top level Haskell identifiers which can appear in other top level definitions. 4- Even an optimisted implementation will probably be very much slower than top level - bindings. 2. Which if either of the proposals would the gods responsible for implementing Haskell compilers favour? Dunno. But if it makes life any easier, I would be quite happy to forget about special restricted monads and just use IO instead. The resulting programs would still be sound I think, but it makes it the programmers responsibility not to do anything stupid in a top level - binding. It seems to me two properties are highly desirable.. 1 - Observable behaviour should not depend on ordering of - bindings in a module 2 - Observable behavior should not depend on ordering of imports in main or any other module. AFAICS all that's needed to ensure this is that top level - bindings are reduced lazily (as with the unsafePerformIO hack). I know that's not ideal, but it's a heck of a lot better than using unsafePerformIO. We have a similar situation with finalisers at the moment. The restricted monads guarantee a third property.. 3 - Observable behaviour does not depend on reduction order of top level - bindings *in any way*. They could be reduced at compile time say (at least with SafeIO, not sure about ACIO). This would be nice to enforce via the type system, but I could live without it. Regards -- Adrian Hey ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] RE: Efficient or predictable Ord for Typeable
The trouble is that *any* function can now deliver unpredictable results. Can I rely on the fact that foo :: Int - Int will always give the same answer given the same input. Not any more. I think the strongest argument here is that it's like a more benign version of unsafePerformIO, whose existence also threatens foo's predictability. | -Original Message- | From: George Russell [mailto:[EMAIL PROTECTED] | Sent: 30 November 2004 09:55 | To: [EMAIL PROTECTED]; Simon Peyton-Jones; John Meacham | Subject: Efficient or predictable Ord for Typeable | | Simon PJ wrote (snipped): | This unfortunate observabilty of an ordering (or hash value) that is | needed only for efficient finite maps, is very annoying. I wish I knew | a way round it. As it is we can pick | a) expose Ord/Hash, but have unpredictable results | b) not have Ord/Hash, but have inefficient maps | | In this case there is a simple solution. Simply define | | newtype FastUnpredictableInstances a = FastUnpredictableInstances a | | and define the fast Ord and Hash only for FastUnpredictableInstances. | People who manage to type all that then have no grounds to grumble | if they get bitten. For something as basic as implementing execution | contexts, FastUnpredictableInstances is acceptable. ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ACIO versus Execution Contexts
Adrian Hey wrote: Also, we don't want different threads to have their own versions of these. They are for use in situations where you need to represent state associated with a genuinely unique resource (eg top level stateful C library or hardware IO device) So in such situations it's both unnecessary and downright dangerous to provide a newResourceState constructor and pass this to releted IO routines as a parameter. But in the absence of such a constructor, how can the state exist at all, unless one allows top level - bindings? This is the problem I think we're trying to solve with the top level - proposal. I disagee - Allowing unique state is a mistake in my opinion. I want Haskell to be the operating system - how can I do this if I cannot create new process contexts. Also how can I deal with multiple pieces of hardware that are unique? The problem with your proposal is that resources are finite, not unique. You need a solution that will allow N drivers to run N pieces of hardware - one is just a special case like when your machine only has one serial port. Some machines have two, or more... (yet the drivers are written to only handle a single device, and will be initialised multiple times once for each device) Look at how Linux scans the hardware at boot time and initialises a driver for each device it finds... that means that each driver is parameterised by the IO address of the device, and can be initialised multiple times. When an OS boots it runs an initialisation routine (the 'main' of the kernel) This is just like the main in a Haskell program - there is no need for anything to be initialised _before_ main runs... The init routine calls init on each device driver in turn, finally handing control over to the scheduler, which loads the 'init' program and that starts all the user programs. I don't see any calls for unique guarantees here... Keean. Keean. ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ACIO versus Execution Contexts
Keean Schupke wrote: Look at how Linux scans the hardware at boot time and initialises a driver for each device it finds... that means that each driver is parameterised by the IO address of the device, and can be initialised multiple times. When an OS boots it runs an initialisation routine (the 'main' of the kernel) This is just like the main in a Haskell program - there is no need for anything to be initialised _before_ main runs... The init routine calls init on each device driver in turn, finally handing control over to the scheduler, which loads the 'init' program and that starts all the user programs. I don't see any calls for unique guarantees here... Hear, hear! :) And to continue on the issue of device IO. If you look at real, portable operating systems, the drivers are actually parametrized on the methods to do IO to the device. The reason is that different busses require different ways to do IO (accessing a chip on ISA bus is not the same as when the chip sits in a USB device). But you want to reuse the same driver regardless of the bus, you drivers have to take the device access methods as arguments. In all the device drivers I've written there has never been anything in any driver that makes sure you don't initialize it twice. On the contrary. You need to initialize it once for each device. It's the bus driver that makes sure you get one driver per device. And the driver on top of the bus driver makes sure you get one bus driver per bus, etc. (At the very top there's only one instance (per machine), mainbus. Creating one copy of this would be the responsibility of main in a Haskell OS.) -- Lennart ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Efficient or predictable Ord for Typeable
Simon Peyton-Jones wrote: The trouble is that *any* function can now deliver unpredictable results. Can I rely on the fact that foo :: Int - Int will always give the same answer given the same input. Not any more. Yes, I see what you mean. I think the strongest argument here is that it's like a more benign version of unsafePerformIO, whose existence also threatens foo's predictability. I suggest you implement hashTypeable :: Typeable - IO Int32 This would be just as useful for global variables/execution contexts as allowing a hash function which doesn't mention IO, but still preserves determinacy for foo :: Int - Int. Determinacy for foo :: Int - IO Int won't be preserved, but then of course you didn't have it in the first place, even with Haskell 98. If there were a Hash class (I think there should be), then it might in general be a good idea to define it by class Hash a where hash :: a - IO HashInt You don't need a pure function for this after all. ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Efficient or predictable Ord for Typeable
George Russell wrote: Simon Peyton-Jones wrote: The trouble is that *any* function can now deliver unpredictable results. Can I rely on the fact that foo :: Int - Int will always give the same answer given the same input. Not any more. Yes, I see what you mean. I think the strongest argument here is that it's like a more benign version of unsafePerformIO, whose existence also threatens foo's predictability. I suggest you implement hashTypeable :: Typeable - IO Int32 And/or mkHashTypeable :: IO (Typeable - Int32) -- Lennart ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] Re: [Haskell] Re: Global Variables and IOinitializers
On Mon, 29 Nov 2004, Simon Peyton-Jones wrote: This unfortunate observabilty of an ordering (or hash value) that is needed only for efficient finite maps, is very annoying. I wish I knew a way round it. As it is we can pick a) expose Ord/Hash, but have unpredictable results b) not have Ord/Hash, but have inefficient maps I was going to ask what was wrong with doing the tedious: class FiniteMappable key where listToFM :: [(key,elt)] - FiniteMap key elt addToFM :: FiniteMap key elt - key - elt - FiniteMap key elt ...etc etc... with the possibility of: instance Ord key = FiniteMappable key where listToFM = listToFMoriginal ...etc etc... where one would only export the fact that a particular type is FiniteMappable, not Ord. But then I remembered that modules can't hide instance declarations, so that's no good. :-( Is there some way to insert a newtype, so that just one instance becomes visible? -- Ian Stark http://www.ed.ac.uk/~stark LFCS, School of Informatics, The University of Edinburgh, Scotland ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ACIO versus Execution Contexts
On Tuesday 30 Nov 2004 11:21 am, Keean Schupke wrote: I want Haskell to be the operating system - how can I do this if I cannot create new process contexts. Also how can I deal with multiple pieces of hardware that are unique? The problem with your proposal is that resources are finite, not unique. You need a solution that will allow N drivers to run N pieces of hardware - one is just a special case like when your machine only has one serial port. Some machines have two, or more... (yet the drivers are written to only handle a single device, and will be initialised multiple times once for each device) Sorry Keean, but throughout this entire thread I have had the feeling that you are determined to misunderstand and misrepresent just about everything I have written. You then present counter arguments to the straw men you have created and seem to expect some kind of response from me. I'm sure this is all boring the pants of other Haskell list subscribers so I don't propose to continue this game. I believe I have made my position perfectly clear to anyone who actually takes the trouble to read my posts with an open mind and understand what I am saying. So I have nothing more to add. Regards -- Adrian Hey ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: ACIO versus Execution Contexts
Adrian Hey wrote (snipped): I've been looking at your global variables library. Thanks. In particular, the purpose of top level - bindings IMO is *not* to provide global variables (though they could be abused this way). If you consider the example.. userInit - oneShot realInit ..the top level MVar created is not global. It doesn't even scope over an entire module, it's buried in a closure. This kind of use would be pretty typical I think. Even when you do have top level IORefs (or more complex mutable data structures) scoping over an entire module, generally they won't be exported by that module. Instead access is strictly limited to a few carefully defined IO actions, and these are exported. I think you must mean by global variable something different to what I mean by global variable. It is precisely such uses as you describe above which I would anticipate being supported by the Execution Contexts proposal. Of course good structured programming would hide a module's use of execution contexts or top-level variables. Also, we don't want different threads to have their own versions of these. There seems to have been some confusion on this point, so I should make it clear that by default, with my proposal, threads *do*not* each have their own versions of the variables. This only happens if you explicitly create a new execution context and run an action within it; that action, and the threads it forks off, will then use the new execution context. They are for use in situations where you need to represent state associated with a genuinely unique resource (eg top level stateful C library or hardware IO device). In my experience this is only true quite rarely. I think Keean and Lennart have already said most of what I have to say here. ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Efficient or predictable Ord for Typeable
(me) I suggest you implement hashTypeable :: Typeable - IO Int32 Lennart wrote (snipped) And/or mkHashTypeable :: IO (Typeable - Int32) Although this is OK, a general hash function might well need to return IO HashKey. A while back, before Data.Unique, I implemented a Unique module with interface: newUnique :: IO Unique uniqCompare :: Unique - Unique - IO Ordering The values returned by uniqCompare are guaranteed to be consistent. This implementation (which was not meant terribly seriously) was unusual because it did not use unsafePerformIO or any other global state, though it did need MVars and access to the current thread identifier (if in a concurrent world). The ordering was constructed dynamically as you called uniqCompare. The source is here: http://www.mail-archive.com/glasgow-haskell-users@haskell.org/msg01109/Unique.hs Converting the function to be of type getUniqCompare :: IO (Unique - Unique - Ordering) would be impossible. I suspect there may be other cases where you dynamically construct a hash function. ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ACIO versus Execution Contexts
Adrian Hey wrote: Sorry Keean, but throughout this entire thread I have had the feeling that you are determined to misunderstand and misrepresent just about everything I have written. Well I think I understand it quite well - of course I may be being stupid... that is always a possibility. You then present counter arguments to the straw men you have created and seem to expect some kind of response from me. I don't think I am constructing straw men... I believe my objections are real. Keean. ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Equality of functions
Hi All, After some weeks of experimenting and digging around, I understand that functions cannot be compared for equality. Thanks to Bjorn Lisper for pointing this out. I basically understand (?) the underlying mathematical issue, which is that functions in general may have infinite domains and ranges. For example, a function f, which gives the successor of an integer, x + 1, could not be compared to a function g, which gives the predecessor of an integer which has 2 added, (x + 2) - 1, even though these two functions give exactly the same result on all arguments, because we would have to compare them on all possible values for x. Question -- is this all there is to the issue, or is there something more? Apologies in advance for not understanding the math better here. Question -- though Haskell, as a lazy language, does not otherwise have problems with infinite lists, why does it here? Question -- is there some way around this problem? It is very handy to be able to have a variable over functions and then compare the value to a designated function. This would let me say things like: when variableFunctionX == functionA then otherwise etc... One possible (dirty?) solution I thought up is to use the record types of Hugs to correlate the function with a name of type String: type FunctionNameFunction = Rec (functionName :: String, functionFunction :: WhateverFunction) Then, whenever one needs to use the function, one uses the value of functionFunction, but whenever one needs to evaluate for identity, one uses the value of functionName, using just string identity. Of course, this makes lots of things less 'pretty' (to apply a function to an argument, one has to first 'pull out' the function from the record), but it addresses a general problem. One would also have to keep careful track of which functionNames correlate with with functionFunctions. Other suggestions? Cheers, Adam ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Equality of functions
Adam Zachary Wyner wrote: Question -- is this all there is to the issue, or is there something more? Apologies in advance for not understanding the math better here. You can compare functions in a pointwise fashion, which does not work (other than approximatively) for infinite domains. This is the black box approach. You can also compare functions in a proof-theoretic fashion. Try to proof a derivation that f can be transformed into g. This is the white-box approach. This requires reasoning at the level of program text. Question -- though Haskell, as a lazy language, does not otherwise have problems with infinite lists, why does it here? Because lazyness only helps in cases where we don't want to see the full infinite data structure. Equality is a universal property; we would need to iterate over all elements of the domain. Question -- is there some way around this problem? It is very handy to be able to have a variable over functions and then compare the value to a designated function. This would let me say things like: when variableFunctionX == functionA then otherwise etc... Don't understand. One possible (dirty?) solution I thought up is to use the record types of Hugs to correlate the function with a name of type String: type FunctionNameFunction = Rec (functionName :: String, functionFunction :: WhateverFunction) Then, whenever one needs to use the function, one uses the value of functionFunction, but whenever one needs to evaluate for identity, one uses the value of functionName, using just string identity. Of course, this makes lots of things less 'pretty' (to apply a function to an argument, one has to first 'pull out' the function from the record), but it addresses a general problem. One would also have to keep careful track of which functionNames correlate with with functionFunctions. Yes, one can represent functions by type codes. These type codes would be interpreted by an Apply class (as in the HList library). Type codes could be compared for equality (again demonstrated in the HList paper). Modulo some extra tweaking, we can compute type equality for such *fixed* functions. In fact, one can build a little functional language in the type system this way. Expressions in this language would distinguished terms. One could even implement the abovementioned white-box approach in the type system. (For any given system of proof/transformation rules.) I am sure this is too complicated and too restricted than to be truly useful. Cheers, Ralf ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Equality of functions
On 30 Nov 2004, at 13:22, Adam Zachary Wyner wrote: Question -- is this all there is to the issue, or is there something more? Apologies in advance for not understanding the math better here. From the point of view of a programmer, that's all there is to it: there is no way of proving two functions are the same except by exhaustively checking every input. Question -- though Haskell, as a lazy language, does not otherwise have problems with infinite lists, why does it here? Try [1..]==[1..] You'll find it runs forever. (Aside: [1..]==[2..] returns False straightaway, though) In the same sense, you could try (map f [1..]) == (map g [1..]) and it will return False quickly if they are different, but it will run forever if they are the same. Question -- is there some way around this problem? It is very handy to be able to have a variable over functions and then compare the value to a designated function. This would let me say things like: You don't need records to pair functions with strings, but yes, one way to do this is to make your functions more structured types and compare them some other way. If you happen to know all your functions are 2nd order polynomials, then it suffices to check them at three points (or, check f, f', and f'' at 0, say): you could implement equality checks this way. In other function domains there may be other effective equality tests. The general situation is: there is no effective way to check the equality of functions on infinite domains. However, for most particular classes of functions you would actually want to compare, there are specific effective procedures. Jules ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Non-technical Haskell question
Hi, all, I'm new to the Cafe, but not to Haskell (experimented with it on and off on a small scale over the last 5 or 6 years and enjoy the language quite a lot) and had more of a political question and wanted to see what people thought: Has anyone tried presenting the language to the average rank and file programming community? If so, was it successful? If not, is there interest in doing so? By rank and file I mean, outside of the acedemic world where a large number of the programmers I see have very little math background. This would be the typical commercial Visual Basic crowd and the like. Thanks, Will Collum ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Non-technical Haskell question
On Tue, 30 Nov 2004, GoldPython wrote: Hi, all, I'm new to the Cafe, but not to Haskell (experimented with it on and off on a small scale over the last 5 or 6 years and enjoy the language quite a lot) and had more of a political question and wanted to see what people thought: Has anyone tried presenting the language to the average rank and file programming community? If so, was it successful? If not, is there interest in doing so? By rank and file I mean, outside of the acedemic world where a large number of the programmers I see have very little math background. This would be the typical commercial Visual Basic crowd and the like. Even inside the mathematical academic world, Haskell is not widely known or even used. So, I'm advocating Haskell whereever I feel it is advantageous compared to the languages in use. Though, the success makes me doubting, if advocacy is always good. Programmers of traditional languages convinced me that it is possible to write bad code in Haskell. :-) It's also hard or impossible to convince people that it is good, that some things are missing in Haskell for good reasons, such as global variables. I observed that people don't like advocacy but want to make the common errors themselves. It is better if they do them in C, Perl, MatLab, whatever. If they have made enough mistakes and wonder if there are ways around then they are at the point where advertising Haskell makes sense. ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: ACIO versus Execution Contexts
On Tuesday 30 Nov 2004 12:53 pm, George Russell wrote: Adrian Hey wrote (snipped): They are for use in situations where you need to represent state associated with a genuinely unique resource (eg top level stateful C library or hardware IO device). In my experience this is only true quite rarely. Well it's true there probably aren't many people actually writing hardware device drivers in Haskell at the moment, but it is something that should be possible to do safely. But the case of C libraries is far more typical at the moment I think. Hardly any (like none that I have ever used) can be safely used without precautions which require top level mutable state, one way or another. I think Keean and Lennart have already said most of what I have to say here. Oh no, not you as well :-). As I observed in an earlier post, you still have the same basic problem even if you a multiple but finite supply of these resources. The problem is slightly different, but is still insoluble without top level TWIs. Keean and Lennart are just hiding the problem in a hypothetical operating system which is simply assumed to be correct (it just doesn't do any of the dangerous things that might otherwise be done). I don't dispute that top level TWIs are arguably unnecessary, in the sense that there's no *program* that can be written with them that couldn't be written without them (in principle). The issue is *modularity*. Without top level TWIs there are certain safety guarantees that I cannot make from within my module. Instead I have to beg for safe use from outside my module. Begging a hypothetical operating system doesn't really help much. Regards -- Adrian Hey ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: ACIO versus Execution Contexts
Adrian Hey wrote: The issue is *modularity*. Without top level TWIs there are certain safety guarantees that I cannot make from within my module. Instead I have to beg for safe use from outside my module. Begging a hypothetical operating system doesn't really help much. And I am arguing that the library is not the appropriate enitity to enforce this uniqueness, and that should I have multiple of these 'unique' resources available, I should be able to initialise the library in two contexts at once. It seems a bad assumtion to assume that _all_ systems will only have one of these whatevers. Keean. ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
[Fwd: Re: [Haskell-cafe] Re: ACIO versus Execution Contexts]
---BeginMessage--- Adrian Hey wrote: Keean and Lennart are just hiding the problem in a hypothetical operating system which is simply assumed to be correct (it just doesn't do any of the dangerous things that might otherwise be done). Well, if think I'm not reading your postings then I think I can claim you're not reading mine either. :) You seem to be writing part of an operating system in Haskell. In that case you are responsible for handling the devices correctly. I'm trying to convince you that a TWI is not the right way. Having a TWI will give you some security against multiple uses of the same device, but it won't protect you against everything. * What if I have another driver for the same device? They can't share the TWI. * What if I have two identical devices? They should not share the TWI. I reiterate: not even device drivers written in C use TWIs. (Well, at least not quality drivers. :)) You need a device framework that does the right thing for you. And you have to write it yourself. So, for interfacing to bad C libraries I see the need for a TWI. But you are writing the device driver yourself. You have the chance to get it right. -- Lennart ---End Message--- ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Non-Academic Haskell was Re: [Haskell-cafe] Non-technical Haskell question
GoldPython [EMAIL PROTECTED] writes: Has anyone tried presenting the language to the average rank and file programming community? If so, was it successful? If not, is there interest in doing so? The #haskell irc channel on irc.freenode.net is composed of many different flavors of programmer, from self-educated 16 year olds on up to post doctoral students studying functional programming. I'm a self-educated, self-employed programmer. I use Python in most of my paying work but would very much prefer to use Haskell. It seems obvious to me (but not to most of my clients :-) that the various powerful and expressive patterns in Haskell allow programmers to deliver more business value in less time than almost any other programming language. By rank and file I mean, outside of the acedemic world where a large number of the programmers I see have very little math background. This would be the typical commercial Visual Basic crowd and the like. I have no math background. I started with BASIC on a Sinclair, and my first real programming job was with Visual Basic 4, 5, and 6 for trust management. It seems that Haskell is about finding essential patterns and making those available for easy use. Most of my code starts out fuzzy and complicated, but as I understand the problem better, my code gets smaller. In the process, I find and refactor more and more places where my code is special or general cases of Prelude functions. Implicit For Each looping in Visual Basic was easier than manual looping in C. The map function in Python was another improvement. Now I have monads as the next step up in power, and I'm reading up on arrows. I'd think every programmer who preferred Visual Basic over C would end up loving Haskell. -- Shae Matijs Erisson - http://www.ScannedInAvian.com/ - Sockmonster once said: You could switch out the unicycles for badgers, and the game would be the same. ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] ACIO versus Execution Contexts
| I think it would be nice to summarise the current state of play. This really | needs to be a WiKi. Thanks for the summary, George. | 2. Which if either of the proposals would the gods responsible for implementing | Haskell compilers favour? Rather than remain completely silent on this topic let me say that (a) I'm totally snowed under at the moment, at least partly with GHC stuff (Template Haskell, GADTs etc); (b) there has been so much traffic on this global variable topic that I've stopped reading it carefully. This isn't because I think it's unimportant or boring, but rather because I'm hoping that someone will eventually emit a summary that really does boil out the main issues, so that everyone else can benefit from the fruits of your (plural) labours. The idea would be that everyone else can just read the summary without reading the thread. A Wiki would be good. (c) I have the impression that there's still quite a bit of active discussion; convergence is not achieved (d) I'm not averse to changing GHC in some way, but big changes (e.g top level -) would need a jolly persuasive argument and solid consensus. Smaller changes (e.g. a robust promise about top-level newMVars) are easier of course. (e) FWIW, as Simon has remarked, we're busy eliminating top-level global MVars from GHC. The really persuasive use I know for them is to implement semantically-pure but implementationally impure things like memo tables. Simon ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Non-Academic Haskell was Re: [Haskell-cafe] Non-technical Haskell question
On Tue, Nov 30, 2004 at 04:57:27PM +0100, Shae Matijs Erisson wrote: The #haskell irc channel on irc.freenode.net is composed of many different flavors of programmer, from self-educated 16 year olds on up to post doctoral students studying functional programming. I'm a self-educated, self-employed programmer. I use Python in most of my paying work but would very much prefer to use Haskell. It seems obvious to me (but not to most of my clients :-) that the various powerful and expressive patterns in Haskell allow programmers to deliver more business value in less time than almost any other programming language. I've been sitting around #haskell on EfNet for something like 5 years and wondering why no one ever came by. -- wli ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Classes in type declarations in Hugs
Hello, I have this line: type CPResult a = MonadError CPError m = m a GHC (with various command-line options I'm already using) compiles this fine. hugs, with -98 +o, complains: Syntax error in input (unexpected `=') How do I make this work both places? ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: not possible with monad transformers ?
Thanks for response; unfortunately my problem was a bit deeper. Note to self: try to verify all code snippets before posting ;-) The problem is that code on line 4 is useless. If one of the arguments a or b is Nothing, computation will just return Nothing and will not bother to execute lines 4-5: 1 foo a b = do 2 output before 3 let r = liftM2 (+) a b 4 when (r == Nothing) $ output error 5 return r -- ??? lift r I guess it does make perfect sense. It just was not intuitive to me that as soon as I use Maybe monad in my monad transformation I will loose ability to do output *after* error occurred. But, anyway, I think I was able to find a nice solution to that: type M2 a = OuptutMonadT Maybe String a whenError:: M2 a - M2 a - M2 a 1 foo a b = do 2 output before 3 let r = liftM2 (+) a b 4 `whenError` $ reportError error 5 return r whenError combines two computations so that if first fails it will use second instead. Thanks, Pavel. ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: not possible with monad transformers ?
On Tue, Nov 30, 2004 at 06:36:46PM +, Pavel Zolnikov wrote: The problem is that code on line 4 is useless. If one of the arguments a or b is Nothing, computation will just return Nothing and will not bother to execute lines 4-5: 1 foo a b = do 2 output before 3 let r = liftM2 (+) a b 4 when (r == Nothing) $ output error 5 return r -- ??? lift r Obviously you are talking about your version of code (with r - liftM2...), because for Mike's code your statement isn't true. How can let abort the computation? Best regards, Tomasz ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: not possible with monad transformers ?
You are absolutely right! I missed that let. And it does work, thanks. On the other hand it is still not what I intended, so I decided not to use Monads in this particular case. I wanted to represent values that can fail and that have complete history of errors. So that if I calculate c = (liftM2 (+)) a b and if *both* a and b have failed, c would also fail plus it would have history of errors form a and b (and potentially its own). I tried to do this by combining Maybe and Output monads. Now I realize that as long as I am using liftM2 it is not possible to have history of errors from a and b - only form a. And as I moved to custom lift functions I realized I didnt need monads in the first place. Anyway, thanks for your help, it is very much appreciated. Regards, Pavel. I didnt know you can have let without in in do expressions, nice! ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ACIO versus Execution Contexts
On Tuesday 30 November 2004 11:41, Adrian Hey wrote: In particular, the purpose of top level - bindings IMO is *not* to provide global variables (though they could be abused this way). ... If you consider the example.. userInit - oneShot realInit ..the top level MVar created is not global. It doesn't even scope over an entire module, it's buried in a closure. ... Even when you do have top level IORefs (or more complex mutable data structures) scoping over an entire module, I don't get it: How can they be top-level without scoping over an entire module? I mean, the proposal was to have x - action at the top-level, right? Then how can it not be visible in the whole module? What scope *does* it have, in your opinion? Ben ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ACIO versus Execution Contexts
Keean Schupke [EMAIL PROTECTED] writes: I disagee - Allowing unique state is a mistake in my opinion. I want Haskell to be the operating system - how can I do this if I cannot create new process contexts. Why does it matter if you can't compile code for new programs at runtime, to become a part of the same process? -- __( Marcin Kowalczyk \__/ [EMAIL PROTECTED] ^^ http://qrnik.knm.org.pl/~qrczak/ ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: not possible with monad transformers ?
On 30 Nov 2004, at 20:55, Pavel Zolnikov wrote: Now I realize that as long as I am using liftM2 it is not possible to have history of errors from a and b - only form a. And as I moved to custom lift functions I realized I didnt need monads in the first place. It's not liftM2 that's the problem, it's rather the strategy of the Maybe monad. The strategy of the maybe monad is very roughly 'abort on error'. As you correctly observe, it doesn't make it at all easy to collect error messages, let alone tree-shaped error graphs. However, your problem *does* have a natural underlying monad, if you care to use it. It's a kind of Error monad, but not the standard one, since you would have to implement your chosen rules for combining errors. I'm not quite sure exactly what you want, probably either a list of errors, or a tree of errors, depending how much structure you're trying to preserve. You may not find the monad approach easier than just coding by hand, though... although if you have a large amount of code, I would expect monads to make it a bit shorter and clearer. Jules ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: not possible with monad transformers ?
Jules Bean wrote: However, your problem *does* have a natural underlying monad, if you care to use it. I may be confused, but I don't think it does. It seems like the OP wants a type like data Perhaps a = Success a | Failure [Error] and semantics like liftM2 (+) (Failure [error1]) (Failure [error2]) === Failure [error1,error2] where liftM2 f a1 a2 = a1 = p where p v1 = a2 = q where q v2 = return (f v1 v2) I don't see how to define (=) such that this will return the appropriate value. If a1 fails you must call p in order to collect additional errors, but there's no appropriate value of v1 that you can pass. But it's easy with a custom lifting function: liftPerhaps2 f (Success x) (Success y) = Success (f x y) liftPerhaps2 f p q = Failure (errors p ++ errors q) where errors (Success _) = [] errors (Failure es) = es -- Ben ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: not possible with monad transformers ?
Ben Rudiak-Gould [EMAIL PROTECTED] writes: I may be confused, but I don't think it does. It seems like the OP wants a type like data Perhaps a = Success a | Failure [Error] When writing a compiler, it makes sense to collect errors as by the writer monad, and not abort anything - producing dummy values instead (except perhaps some fatal errors when it's inconvenient). -- __( Marcin Kowalczyk \__/ [EMAIL PROTECTED] ^^ http://qrnik.knm.org.pl/~qrczak/ ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Equality of functions
On Tue, 2004-11-30 at 13:52 +, Jules Bean wrote: In the same sense, you could try (map f [1..]) == (map g [1..]) and it will return False quickly if they are different, but it will run forever if they are the same. For some very generous definition of quickly :) Bernie. ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Equality of functions
On 1 Dec 2004, at 01:06, Bernard Pope wrote: On Tue, 2004-11-30 at 13:52 +, Jules Bean wrote: In the same sense, you could try (map f [1..]) == (map g [1..]) and it will return False quickly if they are different, but it will run forever if they are the same. For some very generous definition of quickly :) With respect to the fact that we do not know how fast f or g run, the only way to define quickly in this sense is relative to how fast f and g run. We can return False from (map f [1..]) == (map g [1..]) with a constant time slow down from returning False from (f 1) == (g 1). I'd call constant time reasonably 'quickly'. Bob -- What is the internet? It's the largest equivalence class in the reflexive transitive symmetric closure of the relationship can be reached by an IP packet from. -- Seth Breidbart ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Equality of functions
Woops... scratch my stupitity... we could of course discover the test to be false on an extremely large integer. Bob -- God is real... Unless you define it as an integer. On 1 Dec 2004, at 01:19, Thomas Davie wrote: On 1 Dec 2004, at 01:06, Bernard Pope wrote: On Tue, 2004-11-30 at 13:52 +, Jules Bean wrote: In the same sense, you could try (map f [1..]) == (map g [1..]) and it will return False quickly if they are different, but it will run forever if they are the same. For some very generous definition of quickly :) With respect to the fact that we do not know how fast f or g run, the only way to define quickly in this sense is relative to how fast f and g run. We can return False from (map f [1..]) == (map g [1..]) with a constant time slow down from returning False from (f 1) == (g 1). I'd call constant time reasonably 'quickly'. Bob -- What is the internet? It's the largest equivalence class in the reflexive transitive symmetric closure of the relationship can be reached by an IP packet from. -- Seth Breidbart ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Equality of functions
Adam Zachary Wyner wrote: Hi All, After some weeks of experimenting and digging around, I understand that functions cannot be compared for equality. Thanks to Bjorn Lisper for pointing this out. I basically understand (?) the underlying mathematical issue, which is that functions in general may have infinite domains... Other suggestions? You can define equality for functions with finite domains. See the enclosed Haskell module. Loading package base ... linking ... done. Compiling Finite ( Finite.hs, interpreted ) Ok, modules loaded: Finite. *Finite not == not True *Finite () == () True *Finite () == (||) False -- Thomas H module Finite where instance (Finite a, Eq b) = Eq (a-b) where f == g = and [ f x == g x | x - allValues ] -- A class for finite types class Finite a where allValues :: [a] instance Finite () where allValues = [()] instance Finite Bool where allValues = [False,True] --instance Finite Ordering where ... --instance Finite Char where ... --instance Finite Int where ... instance (Finite a,Finite b) = Finite (a,b) where allValues = [ (x,y) | x-allValues, y-allValues] instance Finite a = Finite (Maybe a) where allValues = Nothing:[Just x|x-allValues] instance (Finite a,Finite b) = Finite (Either a b) where allValues = [Left x|x-allValues]++[Right y|y-allValues] -- ... ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Equality of functions
Jules Bean wrote: From the point of view of a programmer, that's all there is to it: there is no way of proving two functions are the same except by exhaustively checking every input. That is too pessimistic, I'm afraid. There is also an intensional equality. Granted, it can be sound but never, in general, complete (although it can be total). That is, if the comparison function returns True, then the arguments truly denote the same, identically the same function. If the answer is False, well, we don't know. The arguments may still denote the same function. Here's one example of intensional comparison: import Foreign comp a b = do pa - newStablePtr a pb - newStablePtr b let res = pa == pb freeStablePtr pa freeStablePtr pb return res *FD comp id id = print True *FD comp undefined id = print False *FD comp undefined undefined = print True This function lives in the IO monad, where it should stay because it destroys free theorems. It is quite equivalent to Scheme's eq? predicate. For some -- wide -- classes of functions, it is possible to define a pure functional intensional comparison. For example, a recent message http://www.haskell.org/pipermail/haskell/2004-November/014939.html demonstrated the reconstruction of (even compiled) numerical functions. So, one can define intensional equality of two numeric functions as structural equality of their reconstructed representations. Alas, this comparison function can't be total: bottom is beyond comparison. ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe